# NeoStasis.ash
# v2
# by Illarion, BDrag0n & Gemelli
# A KoL Stasis script for the post-noodle world.
# formulae courtesy of HCO forums
# Many thanks to Holatuwol and Veracity, without whom this never would have been possible
# Thanks to dirkdiggler for leatherback formula
# Change history
# v2 (28/04/07) Major changes by BDrag0n, mostly enabled by new functions added by Holatuwol
# Armour moved to Medium unsafe stasis list, and high if tetanus would take you below 68 mainstat.
# Aborts added for Amnesia, or no jab sphere running.
# Added elemental defence to expected monster damage
# Will not use up your last anti-anti-antidote during combat.
# Will try to kill immediately if expected damage is too high
# Changed killing logic
# - All spells and TS/LTS are considered at the same time - with exceptions for Procrastination & physical resistance.
# - takes into account elemental damage & weaknesses (note: not for pastamancer spells)
# - does cheapest attack which will kill in 1-shot where possible.
# - When kill logic fails to find a skill to use, abort rather than try and hit
# - will always try to kill as fast as possible where killing is necessary
# v1.7b - (14/04/07) SauceKill rewritten to consider a 2-hit kill if 1-hit isn't possible. Changed behaviour for unsafe monsters which are weak against hot/cold IF you have immaculate seasoning & stream
# v1.7a - Minor tweaks by Gemelli
# v1.7 - (13/04/07) changes by BDrag0n - added new expected damage routine suggested by DarthDud, changed procrastination giant handling
# v1.6 - changes by Gemelli - added check to see if monster is safe to use stasis against, added
# immediate-finish logic for unsafe monsters, tweaked logic of FinishNOW routine, added
# "we have enough MP" logic
# v1.5 - changes by BDrag0n - closer min and max healing levels for salve/cocoon
# v1.4 - better cocoon support, better handling of situations when mob or player cannot hit,
# fixed panic noodling, included Gemelli's workaround for undefined monsters
# v1.3 - fixed entangling noodle bug?, FinishNOW implemented, aware of physical-resistant monsters,
# sanity check when monster can't hit player.
# v1.2- fixed shield/hero test bug, tidied display messages, used antidote
# v1.1 - Location checking for dictionary, pickpocket, fixed mp_cost check
# v1.0 - Forked from ASHStasis v1.4
#*** Begin user-configurable variables ***#
//Change to false if antidote is changed!
boolean USE_ANTIDOTE = true;
//Change to false if goodfella contract is changed!
boolean USE_GOODFELLA = true;
#Default values:
int DAM_THRESHOLD = 20;
// This section is about healing. The safety net is how much HP you want spare - remember to allow for monster variance!
int SAFETY_NET = 3; //Minimum health left after expected monster damage & risk of fumble - suggested 3
int OOC_HEAL_LEVEL = 80; //the max HP level at which changing to out of combat healing would be better
// Threshhold for painful combat effects: set to high (only abort on monsters with really bad
// effects), medium (abort on monsters with moderate-to-bad effects), or low (abort on all
// monsters that could give a bad combat effect)
string EFFECT_THRESHOLD = "medium";
// Set threshhold for MP ... if you are more than MANA_MAX the script will stop stasising
int MANA_MAX = my_maxMP()-10;
// And since the good ol' Bugbear eats MP like it was Pringles ...
if(my_familiar()==$familiar[Pygmy Bugbear Shaman]) MANA_MAX=my_maxMP();
//if your moxie exceeds monster attack by this much, don't bother trying to stasis (as mob can't hit)
int OVERMOXIE_LEVEL = 8;
#print debug messages. These go to the Mafia status bar, and the gCLI. Turn them off if
#you're happy with the performance, and don't care about tweaking/understanding what's going on.
boolean dbug = true;
//Use to show more detailed output
boolean bVerbose = true;
#*** End of user-configurable variables ***#
#Used for status messages
int giRound;
int giCurDelevel;
boolean gbEnemyNoodled;
boolean gbInValley;
stat gDefenceStat;
monster zilch=$monster[];
boolean bUsedNoodles;
string MSG_NOODLEBREAK = "Your opponent struggles free of your entangling noodles.";
int max(int a, int b)
{
int iRetVal;
if (a > b)
{
iRetVal = a;
}
else
{
iRetVal = b;
}
return iRetVal;
}
int min(int a, int b)
{
int iRetVal;
if (a < b)
{
iRetVal = a;
}
else
{
iRetVal = b;
}
return iRetVal;
}
int LeatherBackDR()
{
//DR from Leatherback, as dirkdiggler's formula:
//Leatherback DR = Clamp[ 1 < ceil( (level-3)/2 ) ]
int iResult;
if (have_skill($skill[skin of the leatherback]))
{
iResult = (max(1, ceil( (my_level()-3)/2 )));
}
else
{
iResult = 0;
}
return iResult;
}
void ShowStatusMsg(string Msg)
{
print( "Round: " + giRound + " " +
"(MP Change=" + (my_mp()-string_to_int(get_property("IllStasis_StartMP"))) + ", HP Change=" + (my_hp()-string_to_int(get_property("IllStasis_StartHP"))) + ") --> " + Msg );
}
boolean ShieldEquipped()
{
boolean bFoundShield = false;
string sItem;
sItem = item_to_string(current_equipment($slot[off-hand]));
bFoundShield = bFoundShield || (index_of(sItem, "buckler" )>=0);
bFoundShield = bFoundShield || (index_of(sItem, "shield" )>=0);
bFoundShield = bFoundShield || (index_of(sItem, "hors d'oeuvre tray" )>=0);
bFoundShield = bFoundShield || (index_of(sItem, "box turtle" )>=0);
bFoundShield = bFoundShield || (index_of(sItem, "coffin lid" )>=0);
bFoundShield = bFoundShield || (index_of(sItem, "sewer turtle" )>=0);
if (bVerbose) { Print("Offhand=" + sItem + "-> Shield=" + boolean_to_string(bFoundShield)); }
return bFoundShield;
}
int CheckSkill(skill myskill)
//return 0=success, 1=insufficient mana, 2=do not have skill
{
if (!have_skill(myskill))
{
return 2;
}
else
{
if (my_mp() < mp_cost(myskill) )
{
return 1;
}
}
return 0;
}
// max fumble damage if you're "hitting" with a weapon
int get_fumble()
{
// expected fumble damage for the equipped weapon
int damage = ceil(get_power(current_equipment($slot[weapon]))/10);
if (item_amount($item[goodfella contract])>0 && USE_GOODFELLA && my_familiar()!=$familiar[Penguin Goodfella])
//if you're not hitting with a weapon, you won't fumble
{ damage = 0; }
if (item_amount($item[anti-anti-antidote])>0 && USE_ANTIDOTE)
//if you're not hitting with a weapon, you won't fumble
{ damage = 0; }
if (item_amount($item[dictionary])>0 && !gbInValley)
{ damage = 0; }
if (item_amount($item[facsimile dictionary])>0 && !gbInValley)
{ damage = 0; }
if (have_skill($skill[shake hands]) )
{ damage = 0; }
return damage;
}
string StasisSafe(monster eek) {
if(EFFECT_THRESHOLD=="low")
{
// Trigger on low-impact effects, which generally affect a single stat
if (eek == $monster[7-foot dwarf foreman]) return "finish"; // Grilled
if (eek == $monster[disease-in-the-box]) return "finish"; // The Disease
if (eek == $monster[decent lumberjack]) return "finish"; // axe wound
if (eek == $monster[lumberjack supervisor]) return "finish"; // axe wound
if (eek == $monster[lumberjill]) return "finish"; // axe wound
if (eek == $monster[lumberjuan]) return "finish"; // axe wound
if (eek == $monster[conjoined zmombie]) return "finish"; // half-eaten brain
if (eek == $monster[corpulent zobmie]) return "finish"; // half-eaten brain
if (eek == $monster[grave rober zmobie]) return "finish"; // half-eaten brain
if (eek == $monster[zombie waltzers]) return "finish"; // half-eaten brain
if (eek == $monster[zmobie]) return "finish"; // half-eaten brain
if (eek == $monster[big creepy spider]) return "finish"; // hardly poisoned
if (eek == $monster[completely different spider]) return "finish"; // hardly poisoned
if (eek == $monster[mayonnaise wasp]) return "finish"; // hardly poisoned
if (eek == $monster[mind flayer]) return "finish"; // confused
}
if(EFFECT_THRESHOLD=="medium")
{
// Trigger on medium-impact effects: Moderate poisonings, etc.
if (eek == $monster[acid blob]) return "finish"; // corroded weapon
if (eek == $monster[whitesnake]) return "finish"; // a little bit poisoned
if (eek == $monster[dodecapede]) return "finish"; // a little bit poisoned
if (eek == $monster[spectral jellyfish]) return "finish"; // somewhat poisoned
if (eek == $monster[swarm of killer bees]) return "finish"; // somewhat poisoned
if (eek == $monster[empty suit of armor]) return "finishnow"; // tetanus
}
// Always trigger on high-impact effects - Note cunctatitis is dealt with elsewhere
if (eek == $monster[crusty hippy]) return "finishnow"; // socialismydia
if (eek == $monster[protagonist]) return "finishnow"; // temporary amnesia
if (eek == $monster[quantum mechanic]) return "finishnow"; // teleportitis
if (eek == $monster[empty suit of armor]
&& my_buffedstat(my_primestat())<76) return "finishnow"; // tetanus
// If we got here, no worries! Stasis away, you filthy stasis monkey.
return "safe";
}
int get_spell_bonus(string Spell_class, )
{
int spellbonus=0;
//start with skills
if(Spell_class="sauce")
{
if(have_skill($skill[intrinsic spiciness])) spellbonus=min(my_level(),10);
if(have_skill($skill[immaculate seasoning])) spellbonus=spellbonus+10;
}
// now active effects
if(have_effect($effect[Aspect of the Twinklefairy])>0) spellbonus=spellbonus+5;
if(have_effect($effect[Jackasses' Symphony of Destruction])>0) spellbonus=spellbonus+12;
// Well, that was short. Equipment should have more bonus possibility
if(have_equipped($item[plexiglass pinky ring])) spellbonus=spellbonus+30 ;
if(have_equipped($item[stainless steel scarf])) spellbonus=spellbonus+20 ;
if(have_equipped($item[kickback cookbook])) spellbonus=spellbonus+20 ;
if(have_equipped($item[rib of the bonerdagon])) spellbonus=spellbonus+15 ;
if(have_equipped($item[star spatula])) spellbonus=spellbonus+15 ;
if(have_equipped($item[silver shrimp fork])) spellbonus=spellbonus+14 ;
if(have_equipped($item[oversized pizza cutter])) spellbonus=spellbonus+13 ;
if(have_equipped($item[enchanted toothpick])) spellbonus=spellbonus+12 ;
if(have_equipped($item[chopsticks])) spellbonus=spellbonus+12 ;
if(have_equipped($item[baconstone pendant])) spellbonus=spellbonus+10 ;
if(have_equipped($item[clockwork staff])) spellbonus=spellbonus+10 ;
if(have_equipped($item[huge spoon])) spellbonus=spellbonus+10 ;
if(have_equipped($item[iron pasta spoon])) spellbonus=spellbonus+10 ;
if(have_equipped($item[knob goblin melon baller])) spellbonus=spellbonus+8 ;
if(have_equipped($item[filthy pestle])) spellbonus=spellbonus+7 ;
if(have_equipped($item[hairy staff])) spellbonus=spellbonus+7 ;
if(have_equipped($item[linoleum crossbow])) spellbonus=spellbonus+7 ;
if(have_equipped($item[linoleum sword])) spellbonus=spellbonus+7 ;
if(have_equipped($item[linoleum staff])) spellbonus=spellbonus+7 ;
if(have_equipped($item[projectile icemaker])) spellbonus=spellbonus+7 ;
if(have_equipped($item[shuddersword])) spellbonus=spellbonus+7 ;
if(have_equipped($item[9-ball])) spellbonus=spellbonus+5 ;
if(have_equipped($item[jack flapper])) spellbonus=spellbonus+5 ;
if(have_equipped($item[ring of increase damage])) spellbonus=spellbonus+5 ;
if(have_equipped($item[shiny butcherknife])) spellbonus=spellbonus+5 ;
if(have_equipped($item[knob goblin spatula])) spellbonus=spellbonus+4 ;
if(have_equipped($item[basic meat foon])) spellbonus=spellbonus+3 ;
if(have_equipped($item[bugbear beanie])&& have_equipped($item[bugbear bungguard])) spellbonus=spellbonus+3 ;
if(have_equipped($item[clown wig])) spellbonus=spellbonus+3 ;
if(have_equipped($item[gnollish pie server])) spellbonus=spellbonus+3 ;
if(have_equipped($item[gnollish slotted spoon])) spellbonus=spellbonus+3 ;
if(have_equipped($item[portable corkscrew])) spellbonus=spellbonus+3 ;
if(have_equipped($item[eggbeater])) spellbonus=spellbonus+2 ;
if(have_equipped($item[knob goblin tongs])) spellbonus=spellbonus+2 ;
if(have_equipped($item[corn holder])) spellbonus=spellbonus+1 ;
if(have_equipped($item[little paper umbrella])) spellbonus=spellbonus+1 ;
//I'm going to ignore the concentration potions
return spellbonus;
}
int get_melee_bonus()
{
int add_melee=0;
//start with skills
if(have_skill($skill[claws of the walrus])) add_melee=add_melee+4;
if(have_skill($skill[claws of the otter])) add_melee=add_melee+3;
// now active effects
if(have_effect($effect[Twinkly Weapon])>0) add_melee=add_melee+3;
if(have_effect($effect[Sharp Weapon])>0) add_melee=add_melee+5;
if(have_effect($effect[Pronounced Potency])>0) add_melee=add_melee+5;
if(have_effect($effect[Tenacity of the Snapper])>0) add_melee=add_melee+8;
if(have_effect($effect[Rage of the Reindeer])>0) add_melee=add_melee+10;
if(have_effect($effect[PaPowerful])>0) add_melee=add_melee+10;
if(have_effect($effect[Engorged Weapon])>0) add_melee=add_melee+10;
if(have_effect($effect[Aspect of the Twinklefairy])>0) add_melee=add_melee+5;
if(have_effect($effect[Jackasses' Symphony of Destruction])>0) add_melee=add_melee+12;
if(have_effect($effect[Ponderous Potency])>0) add_melee=add_melee+20;
// and equipment - note that this will not spot duplicate equipment
if(have_equipped($item[flaming talons])) add_melee=add_melee+5 ;
if(have_equipped($item[plexiglass pike pike])) add_melee=add_melee+25 ;
if(have_equipped($item[stainless steel shillelagh])) add_melee=add_melee+20 ;
if(have_equipped($item[batblade])) add_melee=add_melee+15 ;
if(have_equipped($item[mohawk wig])) add_melee=add_melee+10 ;
if(have_equipped($item[pitchfork])) add_melee=add_melee+9 ;
if(have_equipped($item[ridiculously huge sword])) add_melee=add_melee+10 ;
if(have_equipped($item[denim axe])) add_melee=add_melee+5 ;
if(have_equipped($item[hamethyst necklace])) add_melee=add_melee+5 ;
if(have_equipped($item[ring of increase damage])) add_melee=add_melee+5 ;
if(have_equipped($item[9-ball])) add_melee=add_melee+5 ;
if(have_equipped($item[ninja mop])) add_melee=add_melee+4 ;
if(have_equipped($item[sabre teeth])) add_melee=add_melee+4 ;
if(have_equipped($item[knob goblin elite polearm])) add_melee=add_melee+3 ;
return add_melee;
}
int get_elemental(string what_type)
{
int hot_damage=0;
int cold_damage=0;
int spooky_damage=0;
int sleaze_damage=0;
int stench_damage=0;
int elemental=0;
//This will try to get all elemental effects. Since some apply to both, and some only Melee/Spells, it's all one function
//hot first
if(have_effect($effect[heart of orange])>0) hot_damage=hot_damage+5;
if(have_equipped($item[5-ball])) hot_damage=hot_damage+5;
if(have_effect($effect[hot blooded])>0) hot_damage=hot_damage+10;
if(what_type="melee")
{
if(have_effect($effect[flaming weapon])>0) hot_damage=hot_damage+3;
if(have_equipped($item[flaming talons])) hot_damage=hot_damage+5;
if(have_equipped($item[demon whip])) hot_damage=hot_damage+3;
if(have_equipped($item[icy-hot katana])) hot_damage=hot_damage+3;
}
if(what_type="sauce")
{
if(have_equipped($item[demonskin jacket])) hot_damage=hot_damage+5;
if(have_equipped($item[foon of fulmination])) hot_damage=hot_damage+8;
if(have_equipped($item[ram-battering staff])) hot_damage=hot_damage+10;
if(have_equipped($item[Codex of Capsaicin Conjuration])) hot_damage=hot_damage+10 ;
if(have_equipped($item[enchantlers])) hot_damage=hot_damage+10 ;
}
//cold
if(have_effect($effect[cold blooded])>0) cold_damage=cold_damage+10;
if(have_equipped($item[2-ball])) cold_damage=cold_damage+5;
if(what_type="melee")
{
if(have_equipped($item[icy-hot katana])) cold_damage=cold_damage+3;
if(have_equipped($item[projectile icemaker])) cold_damage=cold_damage+5;
if(have_effect($effect[frigid weapon])>0) cold_damage=cold_damage+3;
}
if(what_type="sauce")
{
if(have_equipped($item[foon of frigidity])) cold_damage=cold_damage+8;
if(have_equipped($item[Gazpacho's Glacial Grimoire])) cold_damage=cold_damage+10 ;
}
//spooky
if(have_effect($effect[spooky demeanor])>0) spooky_damage=spooky_damage+10;
if(have_equipped($item[3-ball])) spooky_damage=spooky_damage+5;
if(have_effect($effect[dirge of dreadfulness])>0) spooky_damage=spooky_damage+12;
if(what_type="melee")
{
if(have_effect($effect[spooky weapon])>0) spooky_damage=spooky_damage+3;
if(have_effect($effect[snarl of the timberwolf])>0) spooky_damage=spooky_damage+10;
if(have_equipped($item[clownskin harness])) spooky_damage=spooky_damage+2;
if(have_equipped($item[lupine sword])) spooky_damage=spooky_damage+9;
if(have_equipped($item[spiked femur])) spooky_damage=spooky_damage+6;
if(have_equipped($item[shuddersword])) spooky_damage=spooky_damage+5;
}
if(what_type="sauce")
{
if(have_equipped($item[foon of fearfulness])) spooky_damage=spooky_damage+8;
}
//sleaze
if(have_equipped($item[4-ball])) sleaze_damage=sleaze_damage+5;
if(have_effect($effect[supafly])>0) sleaze_damage=sleaze_damage+10;
if(what_type="melee")
{
if(have_equipped($item[clownskin harness])) sleaze_damage=sleaze_damage+2;
if(have_equipped($item[demon whip])) sleaze_damage=sleaze_damage+3;
if(have_effect($effect[sleazy weapon])>0) sleaze_damage=sleaze_damage+3;
if(have_effect($effect[amorous])>0) sleaze_damage=sleaze_damage+5;
}
if(what_type="sauce")
{
if(have_equipped($item[foon of fleshiness])) sleaze_damage=sleaze_damage+8;
if(have_equipped($item[giant cheesestick])) sleaze_damage=sleaze_damage+11;
}
//stench
if(have_effect($effect[stenchtastic])>0) stench_damage=stench_damage+10;
if(have_equipped($item[6-ball])) stench_damage=stench_damage+5;
if(what_type="melee")
{
if(have_effect($effect[stinky weapon])>0) stench_damage=stench_damage+3;
if(have_equipped($item[demon whip])) stench_damage=stench_damage+3;
}
if(what_type="sauce")
{
if(have_equipped($item[foon of foulness])) stench_damage=stench_damage+8;
if(have_equipped($item[smoldering staff])) stench_damage=stench_damage+11;
}
// calculating elemental bonus for sauce before weaknesses, since that will be dealt with for the whole spell.
if(what_type="sauce" && have_skill($skill[immaculate seasoning])) elemental=max(hot_damage, cold_damage);
if(what_type="sauce" && !have_skill($skill[immaculate seasoning])) elemental=min(hot_damage, cold_damage); //best to assume the worst
//now to consider the weaknesses
if(bVerbose) print("Monster defence is "+element_to_string(monster_defense_element()));
if(monster_defense_element()= $element[hot])
{
stench_damage=stench_damage*2;
sleaze_damage=sleaze_damage*2;
hot_damage=1;
}
if(monster_defense_element()= $element[cold])
{
hot_damage=hot_damage*2;
spooky_damage=spooky_damage*2;
cold_damage=1;
}
if(monster_defense_element()= $element[spooky])
{
stench_damage=stench_damage*2;
hot_damage=hot_damage*2;
spooky_damage=1;
}
if(monster_defense_element()= $element[sleaze])
{
cold_damage=cold_damage*2;
spooky_damage=spooky_damage*2;
sleaze_damage=1;
}
if(monster_defense_element()= $element[stench])
{
cold_damage=cold_damage*2;
sleaze_damage=sleaze_damage*2;
stench_damage=1;
}
if(what_type="melee") elemental = hot_damage+cold_damage+spooky_damage+sleaze_damage+stench_damage;
if(dbug) print("You have "+int_to_string(elemental)+" elemental damage to add for "+what_type );
return elemental;
}
int get_offhand()
{
int offhand_weapon_damage=0;
if(get_power(current_equipment($slot[off-hand]))>0 && !ShieldEquipped())
{
if(bVerbose) print("Weapon in offhand");
offhand_weapon_damage=get_power(current_equipment($slot[off-hand]))/10;
}
return offhand_weapon_damage;
}
skill Choose_skill(int hp_target, boolean hitting_allowed)
{
// LTS/TS formulae are from HCO forums, courtesy of Strangerer
// Spell bonuses - sauce only, no check for cookbook or flavour of magic as these are unlikely!
int spicebonus=get_spell_bonus("sauce");
int pastabonus=get_spell_bonus("pasta");
int spell_element = get_elemental("sauce");
int expectdam=0;
int my_myst=my_buffedstat($stat[mysticality]);
skill To_use=$skill[none];
boolean sauce_resistant=false;
if(monster_defense_element()==$element[cold])
{
if(!have_skill($skill[immaculate seasoning]) && !have_equipped($item[Gazpacho's Glacial Grimoire]))
{
sauce_resistant=true; //risk of doing minimal damage with sauce
if(dbug) print("Risk of doing minimal damage, ignoring sauce spells");
}
}
if(monster_defense_element()==$element[hot])
{
if(!have_skill($skill[immaculate seasoning]) && !have_equipped($item[Codex of Capsaicin Conjuration]))
{
sauce_resistant=true; //risk of doing minimal damage with sauce
if(dbug) print("Risk of doing minimal damage, ignoring sauce spells");
}
}
boolean sauce_weak=false; //check if the spell you're casting hits a weakness - only if guaranteed
if(monster_defense_element()==$element[sleaze] ||monster_defense_element()==$element[stench])
{
if(have_skill($skill[immaculate seasoning]) || have_equipped($item[Gazpacho's Glacial Grimoire]))
{
sauce_weak=true;
if(dbug) print("Monster is weak to your spells!");
}
}
if(monster_defense_element()==$element[cold] ||monster_defense_element()==$element[spooky])
{
if(have_skill($skill[immaculate seasoning]) || have_equipped($item[Codex of Capsaicin Conjuration]))
{
sauce_weak=true;
if(dbug) print("Monster is weak to your spells!");
}
}
int melee_bonus=get_melee_bonus(); //only for physical attacks
int melee_elemental=get_elemental("melee");
int offhand_damage=get_offhand();
record kill_it { skill name; int spelldam; } ;
kill_it [int] damage_dealers;
damage_dealers [1].name = $skill[saucegeyser]; // 40 mp
damage_dealers [1].spelldam = (my_myst*0.35)+35 + spicebonus + spell_element;
damage_dealers [2].name = $skill[weapon of the pastalord]; // 35 mp
damage_dealers [2].spelldam = (my_myst*.35)+32 + pastabonus;
damage_dealers [3].name = $skill[wave of sauce]; // 23 mp
damage_dealers [3].spelldam = min((my_myst*0.3)+20,50) + spicebonus + spell_element;
damage_dealers [4].name = $skill[cone of whatever]; // 19 mp
damage_dealers [4].spelldam = min((my_myst*.25)+16,46) + pastabonus;
damage_dealers [5].name = $skill[saucestorm]; // 12 mp
damage_dealers [5].spelldam = min((my_myst/5)+14,39) + spicebonus + spell_element;
if(hitting_allowed && current_hit_stat() == $stat[muscle])
{
damage_dealers [6].name = $skill[lunging thrust-smack]; // 8 mp
damage_dealers [6].spelldam = (((get_power(current_equipment($slot[weapon]))/10)+melee_bonus)*3) + melee_elemental + min(0,(my_buffedstat($stat[muscle])-monster_defense()))+offhand_damage;
}
damage_dealers [7].name = $skill[extreme ray of something]; // 7 mp
damage_dealers [7].spelldam = min((my_myst*.15)+8,28) + pastabonus;
damage_dealers [8].name = $skill[minor ray of something]; // 4 mp
damage_dealers [8].spelldam = min((my_myst*.07)+3,18) + pastabonus;
damage_dealers [9].name = $skill[stream of sauce]; // 3 mp
damage_dealers [9].spelldam = min((my_myst/10)+3,18) + spicebonus + spell_element;
if(hitting_allowed && current_hit_stat() == $stat[muscle])
{
damage_dealers [10].name = $skill[thrust-smack]; // 3 mp
damage_dealers [10].spelldam = (((get_power(current_equipment($slot[weapon]))/10)+melee_bonus)*2)+ melee_elemental + min(0,(my_buffedstat($stat[muscle])-monster_defense()))+offhand_damage;
}
//allowance for elemental spells here - Sauce only
if(sauce_resistant)
{
damage_dealers [1].spelldam = 1; //Saucegeyser
damage_dealers [3].spelldam = 1; //Wave
damage_dealers [5].spelldam = 1; //Storm
damage_dealers [9].spelldam = 1; //Stream
}
if(sauce_weak)
{
damage_dealers [1].spelldam = 2*((my_myst*0.35)+35 + spicebonus + spell_element); //Saucegeyser
damage_dealers [3].spelldam = 2*(min((my_myst*0.3)+20,50) + spicebonus + spell_element); //Wave
damage_dealers [5].spelldam = 2*(min((my_myst/5)+14,39) + spicebonus + spell_element); //Storm
damage_dealers [9].spelldam = 2*(min((my_myst/10)+3,18) + spicebonus + spell_element); //Stream
}
skill possible;
int possible_dam;
foreach key in damage_dealers
{
possible = damage_dealers[key].name;
possible_dam = damage_dealers[key].spelldam;
// Print("Casting "+skill_to_string(damage_dealers[key].name)+" should do "+ int_to_string(damage_dealers[key].spelldam));
if(checkSkill(possible)==0)
{
if(possible_dam >= hp_target)
{
To_use=possible;
expectdam = possible_dam;
if(bVerbose) print(skill_to_string(To_use)+" should do "+int_to_string(expectdam)+" damage.");
}
}
}
return To_use;
}
boolean CheckPhysicalResistance(monster eek)
{
if (eek == $monster[chalkdust wraith])
return true;
if (eek == $monster[Ghost Miner])
return true;
if (eek == $monster[Snow Queen])
return true;
return false;
}
void Kill(monster eek) {
// Guess at monster remaining HP, see which spell we have that can do as close
// to a one-hit kill as possible
int hp_target=monster_hp();
if(dbug) print("Kill: need to do " + hp_target + " points of damage in one turn.");
boolean LTS_safe = true;
// eek==$monster[Apathetic Lizardman] || to be added back
if(eek==$monster[Procrastination Giant] || eek==$monster[acid blob] || CheckPhysicalResistance(eek) || gbEnemyNoodled)
{
LTS_safe = false;
if(dbug) Print("Don't hit it!");
}
skill whichSkill=$skill[none];
Whichskill = Choose_skill(hp_target, LTS_safe);
//If a 1-hit isn't possible, it's worth casting noodles - but only if we've at least 3 rounds to play with
if(WhichSkill==$skill[none] && CheckSkill($skill[entangling noodles])==0 && bUsedNoodles==false && giRound<27)
{
if(dbug) Print("No 1-Hit Kill. Noodling");
use_skill($skill[entangling noodles]);
set_property("IllNeoStasis_UsedNoodles", "true");
set_property("IllNeoStasis_EnemyNoodled", "true");
return;
}
if(WhichSkill=$skill[none]) //no 1-hit kill, check for 2-hit
{
hp_target=hp_target/2;
Whichskill = Choose_skill(hp_target, LTS_safe);
}
//We should have a skill now, for a 1 or 2-hit kill
if(WhichSkill !=$skill[none])
{
if(dbug) print("Casting "+skill_to_string(WhichSkill));
use_skill(WhichSkill);
}
else
{
if(CheckSkill($skill[stream of sauce])==0 && giRound<=27) //allowing time to kill, hopefully!
{
if(dbug) print("Casting stream of sauce ... which is better than nothing.");
use_skill($skill[stream of sauce]);
}
else
{
// Hmm. Got CLEESH?
if(CheckSkill($skill[cleesh])==0)
{
whichSkill=$skill[cleesh];
}
else
{
cli_execute("Abort Kill it now!");
}
}
}
}
int ExpectedMonsterDamage(monster eek)
//BaseMonsterDmg = (20% to 25%)*Atk + (Atk-Mox)
//Dam = (Base - DR) * DA * ER
{
int iDam;
int iAtk;
int iMoxPenalty;
int iDR;
iAtk = monster_attack();
iMoxPenalty = max(iAtk - my_buffedstat(gDefenceStat),0);
iDam = 0.25*iAtk + iMoxPenalty;
iDam = iDam - damage_reduction()-LeatherbackDR();
iDam = iDam - (iDam * damage_absorption_percent()/100);
iDam = iDam- (iDam * elemental_resistance(monster_attack_element())/100) ;
if(bVerbose) print("You have "+int_to_string(elemental_resistance(monster_attack_element()))+"% elemental resistance");
// if (bVerbose) { Print("Expected: (25% of " + iAtk + "+" + iMoxPenalty + "-(" + damage_reduction() + "+" + LeatherBackDR() + ")DR) * " + damage_absorption_percent() + "%DA = " + iDam); }
return iDam;
}
boolean MonsterCannotHit(monster eek)
//Test if mob can hit us
{
return ((monster_attack() + OVERMOXIE_LEVEL) <= my_buffedstat($stat[moxie]) );
}
boolean PlayerCannotHit(monster eek)
//Test if we can hit the mob
{
return (my_buffedstat(current_hit_stat()) < (monster_defense()+ 7)); //TODO check the 7
}
void PickPocket()
{
print("Picking pocket...");
visit_url("fight.php?action=steal");
}
boolean ThrowJunkItem()
{
item JunkItem;
JunkItem = $item[scroll of turtle summoning];
if (bVerbose) { Print("Trying to throw junk..."); }
if (item_amount(JunkItem)>0)
{
throw_item(JunkItem);
return true;
}
JunkItem = $item[seal tooth];
if (item_amount(JunkItem)>0)
{
throw_item(JunkItem);
return true;
}
JunkItem = $item[spices];
if (item_amount(JunkItem)>0)
{
throw_item(JunkItem);
return true;
}
if (bVerbose) { Print("Failed to throw junk."); }
return false;
}
void FinishHim(monster eek)
{
if (dbug) { print("Finish Him!"); }
if (gbInValley)
//Best to use a dictionary if we can - free
{
if (item_amount($item[dictionary])>0)
{
if (bVerbose) { Print("Finish with dictionary"); }
throw_item($item[dictionary]);
}
else
{
if (item_amount($item[facsimile dictionary])>0)
{
if (bVerbose) { Print("Finish with dictionary"); }
throw_item($item[facsimile dictionary]);
}
}
}
else
{
Kill(eek);
}
}
void DontHurtHim(monster eek)
{
if (bVerbose) { Print("Attack and miss"); }
if (item_amount($item[anti-anti-antidote])>0 && USE_ANTIDOTE)
{
throw_item($item[anti-anti-antidote]);
}
else
{
if (item_amount($item[goodfella contract])>0 && USE_GOODFELLA && my_familiar()!=$familiar[Penguin Goodfella])
{
throw_item($item[goodfella contract]);
}
else
{
if (item_amount($item[dictionary])>0 && !gbInValley)
{
throw_item($item[dictionary]);
}
else
{
if (item_amount($item[facsimile dictionary])>0 && !gbInValley)
{
throw_item($item[facsimile dictionary]);
}
else
{
if (have_skill($skill[shake hands]) )
{
use_skill($skill[shake hands]);
}
else
{
if (buffed_hit_stat() - monster_defense() < -5)
{
#attack and miss
attack();
}
else
//nothing we can do except throw junk, or attack and hit
{
if( eek =$monster[procrastination giant] )
{ kill(eek); }
else {
if (!ThrowJunkItem())
{ attack(); }
}
}
}
}
}
}
}
}
void main(int iRound, monster eek, string sText)
{
// Check this script is worth running!
if(have_effect($effect[temporary amnesia])>0)
{ cli_execute("abort You've forgotten how to do this!"); }
if(have_effect($effect[Jabañero Saucesphere])==0)
{ cli_execute("abort Oops! You forgot the sauce."); }
//Check if we're poisoned, and don't use our last anti-anti-antidote if we are
if(have_effect($effect[hardly poisoned at all])> 0 || have_effect($effect[somewhat poisoned])> 0 || have_effect($effect[a little bit poisoned])> 0)
{
if(item_amount($item[anti-anti-antidote])<=1)
{
USE_ANTIDOTE=FALSE;
}
}
int iDamTaken=0;
string sTemp;
string sName;
int iStart=0;
int iEnd=0;
string sAction;
// Define correct defense stat
if (ShieldEquipped() && have_skill($skill[hero of the half-shell]) &&
( my_buffedstat($stat[muscle]) > my_buffedstat($stat[moxie]) ) )
{
gdefenceStat = $stat[muscle];
set_property("IllNeoStasis_Hero", "true");
// if (dbug) { print("Hero!"); }
}
else
{
gdefenceStat = $stat[moxie];
set_property("IllNeoStasis_Hero", "false");
// if (dbug) { print("Zero :("); }
}
//Sets appropriate health levels
// Decide the expected monster damage - first 4 rounds based on calculation, 5th and on based on damage taken this fight
// Based on DarthDud's suggestions, added by BDrag0n
int ExpectedDamage=ExpectedMonsterDamage(eek);
if(iRound >= 5)
{
ExpectedDamage = string_to_int(get_property("IllNeoStasis_MaxDamTaken"));
if(dbug) { Print ("Expected damage based on this fight is: "+int_to_string(ExpectedDamage)); }
}
int MIN_HEAL_THRESHOLD = ExpectedDamage+get_fumble() + SAFETY_NET; //lowest level to heal at
int HEAL_THRESHOLD;
if(my_maxhp()<OOC_HEAL_LEVEL) {
HEAL_THRESHOLD = my_maxhp()-15;
if(have_effect($effect[purple tongue]) > 0) // allow for purple tongue healing
{ HEAL_THRESHOLD = HEAL_THRESHOLD-20; }
if(have_effect($effect[Heart of Orange]) > 0) // Allow for orange heart healing
{ HEAL_THRESHOLD = HEAL_THRESHOLD-6; }
if(HEAL_THRESHOLD < MIN_HEAL_THRESHOLD) // don't want to drop below the minimum health!
{ HEAL_THRESHOLD = MIN_HEAL_THRESHOLD; }
} else {
HEAL_THRESHOLD = MIN_HEAL_THRESHOLD; // So if your max health is above the OOC_HEAL_THRESHOLD you want to allow minimal health at the end of battle
}
// if(dbug) print("Your heal threshhold is " + HEAL_THRESHOLD);
// Start the round!
giRound = iRound;
print ("++++++++++++++++++++++++++++++++");
print("Round " + iRound + " vs " + eek);
#print(sText);
print ("++++++++++++++++++++++++++++++++");
gbInValley = (my_location() == $location[valley beyond orc chasm]);
if (dbug) { print("Valley=" + boolean_to_string(gbInValley)); }
int MaxDamTaken;
if (iRound == 1)
{
giCurDelevel = 0;
set_property("IllStasis_Delevel", "0");
set_property("IllStasis_StartMP", my_mp());
set_property("IllStasis_StartHP", my_hp());
bUsedNoodles = false;
set_property("IllNeoStasis_UsedNoodles", "false");
gbEnemyNoodled = false;
set_property("IllNeoStasis_EnemyNoodled", "false");
set_property("IllNeoStasis_MaxDamTaken", "0");
}
else
{
giCurDelevel = string_to_int(get_property("IllStasis_Delevel"));
//if (dbug) { print("giCurDelevel=" + giCurDelevel); }
bUsedNoodles = string_to_boolean(get_property("IllNeoStasis_UsedNoodles"));
gbEnemyNoodled = string_to_boolean(get_property("IllNeoStasis_EnemyNoodled"));
MaxDamTaken=string_to_int(get_property("IllNeoStasis_MaxDamTaken"));
}
// Check damage taken
iStart = index_of(sText, "You lose " );
if (iStart > 0)
{
iEnd = index_of(sText, " hit point", iStart );
}
// if (dbug) { print("iStart = " + iStart + "iEnd = " + iEnd); }
if (iStart > 0 && iEnd > 0)
{
sTemp = substring(sText,iStart+9,iEnd );
iDamTaken = string_to_int(sTemp);
if (dbug) { print("Took Dam: " + iDamTaken); }
if(iDamTaken > MaxDamTaken) { set_property("IllNeoStasis_MaxDamTaken", int_to_string(iDamTaken)); }
}
// Check Noodles status
iStart = 0;
iStart = index_of(sText, MSG_NOODLEBREAK);
if (iStart > 0)
{
gbEnemyNoodled = false;
set_property("IllNeoStasis_EnemyNoodled", "false");
}
// Report on current HP and MP threshholds
// removed percentages because I prefer absolute numbers - BD
//int iHPPct;
//iHPPct = 100*my_hp()/my_maxhp();
//int iMPPct = 100*my_mp()/my_maxmp();
//if (dbug) { print("HP = " + iHPPct + "% (HP=" + my_hp() + "/" + my_maxhp() + ")"); }
//if (dbug) { print("MP = " + iMPPct + "% (MP=" + my_mp() + "/" + my_maxmp() + ")"); }
if (dbug) { print("HP=" + my_hp() + "/" + my_maxhp()); }
if (dbug) { print("MP=" + my_mp() + "/" + my_maxmp()); }
//Decide on our action, in reverse priority order
sAction = "Miss"; //Default
if (MonsterCannotHit(eek))
{
if (dbug) { print("Monster cannot hit..."); }
if (PlayerCannotHit(eek))
{
if (dbug) { print("We cannot hit either...finish"); }
sAction = "Finish";
}
else
{
sAction = "Attack";
}
}
// Are we full on MP? If so, we don't need to draw this out.
if (my_MP() >= MANA_MAX)
{
//
if (dbug) { print("We're full on MP!"); }
if (my_hp()< my_maxhp()-15 && CheckSkill($skill[saucy salve]) == 0)
{
// If we are below max HP, might as well burn some MP on healing
sAction = "Salve";
}
else
{
sAction = "Finish";
}
}
if (my_hp() < HEAL_THRESHOLD)
{
//We're hurting, heal if no higher priority action
if (CheckSkill($skill[saucy salve]) == 0)
{
sAction = "Salve";
}
}
if (giRound == 1 && my_primestat()==$stat[moxie] && index_of(sText, "You get the jump") >= 0)
{
sAction = "Pickpocket";
}
if (iDamTaken >= DAM_THRESHOLD ||string_to_int(get_property("IllNeoStasis_MaxDamTaken"))>= DAM_THRESHOLD || ExpectedMonsterDamage(eek)>=DAM_THRESHOLD)
//Too painful! End fight quickly
{
sAction = "Finish";
}
// Check to see if the monster is safe
string safetest=StasisSafe(eek);
if(safetest!="safe") {
if (dbug) { print("Monster is not safe! Result=" + safetest); }
if(safetest=="finish") {
sAction="Finish";
} else {
if(safetest=="finishNOW")
{
if(gbEnemyNoodled)
{
sAction="Finish";
}
else
{
if(checkSkill($skill[entangling noodles])==0 && !bUsedNoodles)
{
sAction="Noodle";
}
else
{
sAction="Finish";
}
}
}
}
}
if (ExpectedDamage > (my_hp() + SAFETY_NET))
//danger of death - panic
{
if(my_maxhp()-my_hp()<=10) {
sAction = "Salve";
} else {
if (dbug) { print("PANIC! : Noodled=" + gbEnemyNoodled + ", UsedNoodles=" + bUsedNoodles); }
if (gbEnemyNoodled)
{
if (my_hp()+10>HEAL_THRESHOLD)
{
//heal back to safety level
if (CheckSkill($skill[saucy salve]) == 0)
{
sAction = "Salve";
}
}
else
{
sAction = "Finish";
}
}
else
{
if (CheckSkill($skill[entangling noodles])==0 && !bUsedNoodles)
{
sAction = "Noodle";
}
else
{
sAction = "Finish";
}
}
}
}
if (iRound >= 29)
{
#long enough!
sAction = "Finish";
}
ShowStatusMsg("Action = " + sAction);
//And finally, perform our action
if (sAction == "Attack") attack();
if (sAction == "Finish") FinishHim(eek);
if (sAction == "Salve") use_skill($skill[saucy salve]);
if (sAction == "Cleesh") {
if(CheckSkill($skill[cleesh]) == 0) use_skill($skill[cleesh]);
else sAction="Finish";
}
if (sAction == "Miss") DontHurtHim(eek);
if (sAction == "Pickpocket") Pickpocket();
if (sAction == "Noodle")
{
use_skill($skill[entangling noodles]);
set_property("IllNeoStasis_UsedNoodles", "true");
set_property("IllNeoStasis_EnemyNoodled", "true");
}
}