Page 2 of 210 FirstFirst 1 2 3 4 12 52 102 ... LastLast
Results 11 to 20 of 2091

Thread: BatBrain -- a central nervous system for consult scripts

  1. #11
    Senior Member Winterbay's Avatar
    Join Date
    Feb 2010
    Posts
    5,033

    Default

    I am currently going through batbrain and adding enters, tabs and {} where I feel is appropriate so that the code becomes legible (for me that is). As an example, the to_event()-function is 26 lines of code in the original version, but in mine it is 51 lines and oh so much more readable

    After I've done that I might dare actually use things
    My scripts:
    Best sushi for Profit
    Winterbay's Helpful Automatic Monsterbasher (WHAM)

    Scripts maintained by me:
    Autobasement
    Smashlib

    A small programmer joke:
    Wife: Honey, please go to the market and buy 1 bottle of milk. If they have eggs, bring 6.
    The man came back with 6 bottles of milk.
    Wife: Why did you buy 6 bottles of milk.
    Man: Because they had eggs...

    The 6 Stages of Debugging: 1 )That can't happen. 2) That shouldn't happen. 3) Hmmm, weird. 4) Why does that happen? 5) Oh, I see. 6 )How did that ever work?

    All programs can be optimized, and all programs have bugs; therefore all programs can be optimized to one line that doesn’t work. /Bob Fitch, Blizzard

  2. #12
    Senior Member zarqon's Avatar
    Join Date
    Nov 2007
    Location
    Seoul, Korea
    Posts
    3,370

    Default

    Here's an easier-to-read version:

    Code:
    import<zlib.ash> check_version("BatBrain","batbrain","0.8.2",1715);float[string]fvars;fvars["famgear"]=to_int(equipped_item($slot[familiar])==familiar_equipment(my_familiar()));fvars["spelldmgpercent"]=1.0+(numeric_modifier("Spell Damage Percent")/100);fvars["spelldmg"]=numeric_modifier("Spell Damage");fvars["yuletide"]=to_int(have_effect($effect[yuletide])>0);fvars["havesugar"]=to_int(have_effect($effect[sugar rush])>0);fvars["fweight"]=familiar_weight(my_familiar())+numeric_modifier("Familiar Weight");if(have_skill($skill[kneebutt]))fvars["pantspower"]=(have_skill($skill[Tao of the Terr]))?get_power(equipped_item($slot[pants]))*2:get_power(equipped_item($slot[pants]));if(have_skill($skill[headbutt]))fvars["helmetpower"]=(have_skill($skill[Tao of the Terr]))?get_power(equipped_item($slot[hat]))*2:get_power(equipped_item($slot[hat]));if(have_skill($skill[shieldbutt]))fvars["shieldpower"]=(item_type(equipped_item($slot[offhand]))=="shield")?get_power(equipped_item($slot[offhand])):0;if(have_equipped($item[staff of queso escusado]))fvars["stinkycheese"]=to_int(get_property("_stinkyCheeseCount"));boolean famspent;boolean smusted;boolean waved;boolean should_putty;boolean should_olfact;boolean should_pp;int round;int[item]stolen;int maxround=30;float attadj,defadj,stunadj,hpadj;if(last_monster()==$monster[none]||monster_attack(last_monster())==monster_level_adjustment()){attadj=to_int(vars["unknown_ml"]);defadj=attadj;hpadj=attadj}float monster_stat(string which){switch(which){case"att":return attadj+monster_attack();case"def":return defadj+monster_defense();case"hp":return hpadj+max(1.0,monster_hp())}return 0}int how_many_foes(){int[monster]pluralm;load_current_map("pluralMonsters",pluralm);return(pluralm contains last_monster())?pluralm[last_monster()]:1}int howmanyfoes=how_many_foes();typedef float[element]spread;typedef int[stat]substats;record combat_rec{string ufname;string dmg;string dmgtypes;string special};record advevent{string id;spread dmg;float att;float def;float stun;float hp;float mp;float meat};advevent base;advevent retal;advevent onhit;base.id="base";retal.id="retal";onhit.id="onhit";spread merge(spread fir,spread sec){spread res;res[$element[none]]=fir[$element[none]]+sec[$element[none]];foreach el in $elements[]if((fir contains el)||(sec contains el))res[el]=fir[el]+sec[el];return res}advevent merge(advevent fir,advevent sec){advevent res;res.id=fir.id+"; "+sec.id;res.dmg=merge(fir.dmg,sec.dmg);res.att=fir.att+sec.att;res.def=fir.def+sec.def;res.stun=(fir.stun>=1.0||sec.stun>=1.0)?max(fir.stun,sec.stun):fir.stun+sec.stun-fir.stun*sec.stun;res.hp=fir.hp+sec.hp;res.mp=fir.mp+sec.mp;res.meat=fir.meat+sec.meat;return res}advevent merge(advevent fir,advevent sec,advevent thr){return merge(merge(fir,sec),thr)}spread factor(spread f,float fact){foreach el in f f[el]*=fact;return f}advevent factor(advevent a,float fact){a.dmg=factor(a.dmg,fact);a.att*=fact;a.def*=fact;a.stun*=fact;a.hp*=fact;a.mp*=fact;a.meat*=fact;return a}string elem_to_color(element src){switch(src){case $element[hot]:return"red";case $element[cold]:return"blue";case $element[spooky]:return"gray";case $element[sleaze]:return"purple";case $element[stench]:return"green"}return"black"}string to_html(spread src){buffer b;if(src contains $element[none])b.append(rnum(src[$element[none]]));b.append("<b>");foreach el in $elements[]if(src contains el&&src[el]!=0)b.append(" <span style='color: "+elem_to_color(el)+"'>("+rnum(src[el])+")</span>");return b.to_string()+"</b>"}spread to_spread(float dmg,string types,float factor){spread res;if(dmg<=0)return res;string[int]t=split_string(types,",");foreach i,bit in t res[to_element(bit)]=factor*dmg/to_float(count(t));return res}spread to_spread(float dmg,string types){return to_spread(dmg,types,1.0)}float item_val(item i);float dmg_dealt(spread action);advevent to_event(string id,spread dmg,string special){int aoe=(howmanyfoes>1&&contains_text(special,"aoe "))?min(howmanyfoes,to_int(substring(excise(special,"aoe ",""),0,1))):1;advevent res;res.id=id;res.dmg=factor(dmg,aoe);fvars["dmg"]=dmg_dealt(res.dmg);string[int]parts=split_string(special,", ");if(count(parts)>0)foreach num,bit in parts{if(contains_text(bit," "))switch(excise(bit,""," ")){case"att":res.att=aoe*eval(excise(bit," ",""),fvars);break;case"def":res.def=aoe*eval(excise(bit," ",""),fvars);break;case"stun":res.stun=eval(excise(bit," ",""),fvars);break;case"hp":res.hp=eval(excise(bit," ",""),fvars);break;case"mp":res.mp=eval(excise(bit," ",""),fvars);break;case"meat":res.meat=eval(excise(bit," ",""),fvars);break;case"item":string[int]its=split_string(excise(bit," ",""),"; ");float v;foreach n,it in its{if(id=="crown"&&$ints[3450,4469,1445,1446,1447,1448]contains to_int(to_item(it))&&stolen contains to_item(it)){v=0;break}v+=item_val(to_item(it))}res.meat+=v/count(its);break;case"monster":if(last_monster()!=to_monster(excise(bit," ","")))return to_event(id,to_spread(0,"physical"),"");case"notmonster":if(last_monster()==to_monster(excise(bit," ","")))return to_event(id,to_spread(0,"physical"),"")}}return res}advevent to_event(string id,combat_rec src){return to_event(id,to_spread(eval(src.dmg,fvars),src.dmgtypes),src.special)}spread get_resistance(element which){spread res;foreach el in $elements[]res[el]=0;res[$element[none]]=0;if(which!=$element[none])res[which]=1;switch(which){case $element[hot]:res[$element[sleaze]]=-1;res[$element[stench]]=-1;break;case $element[spooky]:res[$element[hot]]=-1;res[$element[stench]]=-1;break;case $element[cold]:res[$element[hot]]=-1;res[$element[spooky]]=-1;break;case $element[sleaze]:res[$element[cold]]=-1;res[$element[spooky]]=-1;break;case $element[stench]:res[$element[cold]]=-1;res[$element[sleaze]]=-1;break}return res}spread mres=get_resistance(monster_element());boolean isseal;switch(last_monster()){case $monster[trophyfish]:foreach el in $elements[]mres[el]=0.25;case $monster[war frat kegrider]:case $monster[war hippy dread squad]:mres[$element[none]]=0.25;break;case $monster[gargantuchicken]:case $monster[heavy kegtank]:case $monster[mobile armored sweat lodge]:mres[$element[none]]=0.5;break;case $monster[frosty]:foreach el in $elements[]mres[el]=1;case $monster[snow queen]:case $monster[chalkdust wraith]:case $monster[ancient protector spirit]:case $monster[Protector Spectre]:case $monster[booty crab]:case $monster[ghost miner]:mres[$element[none]]=1;break;case $monster[broodling seal]:case $monster[centurion of sparky]:case $monster[hermetic seal]:case $monster[spawn of wally]:case $monster[heat seal]:case $monster[navy seal]:case $monster[servant of grodstank]:case $monster[shadow of black bubbles]:case $monster[watertight seal]:case $monster[wet seal]:isseal=true;if(item_type(equipped_item($slot[weapon]))=="club")break;case $monster[hulking construct]:mres[$element[none]]=1;case $monster[zombo]:case $monster[spooky hobo]:foreach el in $elements[]mres[el]=1;break;case $monster[the ghost of fernswarthy n great-grandfather]:mres[$element[none]]=1;maxround=50;break;case $monster[a n stone golem]:mres[$element[none]]=0.5;case $monster[the beast with n ears]:case $monster[the beast with n eyes]:case $monster[a n-headed hydra]:case $monster[n bottles of beer on a golem]:case $monster[a n-dimensional horror]:case $monster[the naughty sorceress]:case $monster[naughty sorceress(2)]:case $monster[the man]:case $monster[big wisniewski]:maxround=50;break;case $monster[blackberry bush]:case $monster[cactuary]:if(weapon_type(equipped_item($slot[weapon]))!=$stat[moxie])onhit.hp-=5.3;break;case $monster[quiet healer]:base.hp+=0.25*17.5;break;case $monster[knob goblin mad scientist]:base.mp+=0.25*9;break}spread pres=get_resistance($element[none]);foreach el in $elements[]{if(el!=$element[slime]&&have_effect(to_effect(to_string(el)+"form"))>0){pres=get_resistance(el);break}pres[el]=elemental_resistance(el)/100.0}float dmg_dealt(spread action){float res;element eform;foreach el in $elements[]if(el!=$element[slime]&&have_effect(to_effect(to_string(el)+"form"))>0){eform=el;break}foreach el in action{if(eform==$element[none])res+=max(to_int(action[el]>0),action[el]-mres[el]*action[el]);else res+=action[el]}if(eform==$element[none])return min(res,monster_stat("hp"));return max(to_int(res>0),res-mres[eform]*res)}int hpgoal=round(to_float(get_property("hpAutoRecoveryTarget"))*to_float(my_maxhp()));int hpmin=round(to_float(get_property("hpAutoRecovery"))*to_float(my_maxhp()));float meatpermp,meatperhp;if(get_property("_meatpermp")!="")meatpermp=to_float(get_property("_meatpermp"));else{if(my_primestat()==$stat[mysticality]||(my_class()==$class[accordion thief]&&my_level()>8))meatpermp=100.0/(1.5*to_float(my_level())+5);else if(have_outfit("Elite Guard"))meatpermp=8;else meatpermp=17-to_int(galaktik_cures_discounted())*5}if(get_property("_meatperhp")!="")meatperhp=to_float(get_property("_meatperhp"));else meatperhp=10-to_int(galaktik_cures_discounted())*4;float stat_value(substats s){float res,i;foreach st,v in s{i=v*to_float(vars["BatMan_baseSubstatValue"]);if(st==my_primestat())i*=2.0;if(st==current_hit_stat())i*=1.5;if(my_buffedstat(st)==my_defstat())i*=1.5;res+=i}vprint("Value of stat gain: "+rnum(res),10);return res}substats m_stats(){stat d_stat(){return(string_modifier("Stat Tuning")=="")?my_primestat():string_modifier("Stat Tuning").to_stat()}substats res;foreach st in $stats[]res[st]=numeric_modifier(st+" Experience")+((monster_attack()-monster_level_adjustment())/16.0)*(1+to_int(st==d_stat()));return res}float item_val(item i){if(is_tradeable(i)&&historical_price(i)>max(100,2*autosell_price(i)))return historical_price(i);return autosell_price(i)}float item_val(item i,float rate){float modv=item_val(i)*minmax(rate*(item_drop_modifier()+100)/100.0,0,100)/100.0;vprint(i+" ("+rate+" @ +"+item_drop_modifier()+"): "+item_val(i)+" meat * "+minmax(rate*(item_drop_modifier()+100)/100.0,0,100)+"% = "+modv,8);return modv}float monstervalue(){float res=to_float(meat_drop())*(max(0,meat_drop_modifier()+100))/100.0;int skipped;should_pp=(monster_attack()==0);foreach num,rec in item_drops_array(){switch(rec.type){case"p":if(my_primestat()!=$stat[moxie]||skipped>0)break;foreach dealy in stolen if(item_drops()contains dealy)break;res+=item_val(rec.drop)*minmax(rec.rate*(numeric_modifier("Pickpocket Chance")+100)/100.0,0,100)/100.0;should_pp=true;break;case"":if(stolen contains rec.drop&&skipped<stolen[rec.drop]){skipped+=1;break}if(!should_pp&&count(stolen)==0&&rec.rate*(item_drop_modifier()+100)/100.0<100)should_pp=true;case"c":if(item_type(rec.drop)=="shirt"&&!have_skill($skill[torso awaregness]))break;if(!is_displayable(rec.drop))break;case"n":res+=item_val(rec.drop,max(rec.rate,0.01))}}return res+stat_value(m_stats())}float runaway_cost(){return monstervalue()+to_int(get_property("valueOfAdventure"))}float beatenup_cost(){if(my_familiar()==$familiar[wild hare])return 0;if(item_amount($item[personal massager])>0)return 100;float cheapest=to_int(get_property("valueOfAdventure"))*3;if(have_skill($skill[tongue of the otter]))cheapest=min(cheapest,meatpermp*mp_cost($skill[tongue of the otter]));if(have_skill($skill[tongue of the walrus]))cheapest=min(cheapest,meatpermp*mp_cost($skill[tongue of the walrus]));if(item_amount($item[tiny house])>0)cheapest=min(cheapest,item_val($item[tiny house]));if(item_amount($item[forest tears])>0)cheapest=min(cheapest,item_val($item[forest tears]));if(item_amount($item[sgeea])>0)cheapest=min(cheapest,item_val($item[sgeea]));return cheapest}float beatenup=beatenup_cost()+runaway_cost();combat_rec[string,int]factors;load_current_map("batfactors",factors);if(last_monster()==$monster[mother slime]||last_monster()==$monster[chester]||have_effect($effect[form of...bird])>0){remove factors["item"];vprint("You can't use items in this combat.",-6)}if(have_effect($effect[temporary amnesia])>0){remove factors["skill"];vprint("You can't cast any skills with amnesia!",-5)}float spell_elem_bonus(string types){float result;int milieu=0;foreach el in $elements[]{if(types.contains_text(to_string(el))){milieu+=1;result+=numeric_modifier(to_string(el)+" Spell Damage")}}if(milieu==0)return 0;return(result/(milieu+to_int(types.contains_text("physical"))))}string normalize_dmgtype(string dmgt){switch(dmgt){case"pasta":if(have_equipped($item[chester aquarius medallion])||have_equipped($item[sinful desires]))return"sleaze";if(have_equipped($item[necrotelicomnicon]))return"spooky";if(have_equipped($item[cookbook of the damned]))return"stench";case"sauce":if(have_equipped($item[ol' scratch's manacles])||have_equipped($item[capsaicin conjuration])||have_equipped($item[snapdragon pistil]))return"hot";if(have_equipped($item[glacial grimoire])||have_equipped($item[double-ice box]))return"cold";if(dmgt=="sauce"){if(have_skill($skill[immaculate seasoning])&&dmg_dealt(to_spread(1+spell_elem_bonus("hot"),"hot"))!=dmg_dealt(to_spread(1+spell_elem_bonus("cold"),"cold")))return(dmg_dealt(to_spread(1+spell_elem_bonus("hot"),"hot"))>dmg_dealt(to_spread(1+spell_elem_bonus("cold"),"cold")))?"hot":"cold";return"hot,cold"}if(have_effect($effect[spirit of cayenne])>0)return"hot";if(have_effect($effect[spirit of peppermint])>0)return"cold";if(have_effect($effect[spirit of garlic])>0)return"stench";if(have_effect($effect[spirit of wormwood])>0)return"spooky";if(have_effect($effect[spirit of bacon grease])>0)return"sleaze";string res="cold,hot,sleaze,spooky,stench,physical";if(res.contains_text(monster_element()))res.replace_string(monster_element()+",","");return res}return dmgt}foreach ty,in,rec in factors{string deranged(string sane){matcher rng=create_matcher("\\{.+?,(.+?),.+?}",sane);while(rng.find())sane=sane.replace_string(rng.group(0),rng.group(1));return sane}if(contains_text(rec.special,"custom")){remove factors[ty,in];continue}factors[ty,in].dmg=deranged(rec.dmg);factors[ty,in].special=deranged(rec.special);if(ty=="skill"){factors[ty,in].dmgtypes=normalize_dmgtype(rec.dmgtypes);if(to_skill(in)==$skill[weapon of the pastalord]&&!contains_text(factors[ty,in].dmgtypes,"physical"))factors[ty,in].dmgtypes+=",physical"}}advevent famevent(){advevent res;res.id=to_string(my_familiar());if(famspent)return res;if(!(factors["fam"]contains to_int(my_familiar()))||(my_familiar()==$familiar[dandy lion]&&item_type(equipped_item($slot[weapon]))!="whip"))return res;fvars["fweight"]=familiar_weight(my_familiar())+weight_adjustment()+min(20,2*my_level())*to_int(to_int(my_class())+82==to_int(my_familiar()));if(my_familiar()==$familiar[mad hatrack]){if(get_power(equipped_item($slot[familiar]))>0&&get_power(equipped_item($slot[familiar]))<200)fvars["fweight"]=min(fvars["fweight"],floor(get_power(equipped_item($slot[familiar]))/4.0));res=to_event(to_string(my_familiar()),factors["hatrack",to_int(equipped_item($slot[familiar]))])}else res=to_event(to_string(my_familiar()),factors["fam",to_int(my_familiar())]);if(round>9)res.meat=0;matcher rate=create_matcher("rate (.+?)(, |$)",factors["fam",to_int(my_familiar())].special);float r=(rate.find())?eval(rate.group(1),fvars):0;if(r==0||r==1)return factor(res,r);return factor(res,minmax(r+min(0.1,have_effect($effect[jingle jangle jingle]))+min(0.25,to_int(have_equipped($item[loathing legion helicopter]))),0,1.0))}advevent crown(){advevent res;res.id="crown";boolean cutoff=factors["crown",to_int(my_enthroned_familiar())].special.contains_text("r3");if(cutoff&&round>3)return res;res=to_event("crown",factors["crown",to_int(my_enthroned_familiar())]);float crownrate=(cutoff)?1:0.315;switch(my_enthroned_familiar()){case $familiar[chihuahua]:case $familiar[sandworm]:case $familiar[snow angel]:crownrate=0.5;break;case $familiar[Green Pixie]:crownrate=0.2;break;case $familiar[Maple Leaf]:crownrate=0.25;break;case $familiar[Black Cat]:crownrate=1;break}return factor(res,crownrate)}advevent baseround(){return(have_equipped($item[crown of thrones])&&my_enthroned_familiar()!=$familiar[none]&&factors["crown"]contains to_int(my_enthroned_familiar()))?merge(base,famevent(),crown()):merge(base,famevent())}foreach ef,fect in factors["effect"]{if(have_effect(to_effect(ef))==0)continue;vprint_html("Factoring in "+to_effect(ef)+": "+to_html(to_spread(eval(fect.dmg,fvars),fect.dmgtypes))+" damage, "+fect.special,4);if(contains_text(fect.special,"retal"))retal=merge(retal,to_event(to_effect(ef),fect));else if(contains_text(fect.special,"onhit"))onhit=merge(onhit,to_event(to_effect(ef),fect));else base=merge(base,to_event(to_effect(ef),fect))}foreach eq,uip in factors["gear"]{if(!have_equipped(to_item(eq)))continue;vprint_html("Factoring in "+to_item(eq)+": "+to_html(to_spread(eval(uip.dmg,fvars),uip.dmgtypes))+" damage, "+uip.special,4);if(contains_text(uip.special,"retal"))retal=merge(retal,to_event(to_item(eq),uip));else if(contains_text(uip.special,"onhit"))onhit=merge(onhit,to_event(to_item(eq),uip));else base=merge(base,to_event(to_item(eq),uip))}float fumble_chance(){if(have_effect($effect[clumsy])>0)return 1;if(boolean_modifier("Never Fumble"))return 0;return(1.0/max(22.0,to_int(have_effect($effect[sticky hands])>0)*30.0))*max(1.0,numeric_modifier("Fumble"))/(1.0+to_int(have_skill($skill[eye of the stoat])))}float fumble_damage(){int wpnpwr=get_power(equipped_item($slot[weapon]));if(have_skill($skill[double-fisted skull smashing])&&item_type(equipped_item($slot[offhand]))!="shield")wpnpwr+=get_power(equipped_item($slot[offhand]));return max(1.0,to_float(wpnpwr)*0.05)}onhit.hp=(-fumble_chance()*fumble_damage());float m_hit_chance(){float stunmod=min(1.0,stunadj+0.5*(1.0-min(1.0,stunadj))*to_int(have_equipped($item[navel ring of navel gazing])));if(contains_text(last_monster(),"Gremlin"))return 1.0-stunmod;return(1.0-stunmod)*minmax(0.55+(max(monster_stat("att"),0.0)-my_buffedstat($stat[moxie]))*0.055,0.06,0.94)}float m_regular(){float res;res=max(1.0,max(0.0,max(monster_stat("att"),0.0)-my_defstat())+0.225*max(monster_stat("att"),0.0)-numeric_modifier("Damage Reduction"))*(1-minmax((square_root(numeric_modifier("Damage Absorption")/10)-1)/10,0,0.9));if(monster_element()==$element[none])return minmax(res,1.0,my_hp());return minmax(res-pres[monster_element()]*res,1.0,my_hp())}float m_dpr(float att_mod,float stun_mod){attadj+=att_mod;stunadj+=stun_mod;float res=m_hit_chance()*m_regular();attadj-=att_mod;stunadj-=stun_mod;return res}boolean intheclear(){if(stunadj>0.94)return true;if(last_monster()==$monster[none]||m_dpr(0,0)>my_hp()||have_effect($effect[strangulated])>0)return false;return(monster_stat("att")<my_defstat()-6+to_int(vars["threshold"]))}float to_profit(advevent a){float res;if(a.id!=to_string(my_familiar())&&!a.id.contains_text("base"))a=merge(a,baseround());if(dmg_dealt(a.dmg)<monster_stat("hp")){a=merge(a,factor(retal,m_hit_chance()));res-=m_dpr(a.att,a.stun)*meatperhp}return res+minmax(a.hp,-my_hp(),my_maxhp()-my_hp())*meatperhp+minmax(a.mp,-my_mp(),my_maxmp()-my_mp())*meatpermp+a.meat}string to_html(advevent a,boolean table){buffer res;if(table)res.append("<table width=100%><tr><th>Action</th><th>Profit</th><th>Damage</th><th>Other</th></tr>");res.append("<tr><td align=left>");switch{case(contains_text(a.id,"use ")):res.append("Throw "+excise(a.id,"use ",""));break;case(contains_text(a.id,"skill ")):res.append("Cast "+excise(a.id,"skill ",""));break;case(a.id=="attack"):res.append("Attack with weapon");break;case(a.id=="jiggle"):res.append("Jiggle Your Chefstaff");break;default:res.append(a.id)}res.append(" <span color='green'><small>("+rnum(a.meat)+"&mu;)</small></span></td><td align=right><span color='green'><b>");res.append(rnum(to_profit(a))+"&mu;</b></span></td><td align=center>");if(dmg_dealt(a.dmg)>0){res.append(to_html(a.dmg)+" <small>");if(a.dmg[$element[none]]!=dmg_dealt(a.dmg))res.append("Actual: "+rnum(dmg_dealt(a.dmg)));res.append(" <span color='green'>("+rnum(-a.meat/dmg_dealt(a.dmg))+" MPD)</span></small>")}else res.append("--");res.append("</td><td align=center>");if(a.att!=0)res.append(" <span color='gray'>Att: "+rnum(a.att)+" <small>("+rnum(m_dpr(a.att,0)-m_dpr(0,0))+" DPR)</small> Def: "+rnum(a.def)+"</span> ");if(a.stun!=0)res.append(" "+rnum(a.stun*100.0)+"% stun chance");if(a.hp!=0)res.append(" <span color='red'>HP: "+rnum(a.hp)+"</span> ");if(a.mp!=0)res.append(" <span color='blue'>MP: "+rnum(a.mp)+"</span> ");res.append("</td></tr>");if(table)res.append("</table>");return res.to_string()}string to_html(advevent a){return to_html(a,true)}advevent[int]custom;advevent[int]opts;void addopt(advevent a,float cost,float factor){int c=count(opts);opts[c]=a;if(last_monster()==$monster[mine crab]&&dmg_dealt(a.dmg)>39)a.hp-=100000;if(factor!=1.0)opts[c]=factor(opts[c],factor);opts[c].meat-=cost}advevent bander(int which){if(!smusted&&factors["bander",which].special.contains_text("smust"))return to_event("#bander",to_spread(0,"physical"),"stun 2");return to_event("#bander",factors["bander",which])}combat_rec get_bang(string which){combat_rec res;res.dmg="0";res.dmgtypes="physical";switch(which){case"healing":res.dmg="-14";return res;case"confusion":res.special="att -2.5, def -2.5";return res;case"ettin strength":res.special="att 10";return res;case"mental acuity":res.special="att 5, def 5";return res;case"teleportitis":res.special="def 17.5";return res;case"blessing":res.special="def 25";return res;case"detection":case"sleepiness":case"inebriety":return res}string known;for i from 819 upto 827 known+=get_property("lastBangPotion"+i);advevent bang;float bcount;foreach bp in $strings[healing,confusion,ettin strength,mental acuity,teleportitis,blessing,detection,sleepiness,inebriety]{if(contains_text(known,bp))continue;bcount+=1;bang=merge(bang,to_event("",get_bang(bp)))}if(bcount>1)bang=factor(bang,1.0/bcount);res.dmg=bang.dmg[$element[none]];if(bang.att!=0)res.special="att "+bang.att;if(bang.def!=0)res.special="def "+bang.att;return res}combat_rec get_sphere(string which){combat_rec res;res.dmg="0";res.dmgtypes="physical";switch(which){case"fire":res.dmg="9";res.dmgtypes="hot";return res;case"nature":res.special="att -2, def -2, stun 1";return res;case"lightning":res.dmg="9";return res;case"water":res.special="hp 4.5";return res}return res}float hitchance(int ts){float attack=my_buffedstat(weapon_type(equipped_item($slot[weapon])));switch(ts){case 0:attack=my_buffedstat($stat[moxie]);break;case 2:if(have_skill($skill[eye of the stoat]))attack+=20;case 3:if(my_class()==$class[seal clubber]&&item_type(equipped_item($slot[weapon]))=="club"&&weapon_hands(equipped_item($slot[weapon]))==2)return 1.0;if(ts==2)break;if(have_skill($skill[eye of the stoat]))attack*=1.25+0.05*to_int(my_class()==$class[seal clubber]);break;case 4:attack=my_buffedstat($stat[muscle])+20}return minmax((6.0+attack-max(monster_stat("def"),0.0))/10.5,0.0,1.0)*(1.0-fumble_chance())}spread regular(int ts){spread res;if(ts!=0&&last_monster()==$monster[a n-dimensional horror])return res;float ltsadj=(ts==3)?1.25+0.05*to_int(my_class()==$class[seal clubber]):(ts==5)?1.4:1.0;boolean ranged=(weapon_type(equipped_item($slot[weapon]))==$stat[moxie]&&ts>0);float radj=(ranged)?0.75:1.0;if(equipped_item($slot[weapon])==$item[none])radj=0.25+0.75*to_int(ts==0);res[$element[none]]=max(0,max(0,floor(my_buffedstat($stat[muscle])*ltsadj*radj)-monster_stat("def"))+max(1,0.15*get_power(equipped_item($slot[weapon]))+0.5)*1.09*max(1.0,ts)+numeric_modifier("Weapon Damage")+to_int(ranged)*numeric_modifier("Ranged Damage"))*(100+numeric_modifier("Weapon Damage Percent")+to_int(ranged)*numeric_modifier("Ranged Damage Percent"))/100;if(have_skill($skill[double-fisted])&&to_slot(equipped_item($slot[offhand]))==$slot[weapon])res[$element[none]]+=0.15*get_power(equipped_item($slot[offhand]))+0.5;if(ts>0)foreach el in $elements[]if(numeric_modifier(el+" Damage")>0)res[el]=numeric_modifier(el+" Damage");return res}float dam,rate;void build_items(float factor){foreach it,fields in factors["item"]{if(item_amount(to_item(it))==0)continue;rate=item_val(to_item(it))*to_int(!to_item(it).reusable||last_monster()==$monster[the naughty sorceress]||last_monster()==$monster[bonerdagon]);switch(it){case 3388:if(get_counters("Zombo's Empty Eye",0,50)!="")continue;break;case 2065:if(my_location()!=$location[battlefield(frat uniform)]||string_modifier("Outfit")!="Frat Warrior Fatigues"||get_counters("PADL Phone",0,10)!="")continue;case 2354:if(to_float(my_hp())/my_maxhp()<0.25)fields.special="hp 275";else if(to_float(my_mp())/my_maxmp()<0.25)fields.special="mp 175";else fields.dmg="175";if(to_item(it)==$item[PADL phone])break;if(my_location()!=$location[battlefield(hippy uniform)]||get_counters("Communications Windchimes",0,10)!=""||string_modifier("Outfit")!="War Hippy Fatigues")continue;break;case 3101:rate*=0.5;break;case 819:case 820:case 821:case 822:case 823:case 824:case 825:case 826:case 827:if(get_property("lastBangPotion"+it)==""){if(item_amount(to_item(it))>to_int(get_property("autoPotionID")=="false"))custom[count(custom)]=to_event("use "+it,get_bang(""));continue}fields=get_bang(get_property("lastBangPotion"+it));break;case 2174:case 2175:case 2176:case 2177:if(get_property("lastStoneSphere"+it)==""&&get_property("autoSphereID")=="true"){custom[count(custom)]=to_event("use "+it,get_sphere(""));continue}fields=get_sphere(get_property("lastStoneSphere"+it));break}fvars["itemamount"]=item_amount(to_item(it));dam=eval(fields.dmg,fvars);if(isseal&&dam>0)dam=min(1.0,dam);else if(have_equipped($item[v for vivala mask]))dam*=1.5;addopt(to_event("use "+it,to_spread(dam,fields.dmgtypes),fields.special),rate,factor)}}void build_skills(string page,float factor){if(count(factors["skill"])==0)return;vprint("1 MP costs "+meatpermp+" meat.",8);spread d;fvars["bonusdb"]=numeric_modifier("DB Combat Damage")+to_int(my_familiar()==$familiar[frumious bandersnatch])*0.75*(familiar_weight(my_familiar())+numeric_modifier("Familiar Weight"));int burrowgrub_amt(){return(1+to_int(have_effect($effect[yuletide mutations])>0))*min(my_level(),15)}foreach sk,fields in factors["skill"]{if(mp_cost(to_skill(sk))>my_mp())continue;if(!contains_text(page,"value=\""+sk+"\""))continue;fvars["elembonus"]=spell_elem_bonus(fields.dmgtypes);d=to_spread(0,"physical");switch(sk){case 7082:if(contains_text(page,"red eye")){d=to_spread((4.5-minmax(have_effect($effect[everything looks red]),0,2))*fvars["fweight"],"hot");if(have_effect($effect[everything looks red])>0)fields.special="stats "+(4.5*fvars["fweight"])+"-"+(4.5*fvars["fweight"])+"-"+(4.5*fvars["fweight"])}else if(contains_text(page,"blue eye")){if(have_effect($effect[everything looks blue])>0)d=to_spread(1.5*fvars["fweight"],"cold");else fields.special="stun 3"}else if(contains_text(page,"yellow eye")){if(have_effect($effect[everything looks yellow])>0)d=to_spread(0.75*fvars["fweight"],"physical");else d=to_spread(6*monster_hp(),"hot,cold,spooky,sleaze,stench,physical")}break;case 7074:if(my_maxhp()-my_hp()<=2*burrowgrub_amt()||my_maxmp()-my_mp()<=burrowgrub_amt())continue;break;case 7061:fvars["wpnpower"]=get_power(equipped_item($slot[weapon]));break;case 7003:case 7004:case 7005:case 7006:case 7007:fvars["breath"]=have_effect(to_effect(to_skill(sk)));case 7081:fvars["botcharges"]=get_property("bagOTricksCharges").to_int();default:dam=eval(fields.dmg,fvars);if(isseal&&dam>0)dam=max(1.0,dam);d=to_spread(dam,fields.dmgtypes);if(contains_text(fields.special,"regular"))switch(sk){case 7008:d=factor(regular(0),hitchance(0));break;case 1003:d=factor(regular(2),hitchance(2));break;case 1005:d=factor(regular(3),hitchance(3));break;case 7096:d=regular(5);break;case 7097:d=factor(regular(1),hitchance(1)*7);break;case 2015:case 2103:d=factor(merge(d,regular(1)),hitchance(4));break;default:d=merge(d,regular(1))}}advevent bander(int which){if(!smusted&&factors["bander",which].special.contains_text("smust"))return to_event("#bander",to_spread(0,"physical"),"stun 2");return to_event("#bander",factors["bander",which])}if(my_familiar()==$familiar[bandersnatch]&&factors["bander"]contains sk)addopt(merge(bander(sk),to_event("skill "+to_skill(sk),d,"mp -"+mp_cost(to_skill(sk))+", "+fields.special)),0,factor);else addopt(to_event("skill "+to_skill(sk),d,"mp -"+mp_cost(to_skill(sk))+", "+fields.special),0,factor)}}void build_options(string page){clear(opts);fvars["monsterhp"]=monster_stat("hp");fvars["monsterattack"]=monster_stat("att");fvars["buffedmys"]=my_buffedstat($stat[mysticality]);fvars["buffedmus"]=my_buffedstat($stat[muscle]);fvars["buffedmox"]=my_buffedstat($stat[moxie]);fvars["maxhp"]=my_maxhp();fvars["myhp"]=my_hp();fvars["mymp"]=my_mp();float factor=1.0-0.5*to_int(have_effect($effect[cunctatitis])>0);addopt(to_event("attack",factor(regular(1),hitchance(1)),"hp "+to_string(-fumble_chance()*fumble_damage())),0,factor);if(item_type(equipped_item($slot[weapon]))=="chefstaff"&&contains_text(page,"<form name=chefstaffform")&&factors["chef"]contains to_int(equipped_item($slot[weapon]))){if(isseal)factors["chef",to_int(equipped_item($slot[weapon]))].dmg="1";addopt(to_event("jiggle",factors["chef",to_int(equipped_item($slot[weapon]))]),0,1)}float ifactor=factor-0.5*to_int(my_familiar()==$familiar[black cat]);if(contains_text(to_string(last_monster()),"Naughty Sorceress")||last_monster()==$monster[bonerdagon])ifactor*=0.75;build_items(ifactor);if(contains_text(to_string(last_monster()),"Naughty Sorceress")||last_monster()==$monster[bonerdagon])factor*=0.5;build_skills(page,factor);int monster_kill_rounds(float dmg){if(dmg==0)return 999999;return ceil(to_float(monster_stat("hp"))/(dmg+m_hit_chance()*dmg_dealt(retal.dmg)+dmg_dealt(base.dmg)))}if(last_monster()==$monster[your shadow])foreach i,opt in opts if(opt.hp<=0)remove opts[i];sort opts by monster_kill_rounds(dmg_dealt(value.dmg))*max(1,-value.meat)}advevent stasis_action(){sort opts by-to_profit(value);sort opts by dmg_dealt(value.dmg);foreach i,opt in opts{if(contains_text(opt.id,"use ")&&!to_item(excise(opt.id,"use ","")).reusable)continue;return opt}return new advevent}advevent stun_action(boolean foritem){sort opts by-to_profit(value)/max(0.00001,value.stun-1+to_int(foritem&&have_skill($skill[funkslinging])&&contains_text(value.id,"use ")));foreach i,opt in opts{if(opt.stun>1-to_int(foritem&&have_skill($skill[funkslinging])))return opt;else break}return new advevent}advevent get_action(string whichid){foreach i,opt in opts if(opt.id==whichid)return opt;return new advevent}advevent get_action(item it){return get_action("use "+to_int(it))}advevent get_action(skill sk){return get_action("skill "+to_int(sk))}string act(string action){round=to_int(excise(action,"var onturn = ",";"));if(round==0)round=maxround;if(!famspent)switch(my_familiar()){case $familiar[hobo monkey]:if(contains_text(action,"your shoulder, and hands you some Meat"))famspent=true;break;case $familiar[gluttonous green ghost]:if(!contains_text(action,"/ggg.gif")&&!contains_text(action,"You quickly conjure a saucy salve")){print("Your ghost is hongry.","olive");famspent=true}break;case $familiar[slimeling]:if(!contains_text(action,"/slimeling.gif")&&!contains_text(action,"You quickly conjure a saucy salve")){print("Your slimeling needs sating.","olive");famspent=true}break;case $familiar[spirit hobo]:if(contains_text(action,"Oh, Helvetica,")||contains_text(action,"millennium hands and shrimp.")){print("Your hobo is now sober.  Sober hobo sober hobo.","olive");famspent=true}break}if(my_familiar()==$familiar[bandersnatch]&&contains_text(action,"cloud of smust"))smusted=true;if(my_location()==$location[outside the club]&&contains_text(action,"You lazily wave your hands"))waved=true;foreach doodad,n in extract_items(action){stolen[doodad]+=n;if(contains_text(action,"grab something")||contains_text(action,"You manage to wrest")||(my_class()==$class[disco bandit]&&contains_text(action,"knocked loose some treasure."))){vprint_html("<span color='green'>You snatched a "+doodad+" ("+rnum(item_val(doodad))+" &mu;)!</span>",5);should_pp=vprint("Revised monster value: "+rnum(monstervalue()),"green",-4)}else vprint_html("<span color='green'>Look! You found "+n+" "+doodad+" ("+rnum(n*item_val(doodad))+" &mu;)!</span>",5)}if(have_equipped($item[bag o tricks]))switch{case(contains_text(action,"Bag o' Tricks begins squirming")):case(contains_text(action,"Bag o' Tricks continues")):set_property("bagOTricksCharges","3");break;case(contains_text(action,"Bag o' Tricks begins")):set_property("bagOTricksCharges","2");break;case(contains_text(action,"Bag o' Tricks suddenly feels")):set_property("bagOTricksCharges","1");break;case(contains_text(action,"a single fat bumblebee")):case(contains_text(action,"You open the bag and ")):set_property("bagOTricksCharges","0");break}if(last_monster()==$monster[mother slime]){if(contains_text(action,"ground trembles as Mother Slime shudders"))mres[$element[none]]=1.0;if(contains_text(action,"Veins of purple shoot"))mres[$element[sleaze]]=1.0;if(contains_text(action," a bluish tinge"))mres[$element[cold]]=1.0;if(contains_text(action,"skin becomes ashy and gray"))mres[$element[spooky]]=1.0;if(contains_text(action,"Mother Slime becomes decidedly more reddish"))mres[$element[hot]]=1.0;if(contains_text(action,"looks greener than she did a minute ago"))mres[$element[stench]]=1.0}build_options(action);if(my_location()==$location[slime tube]&&contains_text(action,"a massive loogie that sticks")&&equipped_item($slot[weapon])==$item[none])vprint("Your rusty weapon has been slimed!  Finish combat by yourself.",0);if(get_property("autoAntidote")!="0"){int poison_level(){if(have_effect($effect[Toad In The Hole])>0)return 1;if(have_effect($effect[Majorly Poisoned])>0)return 2;if(have_effect($effect[Really Quite Poisoned])>0)return 3;if(have_effect($effect[Somewhat Poisoned])>0)return 4;if(have_effect($effect[A Little Bit Poisoned])>0)return 5;if(have_effect($effect[Hardly Poisoned at All])>0)return 6;return 0}if(have_effect($effect[Duct Out of Water])>0&&poison_level()>1)return act(use_skill($skill[spew poison]));if(poison_level()>0){vprint("Poison level: "+poison_level()+" (set to remove if "+get_property("autoAntidote")+" or lower)","olive",2);if(item_amount($item[anti-anti-antidote])>0&&poison_level()<=to_int(get_property("autoAntidote")))return act(throw_item($item[anti-anti-antidote]));}}if(item_amount($item[molybdenum magnet])>0&&contains_text(to_string(last_monster()),"Gremlin")&&!contains_text(action,"macroaction: use 2497")&&contains_text(action,"whips")&&(contains_text(action,"a hammer")||contains_text(action,"a crescent wrench")||contains_text(action,"pliers")||contains_text(action,"a screwdriver")))return act(throw_item($item[molybdenum magnet]));if(have_equipped($item[ruby rod])&&my_location()==$location[seaside megalopolis]&&(contains_text(action,"A mechanical hand emerges")||contains_text(action,"liquid nitrogen")||contains_text(action,"freaky alien thing")||contains_text(action,"vile-smelling, milky-white")||contains_text(action,"spinning, whirring, vibrating, tubular")))return act(attack());if(have_equipped($item[fouet de tortue-dressage])&&my_location()==$location[outer compound]&&(contains_text(action,"frenchturtle.gif")||get_property("lastNemesisReset").to_int()==my_ascensions())&&my_mp()>=5*mp_cost($skill[apprivoisez la tortue])){return visit_url("fight.php?action=macro&macrotext=skill 7083; repeat")}if(my_class()==$class[disco bandit]&&!waved&&have_skill($skill[gothy handwave])&&my_mp()>0){switch(last_monster()){case $monster[breakdancing raver]:if(!have_skill($skill[break it on down])&&!contains_text(action,"macroaction: skill 49")&&contains_text(action,"he raver drops "))return act(use_skill($skill[gothy handwave]));break;case $monster[pop-and-lock raver]:if(!have_skill($skill[pop and lock it])&&!contains_text(action,"macroaction: skill 49")&&contains_text(action,"movements suddenly became spastic and jerky."))return act(use_skill($skill[gothy handwave]));break;case $monster[running man]:if(!have_skill($skill[run like the wind])&&!contains_text(action,"macroaction: skill 49")&&contains_text(action,"The raver turns "))return act(use_skill($skill[gothy handwave]))}}if(my_familiar()==$familiar[he-boulder]&&have_effect($effect[everything looks yellow])==0&&contains_text(action," yellow eye")&&contains_text(to_lower_case(vars["ftf_yellow"]),to_lower_case(last_monster().to_string())))return act(use_skill($skill[point at your opponent]));return action}string batround(){buffer res;res.append("abort match effect*Poisoned || match effect*Toad || match \"a massive loogie\" || hpbelow "+round(m_dpr(0,0))+"; scrollwhendone; sub batround");if(item_amount($item[molybdenum magnet])>0&&contains_text(to_string(last_monster()),"Gremlin"))res.append("; if match whips && (match \"a hammer\" || match \"a crescent wrench\" || match pliers || match \"a screwdriver\"); item 2497; endif");if(have_equipped($item[ruby rod])&&my_location()==$location[seaside megalopolis])res.append("; if match \"A mechanical hand emerges\" || match \"liquid nitrogen\" || match \"freaky alien thing\" || "+"match \"vile-smelling, milky-white\" || match \"spinning, whirring, vibrating, tubular\"; attack; endif");if(my_class()==$class[disco bandit]&&have_skill($skill[gothy handwave])&&!waved)switch(last_monster()){case $monster[breakdancing raver]:if(!have_skill($skill[break it on down]))res.append("; if match \"he raver drops \"; skill 49; endif");break;case $monster[pop-and-lock raver]:if(!have_skill($skill[pop and lock it]))res.append("; if match \"movements suddenly became spastic and jerky.\"; skill 49; endif");break;case $monster[running man]:if(!have_skill($skill[run like the wind]))res.append("; if match \"The raver turns \"; skill 49; endif")}if(my_familiar()==$familiar[he-boulder]&&have_effect($effect[everything looks yellow])==0&&contains_text(to_lower_case(vars["ftf_yellow"]),to_lower_case(last_monster().to_string())))res.append("; if match \" yellow eye\"; skill 7082; endif");return res+"; endsub; "}string macro(string mac){return act(visit_url("fight.php?action=macro&macrotext="+url_encode(mac),true,true))}string macro(advevent todo,string rep){if(rep=="0")return macro(batround()+todo.id+"; call batround");return macro(batround()+"sub main; "+todo.id+"; call batround; endsub; call main; repeat "+rep)}string macro(advevent todo){return macro(todo,"0")}advevent[int]queue;string macro(){buffer m;m.append(batround());foreach i,o in queue m.append(o.id+"; call batround; ");if(have_skill($skill[funkslinging])){matcher funky=create_matcher("(use \\d+); call batround; use (\\d+;)",m);while(funky.find())m.replace_string(funky.group(0),funky.group(1)+","+funky.group(2))}vprint("Executing macro: "+m,9);return macro(to_string(m))}setvar("BatMan_macrofy",false);setvar("BatMan_profitforstasis",15.0);setvar("BatMan_baseSubstatValue",5.0);


    @Bale: That was a great explanation. (Although I think of get_action() as a simple map lookup -- there are no conversions happening in that function. But that's purely academic.) I would also avoid documenting macro(advevent,"0") -- the string there specifies (the) repeat condition(s) in BALLS. There is a single parameter version to simply perform an action once.

    The functions in BatBrain are, naturally, still evolving. The focus until now has been making all combat information available and accurate. The focus henceforth will be making that information easily usable -- which I've been figuring out by working on the new SS. The various get_action() functions were just added yesterday. SmartStasis will soon be using these functions rather than adding raw data to the custom actions list.

    Once the functions have stabilized, I'll throw BatBrain up on the ASH Wiki as a resource for combat scripters.

    I like your tweak to macro() -- will probably add it.
    Sig by JakAtk
    My scripts: One-Click Wossname | Om******* (??) | Psychose-a-Matic | RandBot
    Combat suite: Best Between Battle | Mer******** (?!) | SmartStasis | BatMan | BatMan RE
    For script authors: ASH Wiki | ZLib | BatBrain | CLI Links | CanAdv | Script Registry | Map Manager | About Bats
    If you appreciate my work, help me become BAT KING OF THE WORLD! Thanks to all donators!

  3. #13
    Minion Bale's Avatar
    Join Date
    Jun 2008
    Posts
    13,183

    Default

    I think of get_action() as a simple map lookup -- there are no conversions happening in that function. But that's purely academic.)
    Originally Posted by zarqon View Post
    Yup. I got that. However it was tough to really get my mind around the effects of get_action() until I reframed it that way. Then suddenly it became easy to use.


    I would also avoid documenting macro(advevent,"0") -- the string there specifies (the) repeat condition(s) in BALLS. There is a single parameter version to simply perform an action once.
    Ah. So there is! Just leave off the repeat parameter if you don't want to repeat! I won't document that again.


    I like your tweak to macro() -- will probably add it.
    Yay! I'm a superstar! I only spent a little over an hour studying BatBrain and I've already managed to improve it!
    If people like my scripts, please send me stuffed Hodgmen.
    Universal Recovery, OCD Inventory Control, CounterChecker, newLife, ChIT.


  4. #14
    Senior Member Winterbay's Avatar
    Join Date
    Feb 2010
    Posts
    5,033

    Default

    That's not easier
    Also, do you realy use three spaces as indentation or is it Notepad++ that converts something else into that? In my mind a simple tab would be much easier to do than three spaces...
    My scripts:
    Best sushi for Profit
    Winterbay's Helpful Automatic Monsterbasher (WHAM)

    Scripts maintained by me:
    Autobasement
    Smashlib

    A small programmer joke:
    Wife: Honey, please go to the market and buy 1 bottle of milk. If they have eggs, bring 6.
    The man came back with 6 bottles of milk.
    Wife: Why did you buy 6 bottles of milk.
    Man: Because they had eggs...

    The 6 Stages of Debugging: 1 )That can't happen. 2) That shouldn't happen. 3) Hmmm, weird. 4) Why does that happen? 5) Oh, I see. 6 )How did that ever work?

    All programs can be optimized, and all programs have bugs; therefore all programs can be optimized to one line that doesn’t work. /Bob Fitch, Blizzard

  5. #15
    Minion Bale's Avatar
    Join Date
    Jun 2008
    Posts
    13,183

    Default

    That's zarqon who uses three spaces, not me. I was only copying his method.

    I've got my own very simple consult script called FinalAttack.ash which I've been using to conclude a fight. (My version of spamattack.) I just modified it to use BatBrain. I'm not trying to be particularly optimal, I'm just trying to conclude a combat with any of my characters. (I sometimes edit it on the fly when I'm playing.) I am interested in zarqon's commentary about if I used BatBrain properly.

    PHP Code:
    import "BatBrain.ash";

    advevent dangeraction() {
        if(
    my_primestat() == $stat[moxie])
            return 
    get_action($skill[moxious maneuver]);
        else if(
    item_type(equipped_item($slot[off-hand])) == "shield" && have_skill($skill[Shieldbutt]))
            return 
    get_action($skill[Shieldbutt]);
        else if(
    have_skill($skill[Saucegeyser]))
            return 
    get_action($skill[Saucegeyser]);
        return 
    get_action("attack");
    }

    void main(int initroundmonster foestring page) {
        
    page act(page);
        switch(
    foe) {
        case 
    $monster[Candied Yam Golem]:
        case 
    $monster[Malevolent Tofurkey]:
        case 
    $monster[Possessed Can of Cranberry Sauce]:
        case 
    $monster[Stuffing Golem]:
        case 
    $monster[Inebriated Tofurkey]:
        case 
    $monster[Hammered Yam Golem]:
        case 
    $monster[Plastered Can of Cranberry Sauce]:
        case 
    $monster[Soused Stuffing Golem]:
        case 
    $monster[El Novio Cadáver]:
        case 
    $monster[El Padre Cadáver]:
        case 
    $monster[La Novia Cadáver]:
        case 
    $monster[La Persona Inocente Cadáver]:
        case 
    $monster[angry bassist]:
        case 
    $monster[blue-haired girl]:
        case 
    $monster[evil ex-girlfriend]:
        case 
    $monster[peeved roommate]:
        case 
    $monster[random scenester]:
            if(
    have_skill($skill[entangling noodles]))
                
    page macro(get_action($skill[entangling noodles])); 
            
    page macro(dangeraction(), ""); 
            break;
        default:
            
    page macro(get_action("attack"), "");
        }

    If people like my scripts, please send me stuffed Hodgmen.
    Universal Recovery, OCD Inventory Control, CounterChecker, newLife, ChIT.


  6. #16
    Senior Member Winterbay's Avatar
    Join Date
    Feb 2010
    Posts
    5,033

    Default

    So... trying this out. Would:
    Code:
    rounds = monster_stat("hp") / max(1,dmg_dealt(get_action("attack").dmg)) / hitchance(1)
    be the number of rounds it would take me to kill the monster taking my chance to hit ti into account?
    My scripts:
    Best sushi for Profit
    Winterbay's Helpful Automatic Monsterbasher (WHAM)

    Scripts maintained by me:
    Autobasement
    Smashlib

    A small programmer joke:
    Wife: Honey, please go to the market and buy 1 bottle of milk. If they have eggs, bring 6.
    The man came back with 6 bottles of milk.
    Wife: Why did you buy 6 bottles of milk.
    Man: Because they had eggs...

    The 6 Stages of Debugging: 1 )That can't happen. 2) That shouldn't happen. 3) Hmmm, weird. 4) Why does that happen? 5) Oh, I see. 6 )How did that ever work?

    All programs can be optimized, and all programs have bugs; therefore all programs can be optimized to one line that doesn’t work. /Bob Fitch, Blizzard

  7. #17
    Moderator
    Join Date
    Feb 2007
    Posts
    142

    Default

    There is a minor error on line 132 of the new version posted above - it's got 9,5 instead of what I assume should be 9.5

  8. #18
    Senior Member Winterbay's Avatar
    Join Date
    Feb 2010
    Posts
    5,033

    Default

    So, new version of the script. Found some small errors of placing in the spell damage formulas. This version does not use batbrain at all due to unexpected results in some ways and so I've reverted that for now

    Edit: It also fixes the 9,5 vs. 9.5 error. It does so by instead having 11 there
    My scripts:
    Best sushi for Profit
    Winterbay's Helpful Automatic Monsterbasher (WHAM)

    Scripts maintained by me:
    Autobasement
    Smashlib

    A small programmer joke:
    Wife: Honey, please go to the market and buy 1 bottle of milk. If they have eggs, bring 6.
    The man came back with 6 bottles of milk.
    Wife: Why did you buy 6 bottles of milk.
    Man: Because they had eggs...

    The 6 Stages of Debugging: 1 )That can't happen. 2) That shouldn't happen. 3) Hmmm, weird. 4) Why does that happen? 5) Oh, I see. 6 )How did that ever work?

    All programs can be optimized, and all programs have bugs; therefore all programs can be optimized to one line that doesn’t work. /Bob Fitch, Blizzard

  9. #19
    Senior Member zarqon's Avatar
    Join Date
    Nov 2007
    Location
    Seoul, Korea
    Posts
    3,370

    Default

    @Winterbay: hehehehehehehe

    You're mostly correct, but you don't need the max(1,dmg) -- that's already taken into account in dmg_dealt(). Also, your hit chance is already included in the attack event.

    To be entirely correct, you need to access a couple important advevents in BatBrain -- baseround() and retal. The baseround() event includes things that happen every round, such as passive damage and your familiar's attacks (even from the CoT). The retal event happens whenever the monster hits you and includes things like Saucespheres and pointy accessories. Here's the "very correct" way:

    PHP Code:
    killrounds ceil(monster_stat("hp") / (dmg_dealt(get_action("attack").dmg) + m_hit_chance()*dmg_dealt(retal.dmg) + dmg_dealt(baseround().dmg))) 
    Or, taking advantage of BatBrain's merge() and factor() functions for doing arithmetic with advevents:

    PHP Code:
    killrounds ceil(to_float(monster_stat("hp")) / dmg_dealt(merge(get_action("attack"), factor(retalm_hit_chance()), baseround()).dmg)) 
    The first one is actually more accurate, however, since if the monster has resistances the multiple sources of damage will all be reduced, yet they will still add up to more than one.

    @Bale: well done; your example has convinced me to add the tweak you suggested right now. The alternative in your above example would be to add noodles to the queue and then spam the queue with dangeraction, then call macro(), which is slightly inelegant in that it ignores the capability of BALLS to spam actions on your behalf.

    I'm also going to clear the queue in macro() after executing it, so you need not bother clearing it anymore.

    As far as whether you're using BatBrain correctly, yes. However, you are making unnecessary checks. If get_action() returns an empty event, the skill is unavailable. Otherwise, the skill is available. This will do the same as you posted:

    PHP Code:
    advevent dangeraction() {
       foreach 
    da in $strings[skill 7008skill 2005skill 4012attack]
          if (
    get_action(da).id != "") return get_action(da);
       return new 
    advevent;    // you should never reach this

    I suppose if my feature request is implemented that undisambiguates/ambiguates your various shadows, you could reach the last line when fighting your shadow, because there's a line to remove all options that don't restore HP when facing your shadow -- but presently last_monster() can never equal $monster[your shadow] so that's a future concern. And who would automate combat against your shadow anyway?

    (I would! *cackles wickedly*)
    Sig by JakAtk
    My scripts: One-Click Wossname | Om******* (??) | Psychose-a-Matic | RandBot
    Combat suite: Best Between Battle | Mer******** (?!) | SmartStasis | BatMan | BatMan RE
    For script authors: ASH Wiki | ZLib | BatBrain | CLI Links | CanAdv | Script Registry | Map Manager | About Bats
    If you appreciate my work, help me become BAT KING OF THE WORLD! Thanks to all donators!

  10. #20
    Senior Member Winterbay's Avatar
    Join Date
    Feb 2010
    Posts
    5,033

    Default

    zarqon: I did put in that max(1,dmg) since the script died from a divide by zero-error when I didn't. I'll have to look more into your suggestion when I get back home.
    My scripts:
    Best sushi for Profit
    Winterbay's Helpful Automatic Monsterbasher (WHAM)

    Scripts maintained by me:
    Autobasement
    Smashlib

    A small programmer joke:
    Wife: Honey, please go to the market and buy 1 bottle of milk. If they have eggs, bring 6.
    The man came back with 6 bottles of milk.
    Wife: Why did you buy 6 bottles of milk.
    Man: Because they had eggs...

    The 6 Stages of Debugging: 1 )That can't happen. 2) That shouldn't happen. 3) Hmmm, weird. 4) Why does that happen? 5) Oh, I see. 6 )How did that ever work?

    All programs can be optimized, and all programs have bugs; therefore all programs can be optimized to one line that doesn’t work. /Bob Fitch, Blizzard

Similar Threads

  1. Feature - Implemented random_attributes not being passed to consult scripts
    By DoctorRotelle in forum Bug Reports
    Replies: 7
    Last Post: 05-25-2015, 04:38 AM
  2. Replies: 25
    Last Post: 04-05-2015, 07:20 PM
  3. Feature - Implemented Duplicate scripts cause "not found" error for consult scripts
    By nightslide in forum Bug Reports
    Replies: 6
    Last Post: 06-10-2013, 07:07 PM
  4. Multiple consult scripts?
    By fxer in forum Scripting Discussion
    Replies: 2
    Last Post: 03-04-2013, 07:43 PM
  5. Passing variables to consult scripts from the ccs
    By Captain Kirk in forum Custom Combat Settings
    Replies: 0
    Last Post: 08-17-2008, 05:53 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •