Illerai:Sandbox/combat pseudocode
Jump to navigation
Jump to search
/**
unimplemented:
prayers
amulet of avarice
warden p2
nmz
Castle wars bracelet
melee:
verac's
bulwark (pummel)
ranged:
Slayer helmet (i) and Black mask (i) for max hit
karil's
ice arrows
chinchompas
bolts/zcb
venator bow
strangeness from old specs/ogre bow
npcs:
maiden
guardians
verzik
kraken (ranged)
magic:
ahrim's
thammaron's sceptre
spell max hits
special attacks
league relics?
*/
// Please note that all divisions in this code are integer divisions that
// truncate towards zero. Python's // operator does the wrong thing for
// negative numbers.
randominc(n):
return int(random.random() * (n+1))
npc_defence_roll:
effective_defence_level = monster.getBoostedLevel(DEFENCE)
effective_defence_level += 9
defence_roll = effective_defence_level * (monster.getDefensiveBonus(style.type) + 64)
if monster.invocation_level is not None:
defence_roll = defence_roll * (250 + monster.invocation_level) / 250
return defence_roll
melee_player_attack_roll:
style = player.getCombatStyle()
effective_attack_level = int(player.getBoostedLevel(ATTACK) * player.getPrayerBoost(ATTACK))
if style.stance == "Accurate":
effective_attack_level += 3
elif style.stance == "Controlled":
effective_attack_level += 1
effective_attack_level += 8
if player.wearingFullVoidMelee():
effective_attack_level = effective_attack_level * 11/10
attack_roll = effective_attack_level * (player.getBonus(style.type) + 64)
if player.wearing(["Salve amulet (e)", "Salve amulet(ei)"]) and monster.hasAttribute("undead"):
attack_roll = attack_roll * 6/5
elif player.wearing(["Salve amulet", "Salve amulet(i)"]) and monster.hasAttribute("undead"):
attack_roll = attack_roll * 7/6
elif player.wearingBlackMask() and isSlayerTask:
attack_roll = attack_roll * 7/6
if player.wearing(["Viggora's chainmace", "Ursine chainmace"]) and isInWilderness:
attack_roll = attack_roll * 3/2
if player.wearing(["Arclight"]) and monster.hasAttribute("demonic"):
attack_roll = attack_roll * 17/10
if player.wearing(["Dragon hunter lance"]) and monster.hasAttribute("draconic"):
attack_roll = attack_roll * 6/5
if player.wearing(["Keris partisan of breaching"]) and monster.hasAttribute("kalphite"):
attack_roll = attack_roll * 133/100
if player.wearing(["Blisterwood flail", "Blisterwood sickle"]) and monster.hasAttribute("vampyre"): // TODO: make sure this actually works
attack_roll = attack_roll * 21/20
if player.wearing(["Tzhaar-ket-em", "Tzhaar-ket-om", "Tzhaar-ket-om (t)", "Toktz-xil-ak", "Toktz-xil-ek"]) and player.wearing("Obsidian platebody") and player.wearing("Obsidian platelegs") and player.wearing("Obsidian helmet"):
attack_roll = attack_roll * 11/10
if style.type == CRUSH:
inq_pieces = player.countWorn(["Inquisitor's great helm", "Inquisitor's hauberk", "Inquisitor's plateskirt"])
if inq_pieces == 3:
inq_pieces = 5
attack_roll = attack_roll * (200 + inq_pieces) / 200
return attack_roll
melee_max_hit:
style = player.getCombatStyle()
effective_strength_level = int(player.getBoostedLevel(STRENGTH) * player.getPrayerBoost(STRENGTH))
if style.stance == "Aggressive":
effective_strength_level += 3
elif style.stance == "Controlled":
effective_strength_level += 1
effective_strength_level += 8
if player.wearingFullVoidMelee():
effective_strength_level = effective_strength_level * 11/10
max_hit = (effective_strength_level * (player.getBonus(STRENGTH_BONUS) + 64) + 320) / 640
base_damage = max_hit
if player.wearing(["Salve amulet (e)", "Salve amulet(ei)"]) and monster.hasAttribute("undead"):
max_hit = max_hit * 6/5
elif player.wearing(["Salve amulet", "Salve amulet(i)"]) and monster.hasAttribute("undead"):
max_hit = max_hit * 7/6
elif player.wearingBlackMask() and isSlayerTask:
max_hit = max_hit * 7/6
if player.wearing(["Arclight"]) and monster.hasAttribute("demonic"):
max_hit = max_hit * 17/10
if player.wearing(["Tzhaar-ket-em", "Tzhaar-ket-om", "Tzhaar-ket-om (t)", "Toktz-xil-ak", "Toktz-xil-ek"]) and player.wearing("Obsidian platebody") and player.wearing("Obsidian platelegs") and player.wearing("Obsidian helmet"):
max_hit += base_damage / 10 // TODO: confirm that this is the appropriate place
if player.wearing(["Tzhaar-ket-em", "Tzhaar-ket-om", "Tzhaar-ket-om (t)", "Toktz-xil-ak", "Toktz-xil-ek"]) and player.wearing("Berserker necklace"):
max_hit = max_hit * 6/5
if player.wearing(["Dragon hunter lance"]) and monster.hasAttribute("draconic"):
max_hit = max_hit * 6/5
if player.wearing(["Barronite mace"]) and monster.hasAttribute("golem"):
max_hit = max_hit * 23/20
if player.wearing(["Viggora's chainmace", "Ursine chainmace"]) and isInWilderness:
max_hit = max_hit * 3/2
if player.wearing(["Silverlight", "Darklight", "Silverlight (dyed)"]) and monster.hasAttribute("demonic"):
max_hit = max_hit * 8/5 // There is no accuracy boost
if player.wearing(["Blisterwood flail"]) and monster.hasAttribute("vampyre"):
max_hit = max_hit * 5/4
if player.wearing(["Blisterwood sickle"]) and monster.hasAttribute("vampyre"):
max_hit = max_hit * 23/20
if player.wearing(["Ivandis flail"]) and monster.hasAttribute("vampyre"):
max_hit = max_hit * 6/5
if player.wearing(["Leaf-bladed battleaxe"]) and monster.hasAttribute("leafy"):
max_hit = max_hit * 47/40
if player.wearing(["Colossal blade"]):
max_hit = max_hit + min(monster.size * 2, 10)
if style.type == CRUSH:
inq_pieces = player.countWorn(["Inquisitor's great helm", "Inquisitor's hauberk", "Inquisitor's plateskirt"])
if inq_pieces == 3:
inq_pieces = 5
max_hit = max_hit * (200 + inq_pieces) / 200
// TODO: many more...
return max_hit
ranged_player_attack_roll:
style = player.getCombatStyle()
effective_ranged_level = int(player.getBoostedLevel(RANGED) * player.getPrayerBoost(RANGED))
if style.stance == "Accurate":
effective_ranged_level += 3
effective_ranged_level += 8
if player.wearingFullVoidRanged():
effective_ranged_level = effective_ranged_level * 11/10
attack_roll = effective_ranged_level * (player.getBonus(RANGED) + 64)
if player.wearing(["Salve amulet(ei)"]) and monster.hasAttribute("undead"):
attack_roll = attack_roll * 6/5
elif player.wearing(["Salve amulet(i)"]) and monster.hasAttribute("undead"):
attack_roll = attack_roll * 7/6
elif player.wearingImbuedBlackMask() and isSlayerTask:
attack_roll = attack_roll * 23/20
if player.wearing(["Twisted bow"]):
cap = 250
if monster.hasAttribute("raids"):
cap = 350
tbow_magic = max(monster.getBaseLevel(MAGIC), monster.getBonus(MAGIC_BONUS))
m = min(tbow_magic, cap) * 3/10
tbow_mod = min(140, 140 + (m*10-10)/100 - (m-100)^2/100)
attack_roll = attack_roll * tbow_mod / 100
if player.wearing(["Craw's bow"]) and isInWilderness:
attack_roll = attack_roll * 3/2
if player.wearing(["Dragon hunter crossbow"]):
// TODO: https://twitter.com/JagexAsh/status/1647928422843273220 for max_hit seems to be additive now
attack_roll = attack_roll * 13/10
if player.wearingAnyCrystalBow():
// TODO: crystal buff actually applies before slayer helm. need to test salve.
crystal_pieces = (player.isWearing("Crystal helm") ? 1 : 0) + (player.isWearing("Crystal legs") ? 2 : 0) + (player.isWearing("Crystal body") ? 3 : 0)
attack_roll = attack_roll * (20 + crystal_pieces) / 20
return attack_roll
ranged_max_hit:
style = player.getCombatStyle()
effective_ranged_level = int(player.getBoostedLevel(RANGED) * player.getPrayerBoost(RANGED))
if style.stance == "Accurate":
effective_ranged_level += 3
effective_ranged_level += 8
if player.wearingFullEliteVoidRanged():
effective_ranged_level = effective_ranged_level * 9/8
elif player.wearingFullVoidRanged():
effective_ranged_level = effective_ranged_level * 11/10
max_hit = (effective_ranged_level * (player.getBonus(RANGED_STRENGTH) + 64) + 320) / 640
if player.wearing(["Twisted bow"]):
cap = 250
if monster.hasAttribute("raids"):
cap = 350
tbow_magic = max(monster.getBaseLevel(MAGIC), monster.getBonus(MAGIC_BONUS))
m = min(tbow_magic, cap) * 3/10
tbow_mod = min(250, 250 + (m*10-14)/100 - (m-140)^2/100) // the min() is redundant :-)
max_hit = max_hit * tbow_mod / 100
if player.wearing(["Craw's bow"]):
max_hit = max_hit * 3/2
if player.wearing(["Dragon hunter crossbow"]):
// TODO: https://twitter.com/JagexAsh/status/1647928422843273220 for max_hit seems to be additive now
// Is it 25% or 30%? Wiki says 25%
max_hit = max_hit * 5 / 4
if player.wearingAnyCrystalBow():
crystal_pieces = (player.isWearing("Crystal helm") ? 1 : 0) + (player.isWearing("Crystal legs") ? 2 : 0) + (player.isWearing("Crystal body") ? 3 : 0)
max_hit = max_hit * (40 + crystal_pieces) / 40
return max_hit
// For a few things that don't respect prayers, stances, etc
old_ranged_max_hit(slot):
effective_ranged_level = player.getBoostedLevel(RANGED)
max_hit = (effective_ranged_level * (player.getBonusAtSlot(slot, RANGED_STRENGTH) + 64) + 320) / 640
return max_hit
magic_player_attack_roll:
style = player.getCombatStyle()
effective_magic_level = int(player.getBoostedLevel(MAGIC) * player.getPrayerBoost(MAGIC))
if style.stance == "Accurate":
effective_magic_level += 2
effective_magic_level += 9
if player.wearingFullVoidMagic():
effective_magic_level = effective_magic_level * 29/20
magic_bonus = player.getBonus(MAGIC)
if player.wearing(["Tumeken's shadow"]):
if monster.hasAttribute("toa"):
magic_bonus = magic_bonus * 4
else:
magic_bonus = magic_bonus * 3
attack_roll = effective_magic_level * (magic_bonus + 64)
if player.wearing(["Salve amulet(ei)"]) and monster.hasAttribute("undead"):
attack_roll = attack_roll * 6/5
elif player.wearing(["Salve amulet(i)"]) and monster.hasAttribute("undead"):
attack_roll = attack_roll * 23/20
elif player.wearingImbuedBlackMask() and isSlayerTask:
attack_roll = attack_roll * 23/20
if player.wearing(["Thammaron's sceptre", "Accursed sceptre"]) and isInWilderness:
attack_roll = attack_roll * 3/2
if player.wearing(["Mystic smoke staff"]) and player.spell().spellbook == "Standard":
attack_roll = attack_roll * 11/10
return attack_roll
magic_max_hit:
max_hit = None
magic_level = player.getBoostedLevel(MAGIC)
if player.spell().max_hit:
max_hit = player.spell().max_hit
elif player.spell().name == "Magic Dart":
if player.wearing(["Slayer's staff (e)"]) and isSlayerTask:
max_hit = 13 + magic_level / 6
else:
max_hit = 10 + magic_level / 10
elif player.wearing(["Starter staff"]):
max_hit = 8
elif player.wearing(["Trident of the seas", "Trident of the seas (e)"]):
max_hit = magic_level / 3 - 5
elif player.wearing(["Thammaron's sceptre"]):
max_hit = magic_level / 3 - 8
elif player.wearing(["Accursed sceptre"]):
max_hit = magic_level / 3 - 6
elif player.wearing(["Trident of the swamp", "Trident of the swamp (e)"]):
max_hit = magic_level / 3 - 2
elif player.wearing(["Sanguinesti staff", "Holy sanguinesti staff"]):
max_hit = magic_level / 3 - 1
elif player.wearing(["Dawnbringer"]):
max_hit = magic_level / 6 - 1
elif player.wearing(["Tumeken's shadow"]):
max_hit = magic_level / 3 + 1
elif player.wearing(["Warped sceptre"]):
max_hit = (8 * magic_level + 96) / 37
elif player.wearing(["Crystal staff (basic)", "Corrupted staff (basic)"]):
max_hit = 23
elif player.wearing(["Crystal staff (attuned)", "Corrupted staff (attuned)"]):
max_hit = 31
elif player.wearing(["Crystal staff (perfected)", "Corrupted staff (perfected)"]):
max_hit = 39
elif player.wearing(["Swamp lizard"]):
max_hit = (magic_level * (56 + 64) + 320) / 640
elif player.wearing(["Orange salamander"]):
max_hit = (magic_level * (59 + 64) + 320) / 640
elif player.wearing(["Red salamander"]):
max_hit = (magic_level * (77 + 64) + 320) / 640
elif player.wearing(["Black salamander"]):
max_hit = (magic_level * (92 + 64) + 320) / 640
if player.wearing(["Chaos gauntlets"]) and player.spell().is_bolt:
max_hit = max_hit + 3
if charge and player.spell().is_god_spell:
max_hit = max_hit + 10
magic_damage_bonus = player.getBonus(MAGIC_DAMAGE) * 10
if player.wearing(["Tumeken's shadow"]):
// Supposedly this caps at 100, but nothing goes that high yet
if monster.hasAttribute("toa"):
magic_damage_bonus = magic_damage_bonus * 4
else:
magic_damage_bonus = magic_damage_bonus * 3
if player.wearingFullEliteVoidMagic():
// This comes after shadow's tripling
magic_damage_bonus = magic_damage_bonus + 25
if player.wearing(["Mystic smoke staff"]) and player.spell().spellbook == "Standard":
magic_damage_bonus = magic_damage_bonus + 100
blackMaskBonus = false
if player.wearing(["Salve amulet(ei)"]) and monster.hasAttribute("undead"):
magic_damage_bonus = magic_damage_bonus + 200
elif player.wearing(["Salve amulet(i)"]) and monster.hasAttribute("undead"):
magic_damage_bonus = magic_damage_bonus + 150
elif player.wearingImbuedBlackMask() and isSlayerTask:
blackMaskBonus = true
max_hit = max_hit * (1000 + magic_damage_bonus) / 1000
if blackMaskBonus:
max_hit = max_hit * 23/20
// accursed sceptre passive effect comes after black mask
return max_hit
style = player.getCombatStyle()
if style == MELEE:
max_attack_roll = melee_player_attack_roll()
max_hit = max(0, melee_max_hit())
elif style == RANGED:
max_attack_roll = ranged_player_attack_roll()
max_hit = max(0, ranged_max_hit())
elif style == MAGIC:
max_attack_roll = magic_player_attack_roll()
max_hit = max(0, magic_max_hit())
// TODO: Get the right defence roll depending on melee/ranged vs magic and monsters that use defence for magic (ice demon, verzik, etc)
max_defence_roll = npc_defence_roll()
if player.wearing(["Brimstone ring"]) and style == MAGIC:
if random(4) == 0:
max_defence_roll = max_defence_roll * 9/10
if player.wearing(["Scythe of vitur"]):
num_of_hits = min(monster.size, 3)
for _ in range(num_of_hits):
if randominc(max_attack_roll) > randominc(max_defence_roll):
hit_opponent(randominc(max_hit))
max_hit /= 2
else:
attack_roll = randominc(max_attack_roll)
defence_roll = randominc(max_defence_roll)
if attack_roll <= defence_roll and player.wearing(["Osmumten's fang"]):
attack_roll = randominc(max_attack_roll)
if monster.hasAttribute("toa"):
defence_roll = randominc(max_defence_roll)
if attack_roll > defence_roll:
if player.wearing(["Osmumten's fang"]):
fifteen = max_hit * 15/100
hit = fifteen + randominc(max_hit - fifteen*2)
else:
hit = randominc(max_hit)
if player.wearing(["Gadderhammer"]) and monster.hasAttribute("shade"):
if random(20) == 0:
hit = hit * 2
else:
hit = hit * 5/4
if player.wearingAnyKeris() and monster.hasAttribute("kalphite"):
if random(51) == 0:
hit = hit * 3
if player.wearing(["Holy water"]) and monster.hasAttribute("demonic"):
hit = hit * 8 / 5
// if monster defence level isn't drained, drain it by level/20
if player.wearingFullDharok() and style == MELEE:
hit = hit * (10000 + (player.base_hp - player.current_hp) * player.current_hp) / 10000
if player.wearing(['Tome of fire']) and player.spell().element == "Fire":
hit = hit * 3 / 2
if monster.name == "Skogre" or monster.name == "Zogre":
if player.wearing(["Comp ogre bow"]) and player.UsingBrutalArrows():
hit = hit * 1 // do nothing
elif player.spell().name == "Crumble Undead":
hit = hit / 2
else:
hit = hit / 4
if monster.name == "Zulrah" and hit > 50:
hit = 45 + randominc(5)
if monster.name == "Ice demon":
if player.spell().element == "Fire":
hit = hit * 3/2
else:
// TODO: is there anything that isn't /3?
hit = hit / 3
if monster.name == "Corporeal Beast":
if ((style.category == "Spears" or style.category == "Halberds" or player.wearing("Osmumten's fang")) and style.type == STAB) or style == MAGIC:
hit = hit * 1 // do nothing
else:
hit = hit / 2
if monster.name == "Slagilith" and !player.wieldingPickaxe():
hit = hit / 3
if monster.kerisCorrupted:
hit = hit * 5/4
hit_opponent(hit)
// TODO: other stuff that only happens on success
else:
hit_opponent(0)
hit_opponent(hit):
if monster.hasAttribute("penance"):
// Damage is even increased for missed attacks
hit = hit + player.BarbarianAssault.AttackerLevel // (1-5)
// Apply damage and do other stuff