Some minor adjustments for pep8.

This commit is contained in:
Griatch 2017-04-08 19:28:29 +02:00
parent 005923ee72
commit 59f491eab4

View file

@ -51,6 +51,8 @@ from evennia.commands.default.help import CmdHelp
COMBAT FUNCTIONS START HERE
----------------------------------------------------------------------------
"""
def roll_init(character):
"""
Rolls a number between 1-1000 to determine initiative.
@ -75,7 +77,8 @@ def roll_init(character):
This way, characters with a higher dexterity will go first more often.
"""
return randint(1,1000)
return randint(1, 1000)
def get_attack(attacker, defender):
"""
@ -101,6 +104,7 @@ def get_attack(attacker, defender):
attack_value = randint(1, 100)
return attack_value
def get_defense(attacker, defender):
"""
Returns a value for defense, which an attack roll must equal or exceed in order
@ -124,6 +128,7 @@ def get_defense(attacker, defender):
defense_value = 50
return defense_value
def get_damage(attacker, defender):
"""
Returns a value for damage to be deducted from the defender's HP after abilities
@ -147,6 +152,7 @@ def get_damage(attacker, defender):
damage_value = randint(15, 25)
return damage_value
def apply_damage(defender, damage):
"""
Applies damage to a target, reducing their HP by the damage amount to a
@ -156,11 +162,12 @@ def apply_damage(defender, damage):
defender (obj): Character taking damage
damage (int): Amount of damage being taken
"""
defender.db.hp -= damage # Reduce defender's HP by the damage dealt.
defender.db.hp -= damage # Reduce defender's HP by the damage dealt.
# If this reduces it to 0 or less, set HP to 0.
if defender.db.hp <= 0:
defender.db.hp = 0
def resolve_attack(attacker, defender, attack_value=None, defense_value=None):
"""
Resolves an attack and outputs the result.
@ -184,14 +191,15 @@ def resolve_attack(attacker, defender, attack_value=None, defense_value=None):
if attack_value < defense_value:
attacker.location.msg_contents("%s's attack misses %s!" % (attacker, defender))
else:
damage_value = get_damage(attacker, defender) # Calculate damage value.
damage_value = get_damage(attacker, defender) # Calculate damage value.
# Announce damage dealt and apply damage.
attacker.location.msg_contents("%s hits %s for %i damage!" % (attacker, defender, damage_value))
apply_damage (defender, damage_value)
apply_damage(defender, damage_value)
# If defender HP is reduced to 0 or less, announce defeat.
if defender.db.hp <= 0:
attacker.location.msg_contents("%s has been defeated!" % defender)
def combat_cleanup(character):
"""
Cleans up all the temporary combat-related attributes on a character.
@ -204,8 +212,9 @@ def combat_cleanup(character):
longer needed once a fight ends.
"""
for attr in character.attributes.all():
if attr.key[:7] == "combat_": # If the attribute name starts with 'combat_'...
character.attributes.remove(key=attr.key) # ...then delete it!
if attr.key[:7] == "combat_": # If the attribute name starts with 'combat_'...
character.attributes.remove(key=attr.key) # ...then delete it!
def is_in_combat(character):
"""
@ -221,6 +230,7 @@ def is_in_combat(character):
return True
return False
def is_turn(character):
"""
Returns true if it's currently the given character's turn in combat.
@ -237,6 +247,7 @@ def is_turn(character):
return True
return False
def spend_action(character, actions, action_name=None):
"""
Spends a character's available combat actions and checks for end of turn.
@ -251,13 +262,13 @@ def spend_action(character, actions, action_name=None):
"""
if action_name:
character.db.Combat_LastAction = action_name
if actions == 'all': # If spending all actions
character.db.Combat_ActionsLeft = 0 # Set actions to 0
if actions == 'all': # If spending all actions
character.db.Combat_ActionsLeft = 0 # Set actions to 0
else:
character.db.Combat_ActionsLeft -= actions # Use up actions.
character.db.Combat_ActionsLeft -= actions # Use up actions.
if character.db.Combat_ActionsLeft < 0:
character.db.Combat_ActionsLeft = 0 # Can't have fewer than 0 actions
character.db.Combat_TurnHandler.turn_end_check(character) # Signal potential end of turn.
character.db.Combat_ActionsLeft = 0 # Can't have fewer than 0 actions
character.db.Combat_TurnHandler.turn_end_check(character) # Signal potential end of turn.
"""
@ -266,6 +277,7 @@ CHARACTER TYPECLASS
----------------------------------------------------------------------------
"""
class BattleCharacter(DefaultCharacter):
"""
A character able to participate in turn-based combat. Has attributes for current
@ -277,8 +289,8 @@ class BattleCharacter(DefaultCharacter):
Called once, when this object is first created. This is the
normal hook to overload for most object types.
"""
self.db.max_hp = 100 # Set maximum HP to 100
self.db.hp = self.db.max_hp # Set current HP to maximum
self.db.max_hp = 100 # Set maximum HP to 100
self.db.hp = self.db.max_hp # Set current HP to maximum
"""
Adds attributes for a character's current and maximum HP.
We're just going to set this value at '100' by default.
@ -286,6 +298,7 @@ class BattleCharacter(DefaultCharacter):
You may want to expand this to include various 'stats' that
can be changed at creation and factor into combat calculations.
"""
def at_before_move(self, destination):
"""
Called just before starting to move this object to
@ -305,17 +318,20 @@ class BattleCharacter(DefaultCharacter):
# Keep the character from moving if at 0 HP or in combat.
if is_in_combat(self):
self.msg("You can't exit a room while in combat!")
return False # Returning false keeps the character from moving.
return False # Returning false keeps the character from moving.
if self.db.HP <= 0:
self.msg("You can't move, you've been defeated!")
return False
return True
"""
----------------------------------------------------------------------------
COMMANDS START HERE
----------------------------------------------------------------------------
"""
class CmdFight(Command):
"""
Starts a fight with everyone in the same room as you.
@ -337,26 +353,28 @@ class CmdFight(Command):
here = self.caller.location
fighters = []
if not self.caller.db.hp: # If you don't have any hp
if not self.caller.db.hp: # If you don't have any hp
self.caller.msg("You can't start a fight if you've been defeated!")
return
if is_in_combat(self.caller): # Already in a fight
if is_in_combat(self.caller): # Already in a fight
self.caller.msg("You're already in a fight!")
return
for thing in here.contents: # Test everything in the room to add it to the fight.
if thing.db.HP: # If the object has HP...
fighters.append(thing) # ...then add it to the fight.
if len(fighters) <= 1: # If you're the only able fighter in the room
for thing in here.contents: # Test everything in the room to add it to the fight.
if thing.db.HP: # If the object has HP...
fighters.append(thing) # ...then add it to the fight.
if len(fighters) <= 1: # If you're the only able fighter in the room
self.caller.msg("There's nobody here to fight!")
return
if here.db.Combat_TurnHandler: # If there's already a fight going on...
if here.db.Combat_TurnHandler: # If there's already a fight going on...
here.msg_contents("%s joins the fight!" % self.caller)
here.db.Combat_TurnHandler.join_fight(self.caller) # Join the fight!
here.db.Combat_TurnHandler.join_fight(self.caller) # Join the fight!
return
here.msg_contents("%s starts a fight!" % self.caller)
here.scripts.add("contrib.turnbattle.TurnHandler") # Add a turn handler script to the room, which starts combat.
# Add a turn handler script to the room, which starts combat.
here.scripts.add("contrib.turnbattle.TurnHandler")
# Remember you'll have to change the path to the script if you copy this code to your own modules!
class CmdAttack(Command):
"""
Attacks another character.
@ -375,35 +393,36 @@ class CmdAttack(Command):
"This performs the actual command."
"Set the attacker to the caller and the defender to the target."
if not is_in_combat(self.caller): # If not in combat, can't attack.
if not is_in_combat(self.caller): # If not in combat, can't attack.
self.caller.msg("You can only do that in combat. (see: help fight)")
return
if not is_turn(self.caller): # If it's not your turn, can't attack.
if not is_turn(self.caller): # If it's not your turn, can't attack.
self.caller.msg("You can only do that on your turn.")
return
if not self.caller.db.hp: # Can't attack if you have no HP.
if not self.caller.db.hp: # Can't attack if you have no HP.
self.caller.msg("You can't attack, you've been defeated.")
return
attacker = self.caller
defender = self.caller.search(self.args)
if not defender: # No valid target given.
if not defender: # No valid target given.
return
if not defender.db.hp: # Target object has no HP left or to begin with
if not defender.db.hp: # Target object has no HP left or to begin with
self.caller.msg("You can't fight that!")
return
if attacker == defender: # Target and attacker are the same
if attacker == defender: # Target and attacker are the same
self.caller.msg("You can't attack yourself!")
return
"If everything checks out, call the attack resolving function."
resolve_attack(attacker, defender)
spend_action(self.caller, 1, action_name="attack") # Use up one action.
spend_action(self.caller, 1, action_name="attack") # Use up one action.
class CmdPass(Command):
"""
@ -424,16 +443,17 @@ class CmdPass(Command):
"""
This performs the actual command.
"""
if not is_in_combat(self.caller): # Can only pass a turn in combat.
if not is_in_combat(self.caller): # Can only pass a turn in combat.
self.caller.msg("You can only do that in combat. (see: help fight)")
return
if not is_turn(self.caller): # Can only pass if it's your turn.
if not is_turn(self.caller): # Can only pass if it's your turn.
self.caller.msg("You can only do that on your turn.")
return
self.caller.location.msg_contents("%s takes no further action, passing the turn." % self.caller)
spend_action(self.caller, 'all', action_name="pass") # Spend all remaining actions.
spend_action(self.caller, 'all', action_name="pass") # Spend all remaining actions.
class CmdDisengage(Command):
"""
@ -455,21 +475,22 @@ class CmdDisengage(Command):
"""
This performs the actual command.
"""
if not is_in_combat(self.caller): # If you're not in combat
if not is_in_combat(self.caller): # If you're not in combat
self.caller.msg("You can only do that in combat. (see: help fight)")
return
if not is_turn(self.caller): # If it's not your turn
if not is_turn(self.caller): # If it's not your turn
self.caller.msg("You can only do that on your turn.")
return
self.caller.location.msg_contents("%s disengages, ready to stop fighting." % self.caller)
spend_action(self.caller, 'all', action_name="disengage") # Spend all remaining actions.
spend_action(self.caller, 'all', action_name="disengage") # Spend all remaining actions.
"""
The action_name kwarg sets the character's last action to "disengage", which is checked by
the turn handler script to see if all fighters have disengaged.
"""
class CmdRest(Command):
"""
Recovers damage.
@ -487,16 +508,17 @@ class CmdRest(Command):
def func(self):
"This performs the actual command."
if is_in_combat(self.caller): # If you're in combat
if is_in_combat(self.caller): # If you're in combat
self.caller.msg("You can't rest while you're in combat.")
return
self.caller.db.hp = self.caller.db.max_hp # Set current HP to maximum
self.caller.db.hp = self.caller.db.max_hp # Set current HP to maximum
self.caller.location.msg_contents("%s rests to recover HP." % self.caller)
"""
You'll probably want to replace this with your own system for recovering HP.
"""
class CmdCombatHelp(CmdHelp):
"""
View help or a list of topics
@ -513,13 +535,14 @@ class CmdCombatHelp(CmdHelp):
# tips on combat when used in a fight with no arguments.
def func(self):
if is_in_combat(self.caller) and not self.args: # In combat and entered 'help' alone
self.caller.msg("Available combat commands:|/"+
"|wAttack:|n Attack a target, attempting to deal damage.|/"+
"|wPass:|n Pass your turn without further action.|/"+
"|wDisengage:|n End your turn and attempt to end combat.|/")
if is_in_combat(self.caller) and not self.args: # In combat and entered 'help' alone
self.caller.msg("Available combat commands:|/" +
"|wAttack:|n Attack a target, attempting to deal damage.|/" +
"|wPass:|n Pass your turn without further action.|/" +
"|wDisengage:|n End your turn and attempt to end combat.|/")
else:
super(CmdCombatHelp, self).func() # Call the default help command
super(CmdCombatHelp, self).func() # Call the default help command
class BattleCmdSet(default_cmds.CharacterCmdSet):
"""
@ -538,12 +561,14 @@ class BattleCmdSet(default_cmds.CharacterCmdSet):
self.add(CmdDisengage())
self.add(CmdCombatHelp())
"""
----------------------------------------------------------------------------
SCRIPTS START HERE
----------------------------------------------------------------------------
"""
class TurnHandler(DefaultScript):
"""
This is the script that handles the progression of combat through turns.
@ -561,7 +586,7 @@ class TurnHandler(DefaultScript):
Called once, when the script is created.
"""
self.key = "Combat Turn Handler"
self.interval = 5 # Once every 5 seconds
self.interval = 5 # Once every 5 seconds
self.persistent = True
self.db.fighters = []
@ -585,36 +610,35 @@ class TurnHandler(DefaultScript):
# Announce the turn order.
self.obj.msg_contents("Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters))
#Set up the current turn and turn timeout delay.
# Set up the current turn and turn timeout delay.
self.db.turn = 0
self.db.timer = 30 # 30 seconds
self.db.timer = 30 # 30 seconds
def at_stop(self):
"""
Called at script termination.
"""
for fighter in self.db.fighters:
combat_cleanup(fighter) #Clean up the combat attributes for every fighter.
self.obj.db.Combat_TurnHandler = None # Remove reference to turn handler in location
combat_cleanup(fighter) # Clean up the combat attributes for every fighter.
self.obj.db.Combat_TurnHandler = None # Remove reference to turn handler in location
def at_repeat(self):
"""
Called once every self.interval seconds.
"""
currentchar = self.db.fighters[self.db.turn] # Note the current character in the turn order.
self.db.timer -= self.interval # Count down the timer.
currentchar = self.db.fighters[self.db.turn] # Note the current character in the turn order.
self.db.timer -= self.interval # Count down the timer.
if self.db.timer <= 0:
# Force current character to disengage if timer runs out.
self.obj.msg_contents("%s's turn timed out!" % currentchar)
spend_action(currentchar, 'all', action_name="disengage") # Spend all remaining actions.
spend_action(currentchar, 'all', action_name="disengage") # Spend all remaining actions.
return
elif self.db.timer <= 10 and not self.db.timeout_warning_given: # 10 seconds left
elif self.db.timer <= 10 and not self.db.timeout_warning_given: # 10 seconds left
# Warn the current character if they're about to time out.
currentchar.msg("WARNING: About to time out!")
self.db.timeout_warning_given = True
def initialize_for_combat(self, character):
"""
Prepares a character for combat when starting or entering a fight.
@ -622,10 +646,10 @@ class TurnHandler(DefaultScript):
Args:
character (obj): Character to initialize for combat.
"""
combat_cleanup(character) # Clean up leftover combat attributes beforehand, just in case.
character.db.Combat_ActionsLeft = 0 # Actions remaining - start of turn adds to this, turn ends when it reaches 0
character.db.Combat_TurnHandler = self # Add a reference to this turn handler script to the character
character.db.Combat_LastAction = "null" # Track last action taken in combat
combat_cleanup(character) # Clean up leftover combat attributes beforehand, just in case.
character.db.Combat_ActionsLeft = 0 # Actions remaining - start of turn adds to this, turn ends when it reaches 0
character.db.Combat_TurnHandler = self # Add a reference to this turn handler script to the character
character.db.Combat_LastAction = "null" # Track last action taken in combat
def start_turn(self, character):
"""
@ -642,7 +666,7 @@ class TurnHandler(DefaultScript):
separated for movement, by adding "character.db.Combat_MovesLeft = 3" or
something similar.
"""
character.db.Combat_ActionsLeft = 1 # 1 action per turn.
character.db.Combat_ActionsLeft = 1 # 1 action per turn.
# Prompt the character for their turn and give some information.
character.msg("|wIt's your turn! You have %i HP remaining.|n" % character.db.hp)
@ -654,37 +678,36 @@ class TurnHandler(DefaultScript):
# Check to see if every character disengaged as their last action. If so, end combat.
disengage_check = True
for fighter in self.db.fighters:
if fighter.db.Combat_LastAction != "disengage": # If a character has done anything but disengage
if fighter.db.Combat_LastAction != "disengage": # If a character has done anything but disengage
disengage_check = False
if disengage_check == True: # All characters have disengaged
if disengage_check: # All characters have disengaged
self.obj.msg_contents("All fighters have disengaged! Combat is over!")
self.stop() # Stop this script and end combat.
self.stop() # Stop this script and end combat.
return
# Check to see if only one character is left standing. If so, end combat.
defeated_characters = 0
for fighter in self.db.fighters:
if fighter.db.HP == 0:
defeated_characters += 1 # Add 1 for every fighter with 0 HP left (defeated)
if defeated_characters == (len(self.db.fighters) - 1): # If only one character isn't defeated
defeated_characters += 1 # Add 1 for every fighter with 0 HP left (defeated)
if defeated_characters == (len(self.db.fighters) - 1): # If only one character isn't defeated
for fighter in self.db.fighters:
if fighter.db.HP != 0:
LastStanding = fighter # Pick the one fighter left with HP remaining
LastStanding = fighter # Pick the one fighter left with HP remaining
self.obj.msg_contents("Only %s remains! Combat is over!" % LastStanding)
self.stop() # Stop this script and end combat.
self.stop() # Stop this script and end combat.
return
# Cycle to the next turn.
currentchar = self.db.fighters[self.db.turn]
self.db.turn += 1 # Go to the next in the turn order.
self.db.turn += 1 # Go to the next in the turn order.
if self.db.turn > len(self.db.fighters) - 1:
self.db.turn = 0 # Go back to the first in the turn order once you reach the end.
newchar = self.db.fighters[self.db.turn] # Note the new character
self.db.timer = 30 + self.time_until_next_repeat() # Reset the timer.
self.db.timeout_warning_given = False # Reset the timeout warning.
self.db.turn = 0 # Go back to the first in the turn order once you reach the end.
newchar = self.db.fighters[self.db.turn] # Note the new character
self.db.timer = 30 + self.time_until_next_repeat() # Reset the timer.
self.db.timeout_warning_given = False # Reset the timeout warning.
self.obj.msg_contents("%s's turn ends - %s's turn begins!" % (currentchar, newchar))
self.start_turn(newchar) # Start the new character's turn.
self.start_turn(newchar) # Start the new character's turn.
def turn_end_check(self, character):
"""
@ -693,7 +716,7 @@ class TurnHandler(DefaultScript):
Args:
character (obj): Character to test for end of turn
"""
if not character.db.Combat_ActionsLeft: # Character has no actions remaining
if not character.db.Combat_ActionsLeft: # Character has no actions remaining
self.next_turn()
return