Exemple #1
0
    def func(self):
        # Check if it is player's combat_turn
        if self.caller.db.combat_turn:

            # Check to see if caller is in combat loop:
            if self.caller in self.combat_loop:
                self.caller.location.msg_contents(f"|025{self.caller.key} breaks away from combat.|n")
                # Instantiate combat loop class
                loop = CombatLoop(self.caller, target=None)
                # Run cleanup to move to next target
                self.combat_loop.remove(self.caller)
                # Reset stats
                self.caller.db.in_combat = 0
                self.caller.db.combat_turn = 1

                # Check for only npcs remaining.
                loop_contents = [char for char in self.combat_loop if utils.inherits_from(char, Npc)]
                if len(loop_contents) == len(self.caller.location.db.combat_loop):
                    # Reset combat stats
                    for char in self.combat_loop:
                        char.db.combat_turn = 1
                        char.db.in_combat = 0
                    self.combat_loop.clear()
                    self.caller.location.msg_contents("|025Combat is now over.|n")
                    return
                else:
                    loop.cleanup()

            else:
                self.msg(f"|400You are not part of the combat loop for {self.caller.location}.|n")

        else:
            self.caller.msg("|430You need to wait until it is your turn before you are able to act.|n")
Exemple #2
0
    def func(self):
        combatant = Combatant(self.caller)

        if not self.args:
            self.msg("|430Usage: cleave <target>|n")
            return

        if combatant.cantFight:
            combatant.message("|400You are too injured to act.|n")
            return

        # Check for and error handle designated target
        target = self.caller.search(self.target)

        # Pass all checks now execute command.
        # Use parsed args in combat loop. Handles turn order in combat.
        if not target:
            combatant.message("|430Please designate an appropriate target.|n")
            return

        victim = combatant.getVictim(self.target)

        if not target.db.bleed_points:
            combatant.message(f"{victim.name} |400is dead. You only further mutiliate their body.|n")
            combatant.broadcast(f"{combatant.name} |025further mutilates the corpse of|n {victim.name}|025.|n")
            return

        loop = CombatLoop(combatant.caller, target)
        loop.resolveCommand()

        if combatant.hasTurn(f"|430You need to wait until it is your turn before you are able to act.|n"):
            if combatant.isArmed(f"|430Before you attack you must equip a weapon using the command equip <weapon>.|n"):
                if not combatant.hasWeakness(f"|400You are too weak to use this attack.|n"):
                        if combatant.hasCleavesRemaining(
                                f"|400You have 0 cleaves remaining or do not have the skill.\nPlease choose another action."):
                            if combatant.hasTwoHandedWeapon(
                                    f"|430Before you attack you must equip a two handed weapon using the command equip <weapon>.|n"):
                                maneuver_difficulty = 0
                                attack_result = combatant.rollAttack(maneuver_difficulty)
                                if attack_result >= victim.av:
                                    shot_location = combatant.determineHitLocation(victim)
                                    if not victim.blocksWithShield(shot_location):
                                        combatant.decreaseCleaves(1)
                                        if not victim.resistsAttack():
                                            skip_av_damage = True
                                            combatant.broadcast(f"{combatant.name} |025strikes|n (|020{attack_result}|n) |025with great ferocity and cleaves|n {victim.name}|025's {shot_location}|n (|400{victim.av}|n)|025, dealing|n (|430{combatant.getDamage()}|n) |025damage|n.")
                                            victim.takeDamage(combatant, combatant.getDamage(), shot_location, skip_av_damage)
                                        else:
                                            combatant.broadcast(
                                                f"{combatant.name} |025strikes|n (|020{attack_result}|n) |025with great ferocity and cleaves|n {victim.name}|025's {shot_location} but|n {victim.name} |025resists the attack with grim determination.|n")
                                    else:
                                        combatant.broadcast(
                                            f"{combatant.name} |025strikes|n (|020{attack_result}|n) |025with great ferocity and cleaves {victim.name}'s {shot_location}|n (|400{victim.av}|n)|025, however |n{victim.name} |025manages to block the blow with their shield!|n.")
                                else:
                                    combatant.broadcast(f"{combatant.name} |025swings ferociously|n (|030{attack_result}|n) |025at|n {victim.name} (|400{victim.av}|n)|025, but misses.|n")

                                # Clean up
                                # Set self.caller's combat_turn to 0. Can no longer use combat commands.
                                loop.combatTurnOff(self.caller)
                                loop.cleanup()
Exemple #3
0
    def func(self):
        combatant = self.caller

        # Check if it is player's combat_turn
        if combatant.db.combat_turn:

            # Check to see if caller is in combat loop:
            if combatant in self.combat_loop:
                combatant.location.msg_contents(
                    f"|025{self.caller.key} passes on their turn.|n")
                # Instantiate combat loop class
                loop = CombatLoop(self.caller, target=None)
                loop.cleanup()

            else:
                self.msg(
                    f"|400You are not part of the combat loop for {self.caller.location}.|n"
                )

        else:
            combatant.msg(
                "|430You need to wait until it is your turn before you are able to act.|n"
            )
Exemple #4
0
    def func(self):
        combatant = Combatant(self.caller)

        if not self.target:
            self.caller.msg("|430Usage: stagger <target>|n")
            return

        if combatant.cantFight:
            combatant.message("|400You are too injured to act.|n")
            return

        # Get target if there is one
        # Check for and error handle designated target
        target = self.caller.search(self.target)

        # Pass all checks now execute command.
        # Use parsed args in combat loop. Handles turn order in combat.
        if not target:
            combatant.message("|430Please designate an appropriate target.|n")
            return

        victim = combatant.getVictim(self.target)

        if not target.db.bleed_points:
            combatant.message(f"{victim.name} |400is dead. You only further mutiliate their body.|n")
            combatant.broadcast(f"{combatant.name} |025further mutilates the corpse of|n {victim.name}|025.|n")
            return

        loop = CombatLoop(combatant.caller, target)
        loop.resolveCommand()

        if combatant.hasTurn(f"|430You need to wait until it is your turn before you are able to act.|n"):
            if combatant.isArmed(f"|430Before you attack you must equip a weapon using the command equip <weapon>.|n"):
                    if not combatant.hasWeakness(f"|400You are too weak to use this attack.|n"):
                        if combatant.hasStaggersRemaining(
                            f"|400You have 0 staggers remaining or do not have the skill.\nPlease choose another action.|n"):
                            if not combatant.inventory.hasBow() or combatant.hasSniper():
                                maneuver_difficulty = 2
                                attack_result = combatant.rollAttack(maneuver_difficulty)
                                if attack_result >= victim.av:
                                    combatant.decreaseStaggers(1)

                                    shot_location = combatant.determineHitLocation(victim)

                                    if not victim.blocksWithShield(shot_location):

                                        if not victim.resistsAttack():
                                            combatant.broadcast(f"{combatant.name} |025strikes|n (|020{attack_result}|n) |025with a powerful blow to the {shot_location}, staggering|n {victim.name} |025out of their footing|n (|400{victim.av}|n)|025, and dealing|n (|430{combatant.getStaggerDamage()}|n) |025damage.|n")
                                            victim.message(f"|430You have been staggered. You suffer a penalty on your next attack.|n")
                                            victim.stagger()
                                            victim.takeDamage(combatant, combatant.getStaggerDamage(), shot_location)
                                            victim.reportAv()
                                        else:
                                            combatant.broadcast(f"{combatant.name} |025strikes|n (|020{attack_result}|n) |025with a powerful blow to the {shot_location}|n (|400{victim.av}|n)|025, dealing|n (|430{combatant.getStaggerDamage()}|n) |025damage.|n {victim.name} |025resists being staggered by the powerful attack.|n")

                                    else:
                                        if not victim.resistsAttack():
                                            victim.stagger()
                                            combatant.broadcast(
                                                f"{combatant.name} |025strikes|n (|020{attack_result}|n) |025with a powerful blow to the {shot_location} but|n {victim.name} |025manages to block with their shield.  However|n {victim.name} |025is still staggered by the powerful attack.|n")
                                        else:
                                            combatant.broadcast(
                                                f"{combatant.name} |025strikes|n (|020{attack_result}|n) |025with a powerful blow to the {shot_location} but|n {victim.name} |025manages to block with their shield,|n {victim.name} |025also Resists being staggered by the powerful attack.|n")
                                else:
                                    combatant.broadcast(f"{combatant.name} |025swings wide|n (|400{attack_result}|n)|025, missing|n {victim.name} (|020{victim.av}|n)|025.|n")

                                # Set self.caller's combat_turn to 0. Can no longer use combat commands.
                                loop.combatTurnOff(self.caller)
                                loop.cleanup()
                            else:
                                combatant.message(
                                    f"|430To use Stagger with a bow equipped you must have the Sniper skill|n")
Exemple #5
0
    def func(self):
        combatant = Combatant(self.caller)

        if not self.args:
            self.caller.msg("|430Usage: disarm <target>|n")
            return

        if combatant.cantFight:
            combatant.message("|400You are too injured to act.|n")
            return

        # Check for and error handle designated target
        target = self.caller.search(self.target)

        # Pass all checks now execute command.
        # Use parsed args in combat loop. Handles turn order in combat.
        if not target:
            combatant.message("|430Please designate an appropriate target.|n")
            return

        if not target.db.bleed_points:
            combatant.message(
                f"{victim.name} |400is dead. You only further mutiliate their body.|n"
            )
            combatant.broadcast(
                f"{combatant.name} |025further mutilates the corpse of|n {victim.name}|025.|n"
            )
            return

        victim = combatant.getVictim(self.target)
        loop = CombatLoop(combatant.caller, target)
        loop.resolveCommand()

        #TODO: Right now the loop on Disarm and Sunder look almost identical.  I feel like you probably want something different?
        if combatant.hasTurn(
                f"|430You need to wait until it is your turn before you are able to act.|n"
        ):
            if combatant.isArmed(
                    f"|430Before you attack you must equip a weapon using the command equip <weapon>.|n"
            ):
                if not combatant.hasWeakness(
                        f"|400You are too weak to use this attack.|n"):
                    if combatant.hasDisarmsRemaining(
                            f"|400You have 0 disarms remaining or do not have the skill.\nPlease choose another action.|n"
                    ):
                        if not combatant.inventory.hasBow(
                        ) or combatant.hasSniper():
                            if not victim.hasTwoHandedWeapon():
                                if victim.isAlive:
                                    maneuver_difficulty = 2
                                    attack_result = combatant.rollAttack(
                                        maneuver_difficulty)
                                    if attack_result >= victim.av:
                                        # Check for NPC calling the command and pick a new command if so.
                                        # TODO: Spence - Why shouldn't NPCs use Disarm?
                                        if utils.inherits_from(
                                                self.caller, Npc
                                        ) and combatant.isTwoHanded():
                                            self.caller.execute_cmd(
                                                f"strike {target.key}")
                                            return

                                        combatant.decreaseDisarms(1)

                                        shot_location = combatant.determineHitLocation(
                                            victim)

                                        if not victim.resistsAttack():
                                            victim.message(
                                                f"|430You have been disarmed. Your next turn will be skipped.|n"
                                            )
                                            victim.disarm()
                                            combatant.broadcast(
                                                f"{combatant.name} |025nimbly strikes|n (|020{attack_result}|n) |025with a deft maneuver and disarms|n {victim.name} (|400{victim.av}|n)|025, striking them in the {shot_location} and dealing|n (|430{combatant.getDamage()}|n) |025damage|n."
                                            )
                                            victim.takeDamage(
                                                combatant,
                                                combatant.getDamage(),
                                                shot_location)
                                            victim.reportAv()
                                        else:
                                            combatant.broadcast(
                                                f"{combatant.name} |025nimbly strikes|n (|020{attack_result}|n)|025, striking them in the {shot_location} and dealing|n (|430{combatant.getDamage()}|n) |025damage|n. {combatant.name} |025attempts to disarm|n {victim.name}|025, but|n {victim.name} |025Resists the attempt.|n"
                                            )

                                    else:
                                        combatant.broadcast(
                                            f"{combatant.name} |025swings deftly,|n (|020{attack_result}|n) |025attempting to disarm|n {victim.name}|025, but misses|n (|400{victim.av}|n)|025.|n"
                                        )
                                else:
                                    combatant.message(
                                        f"{victim.name} |430is dead. You only further mutilate their body.|n"
                                    )
                                    combatant.broadcast(
                                        f"{combatant.name} |025further mutilates the corpse of|n {victim.name}.|n"
                                    )
                            else:
                                combatant.message(
                                    f"|430You cannot disarm a two-handed weapon. Please try another attack.|n"
                                )
                                combatant.broadcast(
                                    f"{combatant.name} |025tries to disarm|n {victim.name}|025, but cannot disarm a 2-handed weapon!|n"
                                )
                            # Clean up
                            # Set self.caller's combat_turn to 0. Can no longer use combat commands.
                            loop.combatTurnOff(self.caller)
                            loop.cleanup()
                        else:
                            combatant.message(
                                f"|430To use Disarm with a bow equipped you must have the Sniper skill|n"
                            )
Exemple #6
0
    def func(self):
        # Check for correct command
        if not self.args:
            self.caller.msg("|430Usage: heal <target>|n")
            return

        combatant = Combatant(self.caller)

        if combatant.cantFight:
            combatant.message("|400You are too injured to act.|n")
            return

        # Get target if there is one
        target = self.caller.search(self.target)
        victim = Combatant(target)

        # Get caller level of stabilize and emote how many points the caller will heal target that round.
        # May not increase targets body past 1
        # Only works on targets with body <= 0

        # Pass all checks now execute command.
        # Use parsed args in combat loop. Handles turn order in combat.
        if target:
            if (combatant.caller in combatant.caller.location.db.combat_loop
                ) or (target in combatant.caller.location.db.combat_loop):
                loop = CombatLoop(combatant.caller, target)
                loop.resolveCommand()
        else:
            self.msg("|430Please designate an appropriate target.|n")
            return

        if combatant.hasTurn():
            # Anything from this level on, consumes the users turn.  Learn to Diagnose!
            if combatant.hasChirurgeonsKit():
                if not victim.hasBody(3):
                    if victim.hasMoreBodyThan(0):
                        if combatant.battlefieldMedicine():
                            # Victim is at 1 or 2 body, apply Battlefield_Medicine
                            victim.addBody(1)
                            combatant.useChirurgeonsKit()

                            victim.broadcast(
                                f"|025{combatant.name} comes to {victim.name}'s rescue, healing {victim.name} for|n (|4301|n) |025body point.|n"
                            )
                            victim.message(
                                f"|540Your new body value is:|n {victim.body()}|n"
                            )
                        else:
                            victim.broadcast(
                                f"|025{combatant.name} tries to aid {victim.name} but they are not skilled enough to benefit them further.|n"
                            )
                            combatant.message(
                                f"|025You can help {victim.name} no more.|n")
                    elif victim.atMaxBleedPoints() and victim.hasBody(0):
                        # Check which skills get applied at 0 bleed and body
                        if combatant.battlefieldMedicine(
                        ) or combatant.stabilize() or combatant.medicine():
                            victim.broadcast(
                                f"|025{combatant.name} performs some minor healing techniques and provides|n (|4301|n) |025points of aid to {victim.name}.|n"
                            )
                            victim.addBody(1)
                            combatant.useChirurgeonsKit()
                        else:
                            victim.broadcast(
                                f"|025{combatant.name} tries to aid {victim.name} but with no training they are unable to help.|n"
                            )
                    elif victim.atMaxDeathPoints(
                    ) and not victim.atMaxBleedPoints():
                        if combatant.stabilize() or combatant.medicine():
                            amount_to_heal = combatant.medicine()
                            if combatant.stabilize() > combatant.medicine():
                                amount_to_heal = combatant.stabilize()

                            if amount_to_heal > victim.missingBleedPoints():
                                victim.setBody(1)
                                victim.resetBleedPoints()
                                combatant.useChirurgeonsKit()
                                combatant.broadcast(
                                    f"|025{combatant.name} performs some minor healing techniques and provides|n (|430{amount_to_heal}|n) |025points of aid to {victim.name}.  {victim.name} returns to the fight, but weakened|n"
                                )
                            else:
                                victim.addBleedPoints(combatant.medicine())
                                combatant.useChirurgeonsKit()
                                combatant.broadcast(
                                    f"|025{combatant.name} performs some minor healing techniques and provides|n (|430{amount_to_heal}|n) |025points of aid to {victim.name}.|n"
                                )
                        else:
                            combatant.message(
                                f"|400You are not skilled enough.|n")
                            victim.broadcast(
                                f"|025{combatant.name} tries to stop {victim.name} from bleeding, but is unable to|n"
                            )
                    elif victim.hasDeathPoints(1) or victim.hasDeathPoints(2):
                        if combatant.stabilize():
                            combatant.broadcast(
                                f"|025{combatant.name} performs advanced healing techniques and provides|n (|430{combatant.stabilize()}|n) |025 points of aid to {victim.name}.|n"
                            )
                            if combatant.stabilize(
                            ) > victim.missingDeathPoints():
                                remaining_healing = combatant.stabilize(
                                ) - victim.missingDeathPoints()
                                victim.setDeathPoints(3)
                                victim.addBleedPoints(remaining_healing)
                                combatant.useChirurgeonsKit()

                                combatant.message(
                                    f"|400You are able to stop {victim.name} from dying, but they are still bleeding out!|n"
                                )
                            else:
                                victim.addDeathPoints(combatant.stabilize())
                                combatant.useChirurgeonsKit()
                        else:
                            combatant.message(
                                f"|400{victim.name}'s injuries are beyond your skill as a healer.|n"
                            )
                            victim.broadcast(
                                f"|025{combatant.name} tries to stop {victim.name} from dying, but is unable to.|n"
                            )
                    else:
                        combatant.message(
                            f"{victim.name} |025is too fargone to administer further healing.|n"
                        )
                else:
                    combatant.message(
                        f"{victim.name} does not require the application of your healing skills.|n"
                    )
                    combatant.broadcast(
                        f"|025{combatant.name} tries to aid {victim.name} but they are uninjured!|n"
                    )
            else:
                combatant.message(
                    f"|400You are out of materials in your Chirurgeon's kit.|n"
                )
                combatant.broadcast(
                    f"|025{combatant.name} tries to aid {victim.name} but does not have the supplies to do so.|n"
                )

            # Clean up in combat loop
            if (combatant.caller in combatant.caller.location.db.combat_loop
                ) or (target in combatant.caller.location.db.combat_loop):
                loop.combatTurnOff(combatant.caller)
                loop.cleanup()
            else:
                return
        else:
            combatant.message(
                "|430You need to wait until it is your turn before you are able to act.|n"
            )
            return
Exemple #7
0
    def func(self):
        combatant = Combatant(self.caller)
        # Check for correct command
        # Target handling

        # Check for correct command
        # Target handling
        if not self.args:
            self.msg("|430Usage: shoot <target>|n")
            return
        elif self.args == self.caller:
            self.msg("|400You can't do that.|n")
            return
        elif combatant.cantFight:
            combatant.message("|400You are too injured to act.|n")
            return
        elif not combatant.inventory.hasArrowsEquipped:
            combatant.message("|430Please equip arrows to use your bow.|n")
            return
        elif not combatant.inventory.hasArrowsLeft:
            combatant.message("|400You are all out of arrows.|n")
            return

        # Check for and error handle designated target
        target = self.caller.search(self.target)

        # Pass all checks now execute command.
        # Use parsed args in combat loop. Handles turn order in combat.
        if not target:
            combatant.message("|430Please designate an appropriate target.|n")
            return

        if not target.db.bleed_points:
            combatant.message(
                f"{victim.name} |400is dead. You only further mutiliate their body.|n"
            )
            combatant.broadcast(
                f"{combatant.name} |025further mutilates the corpse of|n {victim.name}|025.|n"
            )
            return

        victim = combatant.getVictim(self.target)
        loop = CombatLoop(combatant.caller, combatant.target)
        loop.resolveCommand()

        if combatant.hasTurn(
                f"|430You need to wait until it is your turn before you are able to act.|n"
        ):
            if combatant.inventory.hasBow(
                    "|430You need to equip a bow before you are able to shoot, using the command equip <bow name>.|n"
            ):
                if victim.isAlive:
                    bow_penalty = 2
                    bow_damage = 1

                    attack_result = combatant.rollAttack(bow_penalty)
                    shot_location = combatant.determineHitLocation(victim)

                    if attack_result >= victim.av:
                        combatant.inventory.useArrows(1)

                        if not victim.blocksWithShield(shot_location):
                            # Get damage result and damage for weapon type
                            skip_av_damage = True
                            victim.takeDamage(combatant, combatant.getDamage(),
                                              shot_location, skip_av_damage)
                            combatant.broadcast(
                                f"{combatant.name} |025lets loose an arrow|n (|020{attack_result}|n)|025 straight for|n {victim.name}|025's {shot_location} and hits|n (|400{victim.av}|n), |025dealing|n (|430{bow_damage}|n) |025damage!|n"
                            )
                        else:
                            combatant.broadcast(
                                f"{combatant.name} |025lets loose an arrow|n (|020{attack_result}|n)|025 straight for|n {victim.name}'s |025{shot_location} and hits|n (|400{victim.av}|n)|025, but|n {victim.name} |025is able to raise their shield to block!|n"
                            )

                        combatant.message(
                            f"|430You have {combatant.inventory.arrowQuantity} arrows left."
                        )
                        # Clean up
                        # Set self.caller's combat_turn to 0. Can no longer use combat commands.
                        loop.combatTurnOff(self.caller)
                        loop.cleanup()

                else:
                    combatant.message(
                        f"{victim.name} |400is dead. You only further mutiliate their body.|n"
                    )
                    combatant.broadcast(
                        f"{combatant.name} |025further mutilates the corpse of|n {victim.name}|025.|n"
                    )
Exemple #8
0
    def func(self):
        combatant = Combatant(self.caller)

        # Check for correct command
        # Target handling
        if not self.args:
            self.msg("|430Usage: strike <target>|n")
            return
        elif self.args == self.caller:
            self.msg("|400You can't do that.|n")
            return
        elif combatant.cantFight:
            combatant.message("|400You are too injured to act.|n")
            return

        target = self.caller.search(self.target)

        # Pass all checks now execute command.
        # Use parsed args in combat loop. Handles turn order in combat.
        if not target:
            combatant.message("|430Please designate an appropriate target.|n")
            return

        victim = combatant.getVictim(self.target)

        if not target.db.bleed_points:
            combatant.message(
                f"{victim.name} |400is dead. You only further mutiliate their body.|n"
            )
            combatant.broadcast(
                f"{combatant.name} |025further mutilates the corpse of|n {victim.name}|025.|n"
            )
            return

        loop = CombatLoop(combatant.caller, combatant.target)
        loop.resolveCommand()

        if combatant.hasTurn(
                f"|430You need to wait until it is your turn before you are able to act.|n"
        ):
            if combatant.isArmed(
                    f"|430Before you strike you must equip a melee weapon using the command equip <weapon name>.|n"
            ):
                # Check if damage bonus comes from fayne or master_of_arms
                attack_result = combatant.rollAttack()
                shot_location = combatant.determineHitLocation(victim)

                if attack_result >= victim.av:
                    if not victim.blocksWithShield(shot_location):
                        # Get damage result and damage for weapon type
                        combatant.broadcast(
                            f"{combatant.name} |025strikes deftly|n (|020{attack_result}|n) |025at|n {victim.name} |025and hits|n (|400{victim.av}|n), |025dealing|n (|430{combatant.getDamage()}|n) |025damage!|n"
                        )
                        victim.takeDamage(combatant, combatant.getDamage(),
                                          shot_location)
                        victim.reportAv()
                    else:
                        combatant.broadcast(
                            f"{combatant.name} |025strikes deftly|n (|020{attack_result}|n) |025at|n {victim.name} |025and hits|n (|400{victim.av}|n), |025but|n {victim.name} |025blocks with their shield.|n"
                        )
                else:
                    combatant.broadcast(
                        f"{combatant.name} |025swings wildly|n (|400{attack_result}|n)|025, missing|n {victim.name} (|020{victim.av}|n)|025.|n"
                    )
                # Clean up
                # Set self.caller's combat_turn to 0. Can no longer use combat commands.
                loop.combatTurnOff(self.caller)
                loop.cleanup()
Exemple #9
0
    def func(self):
        combatant = Combatant(self.caller)

        # Check for correct command
        if not self.args:
            self.caller.msg("|430Usage: stun <target>|n")
            return

        if combatant.cantFight:
            combatant.message("|400You are too injured to act.|n")
            return

        # Get target if there is one
        # Check for and error handle designated target
        target = self.caller.search(self.target)

        # Pass all checks now execute command.
        # Use parsed args in combat loop. Handles turn order in combat.
        if not target:
            combatant.message("|430Please designate an appropriate target.|n")
            return

        victim = combatant.getVictim(self.target)

        if not target.db.bleed_points:
            combatant.message(
                f"{victim.name} |400is dead. You only further mutiliate their body.|n"
            )
            combatant.broadcast(
                f"{combatant.name} |025further mutilates the corpse of|n {victim.name}|025.|n"
            )
            return

        loop = CombatLoop(combatant.caller, combatant.target)
        loop.resolveCommand()

        #TODO: Currently Disarm does Damage and Stun doesnt.  Is that intended?
        if combatant.hasTurn(
                f"|430You need to wait until it is your turn before you are able to act.|n"
        ):
            if combatant.isArmed(
                    f"|430Before you attack you must equip a weapon using the command equip <weapon>.|n"
            ):
                if combatant.hasStunsRemaining(
                        f"|400You have 0 stuns remaining or do not have the skill.\nPlease choose another action.|n"
                ):
                    if not combatant.hasWeakness(
                            f"|400You are too weak to use this attack.|n"):
                        maneuver_difficulty = 1
                        attack_result = combatant.rollAttack(
                            maneuver_difficulty)
                        if attack_result >= victim.av:
                            victim.stun()
                            combatant.decreaseStuns(1)
                            combatant.broadcast(
                                f"{combatant.name} |025lines up behind|n {victim.name} |025and strikes|n (|020{attack_result}|n)|025, stunning them momentarily|n (|400{victim.av}|n)|025.|n"
                            )
                        else:
                            combatant.broadcast(
                                f"{combatant.name} (|020{attack_result}|n) |025lines up behind|n {victim.name} (|400{victim.av}|n)|025, but misses their opportunity to stun them.|n"
                            )

                        # Clean up
                        # Set self.caller's combat_turn to 0. Can no longer use combat commands.
                        loop.combatTurnOff(self.caller)
                        loop.cleanup()
Exemple #10
0
    def func(self):
        combatant = Combatant(self.caller)

        if not self.target:
            self.caller.msg("|430Usage: sunder <target>|n")
            return

        # Init combat helper class for logic
        h = Helper(self.caller)

        if not h.canFight(self.caller):
            self.caller.msg("|400You are too injured to act.|n")
            return

        # Check for and error handle designated target
        target = self.caller.search(self.target)

        victim = combatant.getVictim(self.target)

        if not target.db.bleed_points:
            combatant.message(
                f"{victim.name} |400is dead. You only further mutiliate their body.|n"
            )
            combatant.broadcast(
                f"{combatant.name} |025further mutilates the corpse of|n {victim.name}|025.|n"
            )
            return

        loop = CombatLoop(combatant.caller, combatant.target)
        loop.resolveCommand()

        # Run logic for cleave command
        if not self.caller.db.combat_turn:
            self.msg(
                "|430You need to wait until it is your turn before you are able to act.|n"
            )
            return

        combat_stats = h.getMeleeCombatStats(self.caller)
        target_stats = h.getMeleeCombatStats(target)

        # Confirm whether object carried is a two handed weapon
        right_hand_item = combat_stats.get("right_slot", '')
        rightObject = self.caller.search(right_hand_item)
        isTwoHanded = True if rightObject.db.twohanded else False

        left_hand_item = combat_stats.get("left_slot", '')
        sundersRemaining = self.caller.db.sunder

        if not isTwoHanded:
            self.msg(
                "|430Before you attack you must equip a two-handed weapon using the command equip <weapon name>.|n"
            )
            return

        if sundersRemaining <= 0:
            self.caller.msg(
                "|400You have 0 sunders remaining or do not have the skill.\nPlease choose another action.|n"
            )
            return

        die_result = h.fayneChecker(combat_stats.get("master_of_arms", 0),
                                    combat_stats.get("wylding_hand", 0))

        # Get damage result and damage for weapon type
        attack_result = (
            die_result + self.caller.db.weapon_level) - combat_stats.get(
                "dmg_penalty", 0) - combat_stats.get("weakness", 0)
        damage = 2 if combat_stats.get("two_handed", False) else 1
        target_av = target.db.av
        shot_location = h.shotFinder(target.db.targetArray)

        if attack_result >= target.db.av:
            # Check target left and right slots for items. Decrement material value from right and then left.
            # If no more items, subtract damage as normal.
            if target_stats.get("right_slot", ''):
                # Get item and material value for right slot.
                right_item = self.caller.search(target.db.right_slot[0],
                                                location=target)
                right_mv = right_item.db.material_value
                # Decrement one from material value.
                # Check to make sure it won't go below 0.
                if (right_mv - 1) <= 0:
                    right_item.db.material_value = 0
                    right_item.db.broken = True
                    # If two handed, remove from both slots
                    if right_item.db.twohanded:
                        target.db.left_slot.clear()
                    # Remove right slot
                    target.db.right_slot.remove(right_item)
                    self.caller.location.msg_contents(
                        f"{self.caller.key} |025strikes|n (|020{attack_result}|n) |025with great ferocity and sunders|n {target.key}|025's {right_item.key}|n (|400{target.db.av}|n)|025, breaking it.|n"
                    )
                else:
                    right_item.db.material_value -= 1
                    self.caller.location.msg_contents(
                        f"{self.caller.key} |025strikes|n (|020{attack_result}|n) |025with great ferocity and damages|n {target.key}|025's {right_item.key}|n (|400{target.db.av}|n)|025.|n"
                    )

            elif target_stats.get("left_slot", ''):
                # Get item and material value for right slot.
                left_item = self.caller.search(target.db.left_slot[0],
                                               location=target)
                left_mv = left_item.db.material_value
                # Decrement one from material value
                if (left_mv - 1) <= 0:
                    left_item.db.material_value = 0
                    left_item.db.broken = True
                    # if utils.inherits_from(target, Npc):
                    # target.db.skip_turn = 1
                    target.db.left_slot.remove(left_item)

                    self.caller.location.msg_contents(
                        f"{self.caller.key} |025strikes|n (|020{attack_result}|n) |025with great ferocity and sunders|n {target.key}|025's {left_item.key}|n (|400{target.db.av}|n)|025, breaking it.|n"
                    )
                else:
                    left_item.db.material_value -= 1
                    self.caller.location.msg_contents(
                        f"{self.caller.key} |025strikes|n (|020{attack_result}|n) |025with great ferocity and damages|n {target.key}|025's {left_item.key}|n (|400{target.db.av}|n)|025.|n"
                    )

            # Do damage resolution block
            elif target_av:
                # subtract damage from corresponding target stage (shield_value, armor, tough, body)
                new_av = h.damageSubtractor(damage, target, self.caller)
                # Update target av to new av score per damageSubtractor
                target.db.av = new_av
                self.caller.location.msg_contents(
                    f"{self.caller.key} |025strikes with great ferocity|n (|020{attack_result}|n) |025at|n {target.key} |025and hits|n (|400{target_av}|n), |025dealing|n |430{damage}|n |025damage!|n"
                )
                target.msg(
                    f"|430Your new total Armor Value is {new_av}:\nShield: {target.db.shield}\nArmor Specialist: {target.db.armor_specialist}\nArmor: {target.db.armor}\nTough: {target.db.tough}|n"
                )
            else:
                self.caller.location.msg_contents(
                    f"{self.caller.key} |025strikes with great ferocity|n (|020{attack_result}|n) |025at|n {target.key}|025's {shot_location} and hits|n (|400{target_av}|n), |025dealing|n |430{damage}|n |025damage!|n"
                )
                # First torso shot always takes body to 0. Does not pass excess damage to bleed points.
                if shot_location == "torso" and target.db.body > 0:
                    target.db.body = 0
                    self.caller.location.msg_contents(
                        f"{target.key} |025has been fatally wounded and is now bleeding to death. They will soon be unconscious.|n"
                    )
                else:
                    h.deathSubtractor(damage, target, self.caller)

            # Decrement amount of cleaves from amount in database
            self.caller.db.sunder -= 1
        else:
            self.caller.location.msg_contents(
                f"{self.caller.key} |025strikes a devastating blow at|n {target.key}|025, but misses.|n"
            )
            # Clean up
            # Set self.caller's combat_turn to 0. Can no longer use combat commands.
            loop.combatTurnOff(self.caller)

        loop.cleanup()