def checkhit(attacker, defender, time): # Get the skills used by the attacker and defender attackerWeapon = attacker.getweapon() defenderWeapon = defender.getweapon() attackerSkill = combat.utilities.weaponskill(attacker, attackerWeapon, True) defenderSkill = combat.utilities.weaponskill(defender, defenderWeapon, True) combat.utilities.playswinganimation(attacker, defender, attackerWeapon) # Retrieve the skill values attackerValue = attacker.skill[attackerSkill] / 10 defenderValue = defender.skill[defenderSkill] / 10 # Calculate the hit chance bonus = 0 # Get the weapon "accuracy" status bonus += properties.fromchar(attacker, HITBONUS) # Get the attackers AttackChance bonus attackChance = (attackerValue + 20.0) * (100 + bonus) # Calculate the defense chance bonus = properties.fromchar(defender, DEFENSEBONUS) # Get the defenders defend chance defendChance = (defenderValue + 20.0) * (100 + bonus) # Give a minimum chance of 2% chance = max(0.02, attackChance / (defendChance * 2.0)) # Scale the chance using the ability ability = getability(attacker) if ability: chance = ability.scalehitchance(attacker, defender, chance) return checkskill(attacker, attackerSkill, chance)
def miss(attacker, defender, weapon, time): combat.utilities.playmisssound(attacker, defender) # Notify the weapon ability ability = getability(attacker) if ability: ability.miss(attacker, defender)
def checkhit(attacker, defender, time): # Get the skills used by the attacker and defender attackerWeapon = attacker.getweapon() defenderWeapon = defender.getweapon() attackerSkill = combat.utilities.weaponskill(attacker, attackerWeapon, True) defenderSkill = combat.utilities.weaponskill(defender, defenderWeapon, True) combat.utilities.playswinganimation(attacker, defender, attackerWeapon) # Retrieve the skill values attackerValue = attacker.skill[attackerSkill] / 10 defenderValue = defender.skill[defenderSkill] / 10 # Calculate the hit chance bonus = 0 # Get the weapon "accuracy" status bonus += properties.fromchar( attacker, HITBONUS) # Get the attackers AttackChance bonus # attacker gets 10% bonus when they're under divine fury if attacker.hasscript('magic.divinefury'): bonus += 10 if attacker.hastag('hitlowerattack'): bonus -= 25 # Under Hit Lower Attack effect -> 25% malus attackChance = (attackerValue + 20.0) * (100 + bonus) # Calculate the defense chance bonus = properties.fromchar( defender, DEFENSEBONUS) # Get the defenders defend chance # defender loses 20% bonus when they're under divine fury if defender.hasscript('magic.divinefury'): bonus -= 20 if defender.hastag('hitlowerdefense'): bonus -= 25 # Under Hit Lower Defense effect -> 25% malus defendChance = (defenderValue + 20.0) * (100 + bonus) # Give a minimum chance of 2% chance = max(0.02, attackChance / (defendChance * 2.0)) # Scale the chance using the ability ability = getability(attacker) if ability: chance = ability.scalehitchance(attacker, defender, chance) return checkskill(attacker, attackerSkill, chance)
def checkhit(attacker, defender, time): # Get the skills used by the attacker and defender attackerWeapon = attacker.getweapon() defenderWeapon = defender.getweapon() attackerSkill = combat.utilities.weaponskill(attacker, attackerWeapon, True) defenderSkill = combat.utilities.weaponskill(defender, defenderWeapon, True) combat.utilities.playswinganimation(attacker, defender, attackerWeapon) # Retrieve the skill values attackerValue = attacker.skill[attackerSkill] / 10 defenderValue = defender.skill[defenderSkill] / 10 # Calculate the hit chance bonus = 0 # Get the weapon "accuracy" status bonus += properties.fromchar(attacker, HITBONUS) # Get the attackers AttackChance bonus # attacker gets 10% bonus when they're under divine fury if attacker.hasscript('magic.divinefury'): bonus += 10 if attacker.hastag('hitlowerattack'): bonus -= 25 # Under Hit Lower Attack effect -> 25% malus attackChance = (attackerValue + 20.0) * (100 + bonus) # Calculate the defense chance bonus = properties.fromchar(defender, DEFENSEBONUS) # Get the defenders defend chance # defender loses 20% bonus when they're under divine fury if defender.hasscript('magic.divinefury'): bonus -= 20 if defender.hastag('hitlowerdefense'): bonus -= 25 # Under Hit Lower Defense effect -> 25% malus defendChance = (defenderValue + 20.0) * (100 + bonus) # Give a minimum chance of 2% chance = max(0.02, attackChance / (defendChance * 2.0)) # Scale the chance using the ability ability = getability(attacker) if ability: chance = ability.scalehitchance(attacker, defender, chance) return checkskill(attacker, attackerSkill, chance)
def hit(attacker, defender, weapon, time): combat.utilities.playhitsound(attacker, defender) (mindamage, maxdamage) = properties.getdamage(attacker) damage = random.randint(mindamage, maxdamage) damage = scaledamage(attacker, damage, checkability = True) # Slaying? (only against NPCs) if weapon and defender.npc and checkSlaying(weapon, defender): defender.effect(0x37B9, 5, 10) damage *= 2 # Get the ability used by the attacker ability = getability(attacker) # Scale Damage using a weapons ability if ability: damage = ability.scaledamage(attacker, defender, damage) # Give the defender a chance to absorb damage damage = absorbdamage(defender, damage) # If the attack was parried, the ability was wasted if damage == 0 and ability: ability.use(attacker) if attacker.socket: attacker.socket.clilocmessage(1061140) # Your attack was parried ability = None # Reset ability ignorephysical = False if ability: ignorephysical = ability.ignorephysical # Get the damage distribution of the attackers weapon (physical, fire, cold, poison, energy) = damagetypes(attacker) damagedone = energydamage(defender, attacker, damage, physical, fire, cold, poison, energy, 0, DAMAGE_PHYSICAL, ignorephysical=ignorephysical) # Wear out the weapon if weapon: # Leeching leech = properties.fromitem(weapon, LIFELEECH) if leech and leech > random.randint(0, 99) and attacker.maxhitpoints > attacker.hitpoints: amount = (damagedone * 30) / 100 # Leech 30% Health if amount > 0: attacker.hitpoints = min(attacker.maxhitpoints, attacker.hitpoints + amount) attacker.updatehealth() leech = properties.fromitem(weapon, STAMINALEECH) if leech and leech > random.randint(0, 99) and attacker.maxhitpoints > attacker.stamina: amount = (damagedone * 100) / 100 # Leech 100% Stamina if amount > 0: attacker.stamina = min(attacker.maxstamina, attacker.stamina + amount) attacker.updatehealth() leech = properties.fromitem(weapon, MANALEECH) if leech and leech > random.randint(0, 99) and attacker.maxmana > attacker.mana: amount = (damagedone * 40) / 100 # Leech 40% Mana if amount > 0: attacker.mana = min(attacker.maxmana, attacker.mana + amount) attacker.updatemana() # Splash Damage for effectid in [SPLASHPHYSICAL, SPLASHFIRE, SPLASHCOLD, SPLASHPOISON, SPLASHENERGY]: effect = properties.fromitem(weapon, effectid) if effect and effect > random.randint(0, 99): splashdamage(attacker, effectid) # Hit Spell effects for (effectid, callback) in combat.hiteffects.EFFECTS.items(): effect = properties.fromitem(weapon, effectid) if effect and effect > random.randint(0, 99): callback(attacker, defender) # poisoning doesn't work that way anymore #if weapon.hastag( 'poisoning_uses' ): # poisoning.hitEffect( defender, weapon ) # 4% chance for losing one hitpoint if 0.04 >= random.random(): # If it's a self repairing item, grant health instead of reducing it selfrepair = properties.fromitem(weapon, SELFREPAIR) if selfrepair > 0 and weapon.health < weapon.maxhealth - 1: if selfrepair > random.randint(0, 9): weapon.health += 2 weapon.resendtooltip() elif weapon.health > 0: weapon.health -= 1 weapon.resendtooltip() if weapon.health <= 0: tobackpack(weapon, attacker) weapon.update() if attacker.socket: attacker.socket.clilocmessage(500645) # Notify the weapon ability if ability: ability.hit(attacker, defender, damage)
def onSwing(attacker, defender, time): # We won't allow any swings from or against players # who are offline if defender.player and not defender.socket and not defender.logouttime: attacker.attacktarget = 0 return if attacker.player and not attacker.socket and not attacker.logouttime: attacker.attacktarget = 0 return # Our defender went invisible or hidden? if defender.invisible or defender.hidden: attacker.attacktarget = None return # Reveal us attacker.reveal() # Let the defender strike back if he doesnt fight anyone right now if not defender.attacktarget: defender.fight(attacker) if DEBUG_COMBAT_INFO == 1: attacker.log(LOG_PYTHON, "Swing from 0x%x at 0x%x\n" % (defender.serial, attacker.serial)) if AGEOFSHADOWS: weapon = attacker.getweapon() try: # Ranged weapons need shooting first if weapon and (weapon.type == 1007 or weapon.type == 1006): ability = getability(attacker) # We have to be standing for >= 1000 ms, otherwise try again later if (not ability or not ability.movingshot) and attacker.lastmovement + 1000 > wolfpack.time.currenttime(): attacker.nextswing = attacker.lastmovement + 1000 return # See if we can fire the weapon. # if not, wait until the next normal swing. if combat.aos.fireweapon(attacker, defender, weapon): combat.utilities.sendswing(attacker, defender) # Send Swing if combat.aos.checkhit(attacker, defender, time): combat.aos.hit(attacker, defender, weapon, time) else: combat.aos.miss(attacker, defender, weapon, time) elif combat.aos.checkhit(attacker, defender, time): combat.utilities.sendswing(attacker, defender) # Send Swing combat.aos.hit(attacker, defender, weapon, time) else: combat.utilities.sendswing(attacker, defender) # Send Swing combat.aos.miss(attacker, defender, weapon, time) except: # Try again in 10 seconds attacker.nextswing = time + 10000 raise delay = properties.getdelay(attacker, weapon) attacker.nextswing = time + delay
def hit(attacker, defender, weapon, time): combat.utilities.playhitsound(attacker, defender) (mindamage, maxdamage) = properties.getdamage(attacker) damage = random.randint(mindamage, maxdamage) damage = scaledamage(attacker, damage, checkability=True) # Slaying? (only against NPCs) if weapon and defender.npc and checkSlaying(weapon, defender): defender.effect(0x37B9, 5, 10) damage *= 2 # Get the ability used by the attacker ability = getability(attacker) # Scale Damage using a weapons ability if ability: damage = ability.scaledamage(attacker, defender, damage) # Enemy of One (chivalry) if attacker.npc: if defender.player: if defender.hastag("enemyofonetype") and defender.gettag( "enemyofonetype") != attacker.id: damage *= 2 if defender.npc: # only NPC if attacker.player: if attacker.hastag("waitingforenemy"): attacker.settag("enemyofonetype", defender.id) attacker.deltag("waitingforenemy") if attacker.hastag("enemyofonetype") and attacker.gettag( "enemyofonetype") == defender.id: defender.effect(0x37B9, 10, 5) damage += scaledamage(attacker, 50) packInstinctBonus = GetPackInstinctBonus(attacker, defender) if packInstinctBonus: damage += scaledamage(attacker, packInstinctBonus) slayer = properties.fromitem(weapon, SLAYER) if slayer and slayer == "silver" and magic.necromancy.transformed( defender) and not defender.hasscript("magic.horrificbeast"): damage += scaledamage( attacker, 25 ) # Every necromancer transformation other than horrific beast takes an additional 25% damage # Give the defender a chance to absorb damage damage = absorbdamage(defender, damage) blocked = damage <= 0 # If the attack was parried, the ability was wasted if AGEOFSHADOWS and blocked: if attacker.socket: attacker.socket.clilocmessage(1061140) # Your attack was parried clearability(attacker) ignorephysical = False if ability: ignorephysical = ability.ignorephysical # Get the damage distribution of the attackers weapon (physical, fire, cold, poison, energy) = damagetypes(attacker, defender) damagedone = energydamage(defender, attacker, damage, physical, fire, cold, poison, energy, 0, DAMAGE_PHYSICAL, ignorephysical=ignorephysical) # Wear out the weapon if weapon: # Leeching if not blocked: # Making default Leechs to prevent errors lifeleech = 0 staminaleech = 0 manaleech = 0 leech = properties.fromitem(weapon, LIFELEECH) if leech and leech > random.randint( 0, 99) and attacker.maxhitpoints > attacker.hitpoints: lifeleech = (damagedone * 30) / 100 # Leech 30% Health leech = properties.fromitem(weapon, STAMINALEECH) if leech and leech > random.randint( 0, 99) and attacker.maxhitpoints > attacker.stamina: staminaleech = (damagedone * 100) / 100 # Leech 100% Stamina leech = properties.fromitem(weapon, MANALEECH) if leech and leech > random.randint( 0, 99) and attacker.maxmana > attacker.mana: manaleech = (damagedone * 40) / 100 # Leech 40% Mana # Now leech life, stamina and mana if lifeleech > 0: attacker.hitpoints = min(attacker.maxhitpoints, attacker.hitpoints + lifeleech) attacker.updatehealth() if staminaleech > 0: attacker.stamina = min(attacker.maxstamina, attacker.stamina + staminaleech) attacker.updatehealth() if manaleech > 0: attacker.mana = min(attacker.maxmana, attacker.mana + manaleech) attacker.updatemana() # Poisoning (50% chance) if weapon.hastag('poisoning_uses'): poisoning_uses = int(weapon.gettag('poisoning_uses')) if poisoning_uses <= 0: weapon.deltag('poisoning_uses') weapon.resendtooltip() else: poisoning_uses -= 1 if poisoning_uses <= 0: weapon.deltag('poisoning_uses') weapon.resendtooltip() else: weapon.settag('poisoning_uses', poisoning_uses) poisoning_strength = 0 # Assume lesser unless the tag tells so otherwise if weapon.hastag('poisoning_strength'): poisoning_strength = int( weapon.gettag('poisoning_strength')) if defender.hasscript( "magic.evilomen") and poisoning_strength < 4: poisoning_strength += 1 if random.random() >= 0.50: if system.poison.poison(defender, poisoning_strength): if attacker.socket: attacker.socket.clilocmessage( 1008096, "", 0x3b2, 3, None, defender.name, False, False) if defender.socket: attacker.socket.clilocmessage( 1008097, "", 0x3b2, 3, None, attacker.name, False, True) # Splash Damage for effectid in [ SPLASHPHYSICAL, SPLASHFIRE, SPLASHCOLD, SPLASHPOISON, SPLASHENERGY ]: effect = properties.fromitem(weapon, effectid) if effect and effect > random.randint(0, 99): splashdamage(attacker, effectid, excludechar=defender) # Hit Spell effects for (effectid, callback) in combat.hiteffects.EFFECTS.items(): effect = properties.fromitem(weapon, effectid) if effect and effect > random.randint(0, 99): callback(attacker, defender) # Slime or Toxic Elemental, 4% chance for losing one hitpoint if weapon.maxhealth > 0 and ( (weapon.getintproperty('range', 1) <= 1 and (defender.id == 51 or defender.id == 158)) or 0.04 >= random.random()): if (weapon.getintproperty('range', 1) <= 1 and (defender.id == 51 or defender.id == 158)): attacker.message(500263, '') # *Acid blood scars your weapon!* # If it's a self repairing item, grant health instead of reducing it selfrepair = properties.fromitem(weapon, SELFREPAIR) if AGEOFSHADOWS and selfrepair > 0: if selfrepair > random.randint(0, 9): weapon.health += 2 weapon.resendtooltip() else: if weapon.health > 0: weapon.health -= 1 elif weapon.maxhealth > 1: weapon.maxhealth -= 1 attacker.message(1061121, '') # Your equipment is severely damaged. else: weapon.delete() if weapon: weapon.resendtooltip() #if weapon.health <= 0: # tobackpack(weapon, attacker) # weapon.update() # if attacker.socket: # attacker.socket.clilocmessage(500645) # Notify the weapon ability if not blocked and ability: ability.hit(attacker, defender, damage)
def onSwing(attacker, defender, time): # Allow under no circumstances a swing against yourself if attacker == defender: attacker.attacktarget = None return # We won't allow any swings from or against players # who are offline if defender.player and not defender.socket and not defender.logouttime: attacker.attacktarget = 0 return if attacker.player and not attacker.socket and not attacker.logouttime: attacker.attacktarget = 0 return # Our defender went invisible or hidden? if defender.invisible or defender.hidden: attacker.attacktarget = None return # Wait one second until the attacker is unfrozen if attacker.frozen: attacker.nextswing = time + 500 return # Reveal us attacker.reveal() # Let the defender strike back if he doesnt fight anyone right now if not defender.attacktarget: defender.fight(attacker) if DEBUG_COMBAT_INFO == 1: attacker.log( LOG_PYTHON, "Swing from 0x%x at 0x%x\n" % (defender.serial, attacker.serial)) if AGEOFSHADOWS: weapon = attacker.getweapon() try: # Ranged weapons need shooting first if weapon and (weapon.type == 1007 or weapon.type == 1006): ability = getability(attacker) # We have to be standing for >= 500 ms, otherwise try again later if ( not ability or not ability.movingshot ) and attacker.lastmovement + 500 > wolfpack.time.currenttime( ): attacker.nextswing = attacker.lastmovement + 500 return # See if we can fire the weapon. # if not, wait until the next normal swing. if combat.aos.fireweapon(attacker, defender, weapon): combat.utilities.sendswing(attacker, defender) # Send Swing if combat.aos.checkhit(attacker, defender, time): combat.aos.hit(attacker, defender, weapon, time) else: combat.aos.miss(attacker, defender, weapon, time) elif combat.aos.checkhit(attacker, defender, time): combat.utilities.sendswing(attacker, defender) # Send Swing combat.aos.hit(attacker, defender, weapon, time) else: combat.utilities.sendswing(attacker, defender) # Send Swing combat.aos.miss(attacker, defender, weapon, time) except: # Try again in 10 seconds attacker.nextswing = time + 10000 raise delay = properties.getdelay(attacker, weapon) attacker.nextswing = time + delay
def hit(attacker, defender, weapon, time): combat.utilities.playhitsound(attacker, defender) (mindamage, maxdamage) = properties.getdamage(attacker) damage = random.randint(mindamage, maxdamage) damage = scaledamage(attacker, damage, checkability = True) # Slaying? (only against NPCs) if weapon and defender.npc and checkSlaying(weapon, defender): defender.effect(0x37B9, 5, 10) damage *= 2 # Get the ability used by the attacker ability = getability(attacker) # Scale Damage using a weapons ability if ability: damage = ability.scaledamage(attacker, defender, damage) # Enemy of One (chivalry) if attacker.npc: if defender.player: if defender.hastag( "enemyofonetype" ) and defender.gettag( "enemyofonetype" ) != attacker.id: damage *= 2 if defender.npc: # only NPC if attacker.player: if attacker.hastag( "waitingforenemy" ): attacker.settag( "enemyofonetype", defender.id ) attacker.deltag( "waitingforenemy" ) if attacker.hastag( "enemyofonetype" ) and attacker.gettag( "enemyofonetype" ) == defender.id: defender.effect( 0x37B9, 10, 5 ) damage += scaledamage(attacker, 50 ) packInstinctBonus = GetPackInstinctBonus( attacker, defender ) if packInstinctBonus: damage += scaledamage(attacker, packInstinctBonus) slayer = properties.fromitem(weapon, SLAYER) if slayer and slayer == "silver" and magic.necromancy.transformed(defender) and not defender.hasscript("magic.horrificbeast"): damage += scaledamage(attacker, 25 ) # Every necromancer transformation other than horrific beast takes an additional 25% damage # Give the defender a chance to absorb damage damage = absorbdamage(defender, damage) blocked = damage <= 0 # If the attack was parried, the ability was wasted if AGEOFSHADOWS and blocked: if attacker.socket: attacker.socket.clilocmessage(1061140) # Your attack was parried clearability(attacker) ignorephysical = False if ability: ignorephysical = ability.ignorephysical # Get the damage distribution of the attackers weapon (physical, fire, cold, poison, energy) = damagetypes(attacker, defender) damagedone = energydamage(defender, attacker, damage, physical, fire, cold, poison, energy, 0, DAMAGE_PHYSICAL, ignorephysical=ignorephysical) # Wear out the weapon if weapon: # Leeching if not blocked: # Making default Leechs to prevent errors lifeleech = 0 staminaleech = 0 manaleech = 0 leech = properties.fromitem(weapon, LIFELEECH) if leech and leech > random.randint(0, 99) and attacker.maxhitpoints > attacker.hitpoints: lifeleech = (damagedone * 30) / 100 # Leech 30% Health leech = properties.fromitem(weapon, STAMINALEECH) if leech and leech > random.randint(0, 99) and attacker.maxhitpoints > attacker.stamina: staminaleech = (damagedone * 100) / 100 # Leech 100% Stamina leech = properties.fromitem(weapon, MANALEECH) if leech and leech > random.randint(0, 99) and attacker.maxmana > attacker.mana: manaleech = (damagedone * 40) / 100 # Leech 40% Mana # Now leech life, stamina and mana if lifeleech > 0: attacker.hitpoints = min(attacker.maxhitpoints, attacker.hitpoints + lifeleech) attacker.updatehealth() if staminaleech > 0: attacker.stamina = min(attacker.maxstamina, attacker.stamina + staminaleech) attacker.updatehealth() if manaleech > 0: attacker.mana = min(attacker.maxmana, attacker.mana + manaleech) attacker.updatemana() # Poisoning (50% chance) if weapon.hastag('poisoning_uses'): poisoning_uses = int(weapon.gettag('poisoning_uses')) if poisoning_uses <= 0: weapon.deltag('poisoning_uses') weapon.resendtooltip() else: poisoning_uses -= 1 if poisoning_uses <= 0: weapon.deltag('poisoning_uses') weapon.resendtooltip() else: weapon.settag('poisoning_uses', poisoning_uses) poisoning_strength = 0 # Assume lesser unless the tag tells so otherwise if weapon.hastag('poisoning_strength'): poisoning_strength = int(weapon.gettag('poisoning_strength')) if defender.hasscript("magic.evilomen") and poisoning_strength < 4: poisoning_strength += 1 if random.random() >= 0.50: if system.poison.poison(defender, poisoning_strength): if attacker.socket: attacker.socket.clilocmessage(1008096, "", 0x3b2, 3, None, defender.name, False, False) if defender.socket: attacker.socket.clilocmessage(1008097, "", 0x3b2, 3, None, attacker.name, False, True) # Splash Damage for effectid in [SPLASHPHYSICAL, SPLASHFIRE, SPLASHCOLD, SPLASHPOISON, SPLASHENERGY]: effect = properties.fromitem(weapon, effectid) if effect and effect > random.randint(0, 99): splashdamage(attacker, effectid, excludechar = defender) # Hit Spell effects for (effectid, callback) in combat.hiteffects.EFFECTS.items(): effect = properties.fromitem(weapon, effectid) if effect and effect > random.randint(0, 99): callback(attacker, defender) # Slime or Toxic Elemental, 4% chance for losing one hitpoint if weapon.maxhealth > 0 and ( (weapon.getintproperty( 'range', 1 ) <= 1 and (defender.id == 51 or defender.id == 158)) or 0.04 >= random.random() ): if (weapon.getintproperty( 'range', 1 ) <= 1 and (defender.id == 51 or defender.id == 158)): attacker.message( 500263, '' ) # *Acid blood scars your weapon!* # If it's a self repairing item, grant health instead of reducing it selfrepair = properties.fromitem(weapon, SELFREPAIR) if AGEOFSHADOWS and selfrepair > 0: if selfrepair > random.randint(0, 9): weapon.health += 2 weapon.resendtooltip() else: if weapon.health > 0: weapon.health -= 1 elif weapon.maxhealth > 1: weapon.maxhealth -= 1 attacker.message( 1061121, '' ) # Your equipment is severely damaged. else: weapon.delete() if weapon: weapon.resendtooltip() #if weapon.health <= 0: # tobackpack(weapon, attacker) # weapon.update() # if attacker.socket: # attacker.socket.clilocmessage(500645) # Notify the weapon ability if not blocked and ability: ability.hit(attacker, defender, damage)