Ejemplo n.º 1
0
class NaturalAttack(MeleeAttack):
    name = ""
    on_success = StringBuilder(Attacker, Verb("hit", Attacker), Defender)
    on_failure = StringBuilder(Defender, Verb("dodge", Defender), His(Attacker), "attack!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender, "with", His(Attacker), "attack,")

    def can_execute(self, attacker, defender):
        # Natural attacks should come from the body, in turn it should check for it when used.
        return True

    def echo(self, attacker, defender, success, damage, sneak_attack=False):
        context = contexts.Combat(attacker, defender)
        if success:
            if sneak_attack:
                message = self.on_stealth + "for {} damage!".format(damage)
            else:
                message = self.on_success + "for {} damage!".format(damage)
        else:
            message = self.on_failure
        self.game.echo.see(attacker, message, context)

    def execute(self, attacker, defender, attack_set):
        sneak_attack = False
        if attacker.query.special_ability(specialabilities.SneakAttack):
            if not defender.vision.can_see_object(attacker):
                sneak_attack = True

        attacker.events.transmit(events.Attacking(attacker))
        hits = 0
        for _ in range(0, attack_set.amount):
            success = self.make_melee_hit_roll(attacker, defender, sneak_attack=sneak_attack)
            if success:
                hits += 1
                base_attack = attack_set.attack
                damage = self.make_melee_damage_roll(
                    attacker, base_attack.damage_dice,
                    base_attack.damage_bonus,
                    sneak_attack=sneak_attack
                )

                self.echo(attacker, defender, True, damage, sneak_attack=sneak_attack)
                defender_health = defender.health
                if defender_health:
                    defender_health.take_damage(damage, attacker)
            else:
                self.echo(attacker, defender, False, 0)

        return True
Ejemplo n.º 2
0
    def add(self, item):
        if self.host.equipment:
            containers = (item.container
                          for item in self.host.equipment.get_all_items()
                          if item.container)
            for container in containers:
                if container.add_item(item):
                    message = StringBuilder(Actor, Verb("add",
                                                        Actor), TargetOne,
                                            "to", His(Actor), TargetTwo)
                    context = contexts.TwoTargetAction(self.host, item,
                                                       container.host)
                    self.host.game.echo.see(self.host, message, context)

                    return True

        return False
Ejemplo n.º 3
0
    def execute(self, attacker, defender, fired_weapons, distance, compatible_ammo):
        attacker.events.transmit(events.Attacking(attacker))
        for fired_weapon in fired_weapons:
            ammunition_spent = self.consume_ammunition(attacker, fired_weapon, compatible_ammo)
            context = contexts.RangedCombat(attacker, defender, fired_weapon, ammunition_spent)
            message = StringBuilder(
                Attacker, Verb("fire", Attacker), His(Attacker), AttackerWeapon, "at", Defender
            )
            if self.make_hit_roll(attacker, defender, fired_weapon, distance):
                damage = self.make_damage_roll(ammunition_spent)
                message += "hitting for %s damage!" % damage
                self.game.echo.see(attacker, message, context)
                defender.health.take_damage(damage, attacker)
            else:
                # TODO This message here could be better.
                message += "missing the shot!"
                self.game.echo.see(attacker, message, context)

        return True
Ejemplo n.º 4
0
class Gaze(NaturalAttack):
    name = "gaze"
    base_attack = attacks.Gaze
    on_success = StringBuilder(Attacker, Verb("gaze", Attacker), Defender)
    on_failure = StringBuilder(Defender, Verb("dodge", Defender), His(Attacker), "attack!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender, "with", His(Attacker), "gaze,")
Ejemplo n.º 5
0
class Crush(NaturalAttack):
    name = "crush"
    base_attack = attacks.Crush
    on_success = StringBuilder(Attacker, Verb("crush", Attacker), Defender)
    on_failure = StringBuilder(Defender, Verb("dodge", Defender), His(Attacker), "attack!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender, "with", His(Attacker), "crushing attack,")
Ejemplo n.º 6
0
class ConfusionBySwarm(NaturalAttack):
    name = "Confusion By Swarm"
    base_attack = attacks.ConfusionBySwarm
    on_success = StringBuilder(Attacker, Verb("confuse", Attacker), Defender)
    on_failure = StringBuilder(Defender, Verb("dodge", Defender), His(Attacker), "attack!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender, "with", His(Attacker), "confusing attack,")
Ejemplo n.º 7
0
class Kick(NaturalAttack):
    name = "kick"
    base_attack = attacks.Kick
    on_success = StringBuilder(Attacker, Verb("kick", Attacker), Defender)
    on_failure = StringBuilder(Defender, Verb("dodge", Defender), His(Attacker), "attack!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender, "with", His(Attacker), "kick,")
Ejemplo n.º 8
0
class Punch(NaturalAttack):
    name = "punch"
    base_attack = attacks.Punch
    on_success = StringBuilder(Attacker, Verb("punch", Attacker), Defender)
    on_failure = StringBuilder(Defender, Verb("dodge", Defender), His(Attacker), "attack!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender, "with", His(Attacker), "punch,")
Ejemplo n.º 9
0
class Sting(NaturalAttack):
    name = "sting"
    base_attack = attacks.Sting
    on_success = StringBuilder(Attacker, Verb("sting", Attacker), Defender)
    on_failure = StringBuilder(Defender, Verb("dodge", Defender), His(Attacker), "attack!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender, "with", His(Attacker), "sting,")
Ejemplo n.º 10
0
class Hoof(NaturalAttack):
    name = "hoof"
    base_attack = attacks.Hoof
    on_success = StringBuilder(Attacker, Verb("hoof", Attacker), Defender)
    on_failure = StringBuilder(Defender, Verb("dodge", Defender), His(Attacker), "attack!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender, "with", His(Attacker), "hoof,")
Ejemplo n.º 11
0
class WeaponAttack(MeleeAttack):
    name = "weapon"
    base_attack = attacks.WeaponAttack
    on_success = StringBuilder(Attacker, Verb("hit", Attacker), Defender,
                               "with", His(Attacker), AttackerWeapon)
    on_failure = StringBuilder(Attacker, Verb("miss", Attacker), Defender, "!")
    on_stealth = StringBuilder(Attacker, Verb("surprise", Attacker), Defender,
                               "with", His(Attacker), "attack,")

    def can_execute(self, attacker, defender):
        if attacker.equipment.get_wielded_items():
            return True
        return False

    def execute(self, attacker, defender, attack_set):
        sneak_attack = False
        sorted_melee_weapons = self._sort_melee_weapons_by_damage(attacker)
        if attacker.query.special_ability(specialabilities.SneakAttack):
            if not defender.vision.can_see_object(attacker):
                sneak_attack = True

        attacker.events.transmit(events.Attacking(attacker))
        for _ in range(attack_set.amount):
            if sorted_melee_weapons:
                weapon = sorted_melee_weapons.pop()
                damage_dice = weapon.melee.melee_damage
            else:
                improvised_weapons = self._get_improvised_weapons(attacker)
                if not improvised_weapons:
                    return True

                weapon = improvised_weapons.pop()
                damage_dice = D4(1)

            success = self.make_melee_hit_roll(attacker,
                                               defender,
                                               sneak_attack=sneak_attack)
            if success:
                damage = self.make_melee_damage_roll(attacker,
                                                     damage_dice,
                                                     sneak_attack=sneak_attack)
                self.echo(attacker,
                          defender,
                          weapon,
                          True,
                          damage,
                          sneak_attack=sneak_attack)
                if defender.health:
                    defender.health.take_damage(damage, attacker)
            else:
                self.echo(attacker,
                          defender,
                          weapon,
                          False,
                          0,
                          sneak_attack=sneak_attack)

        return True

    @staticmethod
    def _sort_melee_weapons_by_damage(attacker):
        melee_weapons = [
            weapon for weapon in attacker.equipment.get_wielded_items()
            if weapon.melee
        ]
        melee_weapons.sort(key=lambda item: item.melee.melee_damage.sides *
                           item.melee.melee_damage.amount)

        return melee_weapons

    @staticmethod
    def _get_improvised_weapons(attacker):
        return [weapon for weapon in attacker.equipment.get_wielded_items()]

    def echo(self,
             attacker,
             defender,
             weapon,
             success,
             damage,
             sneak_attack=False):
        # TODO I want to have a nice combat message system, I'll think about it.
        # TODO For now, this poor message.
        context = contexts.WeaponCombat(attacker, defender, weapon)
        if success:
            if sneak_attack:
                message = self.on_stealth + "for {} damage!".format(damage)
            else:
                message = self.on_success + "for {} damage!".format(damage)
        else:
            message = self.on_failure
        self.game.echo.see(attacker, message, context)