Correct spawner import in contrib

This commit is contained in:
Griatch 2018-08-12 15:06:16 +02:00
parent 9717b1b3b6
commit 5ec9fd4991

View file

@ -28,7 +28,7 @@ This module includes a number of example conditions:
Haste: +1 action per turn
Paralyzed: No actions per turn
Frightened: Character can't use the 'attack' command
Since conditions can have a wide variety of effects, their code is
scattered throughout the other functions wherever they may apply.
@ -70,7 +70,7 @@ from random import randint
from evennia import DefaultCharacter, Command, default_cmds, DefaultScript
from evennia.commands.default.muxcommand import MuxCommand
from evennia.commands.default.help import CmdHelp
from evennia.utils.spawner import spawn
from evennia.prototypes.spawner import spawn
from evennia import TICKER_HANDLER as tickerhandler
"""
@ -230,10 +230,10 @@ def apply_damage(defender, damage):
def at_defeat(defeated):
"""
Announces the defeat of a fighter in combat.
Args:
defeated (obj): Fighter that's been defeated.
Notes:
All this does is announce a defeat message by default, but if you
want anything else to happen to defeated fighters (like putting them
@ -250,7 +250,7 @@ def resolve_attack(attacker, defender, attack_value=None, defense_value=None,
Args:
attacker (obj): Character doing the attacking
defender (obj): Character being attacked
Options:
attack_value (int): Override for attack roll
defense_value (int): Override for defense value
@ -353,11 +353,11 @@ def spend_action(character, actions, action_name=None):
def spend_item_use(item, user):
"""
Spends one use on an item with limited uses.
Args:
item (obj): Item being used
user (obj): Character using the item
Notes:
If item.db.item_consumable is 'True', the item is destroyed if it
runs out of uses - if it's a string instead of 'True', it will also
@ -365,32 +365,32 @@ def spend_item_use(item, user):
as the name of the prototype to spawn.
"""
item.db.item_uses -= 1 # Spend one use
if item.db.item_uses > 0: # Has uses remaining
# Inform the player
user.msg("%s has %i uses remaining." % (item.key.capitalize(), item.db.item_uses))
else: # All uses spent
if not item.db.item_consumable: # Item isn't consumable
# Just inform the player that the uses are gone
user.msg("%s has no uses remaining." % item.key.capitalize())
else: # If item is consumable
if item.db.item_consumable == True: # If the value is 'True', just destroy the item
user.msg("%s has been consumed." % item.key.capitalize())
item.delete() # Delete the spent item
else: # If a string, use value of item_consumable to spawn an object in its place
residue = spawn({"prototype":item.db.item_consumable})[0] # Spawn the residue
residue.location = item.location # Move the residue to the same place as the item
user.msg("After using %s, you are left with %s." % (item, residue))
item.delete() # Delete the spent item
def use_item(user, item, target):
"""
Performs the action of using an item.
Args:
user (obj): Character using the item
item (obj): Item being used
@ -399,53 +399,53 @@ def use_item(user, item, target):
# If item is self only and no target given, set target to self.
if item.db.item_selfonly and target == None:
target = user
# If item is self only, abort use if used on others.
if item.db.item_selfonly and user != target:
user.msg("%s can only be used on yourself." % item)
return
# Set kwargs to pass to item_func
kwargs = {}
if item.db.item_kwargs:
kwargs = item.db.item_kwargs
if item.db.item_kwargs:
kwargs = item.db.item_kwargs
# Match item_func string to function
try:
item_func = ITEMFUNCS[item.db.item_func]
except KeyError: # If item_func string doesn't match to a function in ITEMFUNCS
user.msg("ERROR: %s not defined in ITEMFUNCS" % item.db.item_func)
return
# Call the item function - abort if it returns False, indicating an error.
# This performs the actual action of using the item.
# Regardless of what the function returns (if anything), it's still executed.
if item_func(item, user, target, **kwargs) == False:
return
# If we haven't returned yet, we assume the item was used successfully.
# Spend one use if item has limited uses
if item.db.item_uses:
spend_item_use(item, user)
# Spend an action if in combat
if is_in_combat(user):
spend_action(user, 1, action_name="item")
def condition_tickdown(character, turnchar):
"""
Ticks down the duration of conditions on a character at the start of a given character's turn.
Args:
character (obj): Character to tick down the conditions of
turnchar (obj): Character whose turn it currently is
Notes:
In combat, this is called on every fighter at the start of every character's turn. Out of
combat, it's instead called when a character's at_update() hook is called, which is every
30 seconds by default.
"""
for key in character.db.conditions:
# The first value is the remaining turns - the second value is whose turn to count down on.
condition_duration = character.db.conditions[key][0]
@ -459,11 +459,11 @@ def condition_tickdown(character, turnchar):
# If the duration is brought down to 0, remove the condition and inform everyone.
character.location.msg_contents("%s no longer has the '%s' condition." % (str(character), str(key)))
del character.db.conditions[key]
def add_condition(character, turnchar, condition, duration):
"""
Adds a condition to a fighter.
Args:
character (obj): Character to give the condition to
turnchar (obj): Character whose turn to tick down the condition on in combat
@ -501,7 +501,7 @@ class TBItemsCharacter(DefaultCharacter):
"""
Adds attributes for a character's current and maximum HP.
We're just going to set this value at '100' by default.
An empty dictionary is created to store conditions later,
and the character is subscribed to the Ticker Handler, which
will call at_update() on the character, with the interval
@ -536,17 +536,17 @@ class TBItemsCharacter(DefaultCharacter):
self.msg("You can't move, you've been defeated!")
return False
return True
def at_turn_start(self):
"""
Hook called at the beginning of this character's turn in combat.
"""
# Prompt the character for their turn and give some information.
self.msg("|wIt's your turn! You have %i HP remaining.|n" % self.db.hp)
# Apply conditions that fire at the start of each turn.
self.apply_turn_conditions()
def apply_turn_conditions(self):
"""
Applies the effect of conditions that occur at the start of each
@ -559,7 +559,7 @@ class TBItemsCharacter(DefaultCharacter):
to_heal = self.db.max_hp - self.db.hp # Cap healing to max HP
self.db.hp += to_heal
self.location.msg_contents("%s regains %i HP from Regeneration." % (self, to_heal))
# Poisoned: does 4 to 8 damage at the start of character's turn
if "Poisoned" in self.db.conditions:
to_hurt = randint(POISON_RATE[0], POISON_RATE[1]) # Deal damage
@ -568,18 +568,18 @@ class TBItemsCharacter(DefaultCharacter):
if self.db.hp <= 0:
# Call at_defeat if poison defeats the character
at_defeat(self)
# Haste: Gain an extra action in combat.
if is_in_combat(self) and "Haste" in self.db.conditions:
self.db.combat_actionsleft += 1
self.msg("You gain an extra action this turn from Haste!")
# Paralyzed: Have no actions in combat.
if is_in_combat(self) and "Paralyzed" in self.db.conditions:
self.db.combat_actionsleft = 0
self.location.msg_contents("%s is Paralyzed, and can't act this turn!" % self)
self.db.combat_turnhandler.turn_end_check(self)
def at_update(self):
"""
Fires every 30 seconds.
@ -602,7 +602,7 @@ class TBItemsCharacterTest(TBItemsCharacter):
self.db.max_hp = 100 # Set maximum HP to 100
self.db.hp = self.db.max_hp # Set current HP to maximum
self.db.conditions = {} # Set empty dict for conditions
"""
----------------------------------------------------------------------------
@ -651,7 +651,7 @@ class TBItemsTurnHandler(DefaultScript):
# Announce the turn order.
self.obj.msg_contents("Turn order is: %s " % ", ".join(obj.key for obj in self.db.fighters))
# Start first fighter's turn.
self.start_turn(self.db.fighters[0])
@ -748,14 +748,14 @@ class TBItemsTurnHandler(DefaultScript):
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 = TURN_TIMEOUT + 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.
# Count down condition timers.
for fighter in self.db.fighters:
condition_tickdown(fighter, newchar)
@ -785,7 +785,7 @@ class TBItemsTurnHandler(DefaultScript):
# Initialize the character like you do at the start.
self.initialize_for_combat(character)
"""
----------------------------------------------------------------------------
COMMANDS START HERE
@ -865,7 +865,7 @@ class CmdAttack(Command):
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
if "Frightened" in self.caller.db.conditions: # Can't attack if frightened
self.caller.msg("You're too frightened to attack!")
return
@ -1033,29 +1033,29 @@ class CmdUse(MuxCommand):
item = self.caller.search(self.lhs, candidates=self.caller.contents)
if not item:
return
# Search for target, if any is given
target = None
if self.rhs:
target = self.caller.search(self.rhs)
if not target:
return
# If in combat, can only use items on your turn
if is_in_combat(self.caller):
if not is_turn(self.caller):
self.caller.msg("You can only use items on your turn.")
return
if not item.db.item_func: # Object has no item_func, not usable
self.caller.msg("'%s' is not a usable item." % item.key.capitalize())
return
if item.attributes.has("item_uses"): # Item has limited uses
if item.db.item_uses <= 0: # Limited uses are spent
self.caller.msg("'%s' has no uses remaining." % item.key.capitalize())
return
# If everything checks out, call the use_item function
use_item(self.caller, item, target)
@ -1077,7 +1077,7 @@ class BattleCmdSet(default_cmds.CharacterCmdSet):
self.add(CmdDisengage())
self.add(CmdCombatHelp())
self.add(CmdUse())
"""
----------------------------------------------------------------------------
ITEM FUNCTIONS START HERE
@ -1091,7 +1091,7 @@ Every item function must take the following arguments:
item (obj): The item being used
user (obj): The character using the item
target (obj): The target of the item use
Item functions must also accept **kwargs - these keyword arguments can be
used to define how different items that use the same function can have
different effects (for example, different attack items doing different
@ -1104,25 +1104,25 @@ take and the effect they have on the result.
def itemfunc_heal(item, user, target, **kwargs):
"""
Item function that heals HP.
kwargs:
min_healing(int): Minimum amount of HP recovered
max_healing(int): Maximum amount of HP recovered
"""
if not target:
if not target:
target = user # Target user if none specified
if not target.attributes.has("max_hp"): # Has no HP to speak of
user.msg("You can't use %s on that." % item)
return False # Returning false aborts the item use
if target.db.hp >= target.db.max_hp:
user.msg("%s is already at full health." % target)
return False
min_healing = 20
max_healing = 40
# Retrieve healing range from kwargs, if present
if "healing_range" in kwargs:
min_healing = kwargs["healing_range"][0]
@ -1132,62 +1132,62 @@ def itemfunc_heal(item, user, target, **kwargs):
if target.db.hp + to_heal > target.db.max_hp:
to_heal = target.db.max_hp - target.db.hp # Cap healing to max HP
target.db.hp += to_heal
user.location.msg_contents("%s uses %s! %s regains %i HP!" % (user, item, target, to_heal))
def itemfunc_add_condition(item, user, target, **kwargs):
"""
Item function that gives the target one or more conditions.
kwargs:
conditions (list): Conditions added by the item
formatted as a list of tuples: (condition (str), duration (int or True))
Notes:
Should mostly be used for beneficial conditions - use itemfunc_attack
for an item that can give an enemy a harmful condition.
"""
conditions = [("Regeneration", 5)]
if not target:
if not target:
target = user # Target user if none specified
if not target.attributes.has("max_hp"): # Is not a fighter
user.msg("You can't use %s on that." % item)
return False # Returning false aborts the item use
# Retrieve condition / duration from kwargs, if present
if "conditions" in kwargs:
conditions = kwargs["conditions"]
user.location.msg_contents("%s uses %s!" % (user, item))
# Add conditions to the target
for condition in conditions:
for condition in conditions:
add_condition(target, user, condition[0], condition[1])
def itemfunc_cure_condition(item, user, target, **kwargs):
"""
Item function that'll remove given conditions from a target.
kwargs:
to_cure(list): List of conditions (str) that the item cures when used
"""
to_cure = ["Poisoned"]
if not target:
if not target:
target = user # Target user if none specified
if not target.attributes.has("max_hp"): # Is not a fighter
user.msg("You can't use %s on that." % item)
return False # Returning false aborts the item use
# Retrieve condition(s) to cure from kwargs, if present
if "to_cure" in kwargs:
to_cure = kwargs["to_cure"]
item_msg = "%s uses %s! " % (user, item)
for key in target.db.conditions:
if key in to_cure:
# If condition specified in to_cure, remove it.
@ -1195,11 +1195,11 @@ def itemfunc_cure_condition(item, user, target, **kwargs):
del target.db.conditions[key]
user.location.msg_contents(item_msg)
def itemfunc_attack(item, user, target, **kwargs):
"""
Item function that attacks a target.
kwargs:
min_damage(int): Minimum damage dealt by the attack
max_damage(int): Maximum damage dealth by the attack
@ -1207,31 +1207,31 @@ def itemfunc_attack(item, user, target, **kwargs):
inflict_condition(list): List of conditions inflicted on hit,
formatted as a (str, int) tuple containing condition name
and duration.
Notes:
Calls resolve_attack at the end.
"""
if not is_in_combat(user):
user.msg("You can only use that in combat.")
return False # Returning false aborts the item use
if not target:
if not target:
user.msg("You have to specify a target to use %s! (use <item> = <target>)" % item)
return False
if target == user:
user.msg("You can't attack yourself!")
return False
return False
if not target.db.hp: # Has no HP
user.msg("You can't use %s on that." % item)
return False
min_damage = 20
max_damage = 40
accuracy = 0
inflict_condition = []
# Retrieve values from kwargs, if present
if "damage_range" in kwargs:
min_damage = kwargs["damage_range"][0]
@ -1240,17 +1240,17 @@ def itemfunc_attack(item, user, target, **kwargs):
accuracy = kwargs["accuracy"]
if "inflict_condition" in kwargs:
inflict_condition = kwargs["inflict_condition"]
# Roll attack and damage
attack_value = randint(1, 100) + accuracy
damage_value = randint(min_damage, max_damage)
# Account for "Accuracy Up" and "Accuracy Down" conditions
if "Accuracy Up" in user.db.conditions:
attack_value += 25
if "Accuracy Down" in user.db.conditions:
attack_value -= 25
user.location.msg_contents("%s attacks %s with %s!" % (user, target, item))
resolve_attack(user, target, attack_value=attack_value,
damage_value=damage_value, inflict_condition=inflict_condition)
@ -1283,14 +1283,14 @@ Only "item_func" is required, but item behavior can be further modified by
specifying any of the following:
item_uses (int): If defined, item has a limited number of uses
item_selfonly (bool): If True, user can only use the item on themself
item_consumable(True or str): If True, item is destroyed when it runs
out of uses. If a string is given, the item will spawn a new
object as it's destroyed, with the string specifying what prototype
to spawn.
item_kwargs (dict): Keyword arguments to pass to the function defined in
item_func. Unique to each function, and can be used to make multiple
items using the same function work differently.