Create a friendly pet
This commit is contained in:
parent
c731383915
commit
43956fa818
1 changed files with 240 additions and 1 deletions
|
|
@ -1,4 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
# Emacs environement
|
||||
# (setq python-shell-interpreter "/Users/howard/src/moss-n-puddles/.venv/bin/ipython")
|
||||
"""
|
||||
Pets
|
||||
|
||||
|
|
@ -194,5 +196,242 @@ class Fire(Pet):
|
|||
|
||||
# def at_post_move(self, source_location, move_type, **kwargs):
|
||||
|
||||
self.update_hunger(feeder=feeder, amount=300)
|
||||
# ----------------------------------------------------------------------
|
||||
# Friendly
|
||||
|
||||
|
||||
class Reaction(Enum):
|
||||
SCARED = 1
|
||||
CONCERNED = 100
|
||||
INTERESTED = 300
|
||||
FRIENDLY = 850
|
||||
ECSTATIC = 1000
|
||||
|
||||
|
||||
class Friendly(Pet):
|
||||
"""
|
||||
This pet keeps track of the characters in the game.
|
||||
It has different reactions based on the characters in the room.
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
Called when object is first created.
|
||||
"""
|
||||
super().at_object_creation()
|
||||
|
||||
# The higher this value the more "spammy" a pet is in making
|
||||
# comments in the room:
|
||||
self.db.active_amount = 3
|
||||
|
||||
# If set to 'ignores', the pet is more concerned about the
|
||||
# 'friendliest' character in Room, otherwise, it is more
|
||||
# scared at the stranger:
|
||||
self.db.new_character_reaction = "ignores"
|
||||
|
||||
@property
|
||||
def friendly_var(self):
|
||||
"""
|
||||
Return variable name on character types use to gauge the
|
||||
reaction of this pet towards that character.
|
||||
"""
|
||||
key = self.key.replace(" ", "_")
|
||||
return f"{key}_friendly_level"
|
||||
|
||||
def friendly_level(self, character):
|
||||
"""
|
||||
Return reaction level of this pet towards a character.
|
||||
"""
|
||||
varname = self.friendly_var
|
||||
return character.attributes.get(varname) or 0
|
||||
|
||||
def friendly_reaction(self, character=None):
|
||||
"""
|
||||
Return reaction enum of this pet towards a character.
|
||||
If character not given, then looks at all characters in the room
|
||||
"""
|
||||
if character:
|
||||
level = self.friendly_level(character)
|
||||
if level < Reaction.SCARED.value:
|
||||
return Reaction.SCARED
|
||||
if level < Reaction.CONCERNED.value:
|
||||
return Reaction.CONCERNED
|
||||
if level < Reaction.INTERESTED.value:
|
||||
return Reaction.INTERESTED
|
||||
if level < Reaction.FRIENDLY.value:
|
||||
return Reaction.FRIENDLY
|
||||
return Reaction.ECSTATIC
|
||||
else:
|
||||
if self.db.new_character_reaction == "ignores":
|
||||
return self.highest_friendly_reaction()
|
||||
return self.lowest_friendly_reaction()
|
||||
|
||||
@property
|
||||
def local_characters(self):
|
||||
"""
|
||||
Return a list of all Characters in the room with the Pet.
|
||||
"""
|
||||
return [c for c in self.location.contents
|
||||
if c.is_typeclass("typeclasses.characters.Character")]
|
||||
|
||||
def lowest_friendly_reaction(self):
|
||||
"""
|
||||
Return reaction of this pet to the least friendliest
|
||||
character(s) in the area (room) that this pet resides.
|
||||
Returns a tuple, Reaction and a list of characters.
|
||||
"""
|
||||
# State is a tuple of the level and the character:
|
||||
level = Reaction.ECSTATIC
|
||||
characters = []
|
||||
|
||||
for c in self.local_characters:
|
||||
this_level = self.friendly_reaction(c)
|
||||
if this_level.value < level.value:
|
||||
level = this_level
|
||||
characters = [c]
|
||||
if this_level.value == level.value:
|
||||
characters += [c]
|
||||
return (level, characters)
|
||||
|
||||
def highest_friendly_reaction(self):
|
||||
"""
|
||||
Return reaction of this pet to the friendliest
|
||||
character(s) in the area (room) that this pet resides.
|
||||
Returns a tuple, Reaction and a list of characters.
|
||||
"""
|
||||
# State is a tuple of the level and the character:
|
||||
level = Reaction.SCARED
|
||||
characters = []
|
||||
|
||||
for c in self.local_characters:
|
||||
this_level = self.friendly_reaction(c)
|
||||
if this_level.value > level.value:
|
||||
level = this_level
|
||||
characters = [c]
|
||||
if this_level.value == level.value:
|
||||
characters += [c]
|
||||
return (level, characters)
|
||||
|
||||
def adjust_all(self, amount):
|
||||
"""
|
||||
Adjusts reaction level to all characters that have
|
||||
interacted with this pet, whether they are near it or not.
|
||||
This is essentially a loneliness measure, for out-of-sight,
|
||||
out-of-mind.
|
||||
"""
|
||||
for c in Character.objects.get_objs_with_attr(self.friendly_var):
|
||||
self.adjust_character(c, amount)
|
||||
|
||||
def adjust_all_locally(self, amount):
|
||||
"""
|
||||
Adjusts reaction level to all characters in the room
|
||||
with this pet. Hanging out with the pet should be helpful.
|
||||
"""
|
||||
for c in self.local_characters:
|
||||
self.adjust_character(c, amount)
|
||||
|
||||
def adjust_character(self, character, amount):
|
||||
"""
|
||||
Adjusts the reaction to 'character' by an 'amount.
|
||||
Note that this should never go below zero.
|
||||
"""
|
||||
new_val = self.friendly_level(character) + amount
|
||||
if new_val < 0:
|
||||
new_val = 0
|
||||
character.attributes.add(self.friendly_var, new_val)
|
||||
|
||||
def return_appearance(self, looker, **kwargs):
|
||||
"""
|
||||
Called by the 'look' command. This formats the description
|
||||
of this object based on 'reaction', and the character's
|
||||
_friendly_ level.
|
||||
|
||||
Args:
|
||||
looker (Object): Object doing the looking.
|
||||
"""
|
||||
level = self.friendly_reaction(looker)
|
||||
# looking at the friendly pets makes them nervous... just a little:
|
||||
self.adjust_character(looker, -1)
|
||||
|
||||
if level == Reaction.SCARED:
|
||||
return self.db.desc + " " + choices(self.db.scared_msg or "It seems scared of you.")
|
||||
elif level == Reaction.CONCERNED:
|
||||
return self.db.desc + " " + choices(self.db.concerned_msg or "It seems concerned you are here.")
|
||||
elif level == Reaction.INTERESTED:
|
||||
return self.db.desc + " " + choices(self.db.interested_msg or "It seems interested in you.")
|
||||
elif level == Reaction.FRIENDLY:
|
||||
return self.db.desc + " " + choices(self.db.friendly_msg or "It seems happy to see you.")
|
||||
else:
|
||||
# If we have an ecstatic message, use it otherwise, grab the friendly:
|
||||
return self.db.desc + " " + choices(self.db.ecstatic_msg or self.db.friendly_msg or
|
||||
"It seems ecstatic to see you.")
|
||||
|
||||
def update_state(self, *args, **kwargs):
|
||||
"""
|
||||
Hrm.
|
||||
"""
|
||||
super().update_state(*args, **kwargs)
|
||||
self.adjust_all(self.db.loneliness_amount or -1)
|
||||
self.adjust_all_locally(self.db.shyness_amount or 5)
|
||||
|
||||
# How spammy do we want the pet to be?
|
||||
if random.randint(0, 100) < self.db.active_amount:
|
||||
self.do_action()
|
||||
else:
|
||||
print("Nope")
|
||||
|
||||
def do_action(self):
|
||||
# Do something based on the highest friendly level is the same area!
|
||||
(level, chars) = self.friendly_reaction()
|
||||
focus = random.choice(chars)
|
||||
|
||||
if level == Reaction.SCARED:
|
||||
msg = choices(self.db.scared_actions)
|
||||
elif level == Reaction.CONCERNED:
|
||||
msg = choices(self.db.concerned_actions)
|
||||
elif level == Reaction.INTERESTED:
|
||||
msg = choices(self.db.interested_actions)
|
||||
elif level == Reaction.FRIENDLY:
|
||||
msg = choices(self.db.friendly_actions)
|
||||
else:
|
||||
# If we have an ecstatic message, use it otherwise, grab the friendly:
|
||||
msg = choices(self.db.ecstatic_actions or self.db.friendly_actions)
|
||||
|
||||
focus.msg(
|
||||
sub("<You>", "You", sub("<you>", "you", msg))
|
||||
)
|
||||
self.location.msg_contents(sub("<[Yy]ou>", focus.name.title(), msg),
|
||||
exclude=focus)
|
||||
|
||||
|
||||
class Imp(Friendly):
|
||||
def action(self):
|
||||
# Do something based on the highest friendly level is the same area!
|
||||
# Need a ticker ..
|
||||
# (state, chars) = self.highest_friendly_level()
|
||||
pass
|
||||
|
||||
def update_state(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class BHB(Friendly):
|
||||
"The Big Hairy Beast object."
|
||||
def action(self):
|
||||
# Do something based on the highest friendly level is the same area!
|
||||
# Need a ticker ..
|
||||
# (state, chars) = self.highest_friendly_level()
|
||||
pass
|
||||
# - < 10 : Attempts to hide
|
||||
# - < 20 : Steers clear but doesn’t hide
|
||||
# - < 50 : Wags it tail/butt
|
||||
# - > 50 : Follows you
|
||||
# level = self.friendly_level(looker)
|
||||
# if level == 0:
|
||||
# return f"You see a massive shadow lurking "
|
||||
# if level < 10:
|
||||
# return f"{self.db.desc} {self.hunger_appearance()}"
|
||||
|
||||
def given(self, giver, thing):
|
||||
# if obj.is_typeclass("typeclasses.things.Wood"):
|
||||
return True
|
||||
|
|
|
|||
Loading…
Reference in a new issue