339 lines
11 KiB
Python
Executable file
339 lines
11 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
from datetime import date
|
|
import random
|
|
|
|
from evennia import TICKER_HANDLER
|
|
from evennia.utils import delay
|
|
from evennia.prototypes.spawner import spawn
|
|
|
|
from commands.consumables import CmdSetTrolley, CmdSetMakeConsumable
|
|
from typeclasses.exits import Opener
|
|
from typeclasses.objects import Object
|
|
from utils.scoring import Scores
|
|
from utils.word_list import routput # , choices
|
|
|
|
|
|
class Litterable(Object):
|
|
"""
|
|
Objects, that if dropped, are deleted instead.
|
|
The default thing for a producer.
|
|
"""
|
|
def at_pre_drop(self, dropper):
|
|
"""
|
|
Let's keep this world tidy.
|
|
"""
|
|
dropper.announce_action(f"$You() $conj(drop) the {self.name}.")
|
|
self.delete()
|
|
|
|
|
|
class Consumable(Litterable):
|
|
"""
|
|
Create with a command:
|
|
|
|
@create/drop berries;berry : typeclasses.consumables.Consumable
|
|
@desc berries = Bright red, almost violet, berry.
|
|
# How many berries are there?
|
|
@set berries/amount = 10
|
|
# How many berries do you eat at a time:
|
|
@set berries/eat_amount = 3
|
|
@set berries/eat_msg = "Sweet and slightly tart. <<Delicious ^ Tangy ^ Mmmm>>."
|
|
@set berries/finish_msg = "Those were <<delicious ^ great>>."
|
|
"""
|
|
amount = 4
|
|
eat_amount = 1
|
|
|
|
def at_object_creation(self):
|
|
self.db.amount = self.amount
|
|
self.db.eat_amount = self.eat_amount
|
|
|
|
def do_eat(self, eater):
|
|
"""
|
|
Consume (eat) or destroy this object.
|
|
Indicate this with messages to eater.
|
|
"""
|
|
self.db.amount = self.db.amount - self.db.eat_amount
|
|
if self.db.eat_msgs:
|
|
msg = random.choice(self.db.eat_msgs)
|
|
elif self.db.eat_msg:
|
|
msg = self.db.eat_msg
|
|
else:
|
|
msg = "You take a bite."
|
|
eater.msg(routput(msg))
|
|
|
|
if self.key == 'candy':
|
|
eater.score(Scores.eat_candy)
|
|
eater.announce_action("$You() $conj(eat) some candy.",
|
|
exclude=eater)
|
|
|
|
if self.db.amount <= 0:
|
|
if self.db.finish_msgs:
|
|
msg = random.choice(self.db.finish_msgs)
|
|
elif self.db.finish_msg:
|
|
msg = self.db.finish_msg
|
|
else:
|
|
msg = None
|
|
|
|
if msg:
|
|
eater.msg(routput(msg))
|
|
self.delete()
|
|
|
|
|
|
class Herb(Litterable):
|
|
"""
|
|
Essentially a marker for something that can go in a cauldron.
|
|
"""
|
|
pass
|
|
|
|
|
|
class Edible(Consumable):
|
|
"""
|
|
Like a Consumable, but this packs a punch.
|
|
|
|
When eaten, it kicks off a temporary script that acts like a
|
|
spell.
|
|
"""
|
|
def do_eat(self, eater):
|
|
"""
|
|
Consume (eat) AND destroy this object.
|
|
We assume one dose is sufficient.
|
|
"""
|
|
msg = self.db.eat_msg or f"You take a bite of {self.name}."
|
|
eater.msg(routput(msg))
|
|
self.delete()
|
|
if self.db.spell:
|
|
eater.scripts.add(self.db.spell, autostart=True)
|
|
elif self.db.spell_msgs:
|
|
eater.delay_sequence(self.db.spell_msgs)
|
|
|
|
|
|
class Producer(Object):
|
|
"""
|
|
An object that produces a Consumable object.
|
|
Use it to create a 'berry bush', for instance:
|
|
|
|
@create/drop berry bush;bush : typeclasses.consumables.Producer
|
|
@desc bush = A bush laden with bright red brambleberries.
|
|
|
|
# Then describe what to produce:
|
|
@set bush/make_name = "berries"
|
|
@set bush/make_aliases = ["berry"]
|
|
@set bush/make_verb = "pick some"
|
|
# This one is optional as it defaults to Consumable:
|
|
@set bush/make_class = "typeclasses.consumables.Consumable"
|
|
@set bush/make_desc = "Bright red berry with flecks of <<purple ^ violet ^ orange>>."
|
|
|
|
# How many berries are there when you pick them?
|
|
@set bush/make_amount = 10
|
|
# How many berries do you eat at a time:
|
|
@set bush/make_eat_amount = 3
|
|
|
|
# Either a single msg:
|
|
@set bush/make_eat_msg = "Sweet and slightly tart. <<Delicious ^ Tangy ^ Mmmm>>."
|
|
# Or many:
|
|
@set bush/make_eat_msgs = [ "Sweet and slightly tart.", "<<Delicious ^ Tangy ^ Mmmm>>.",
|
|
"Ooo...that one was sour.", "That was a bit ripe, but still good.",
|
|
"So sweet with a hint of <<orange ^ maple>>." ]
|
|
@set bush/make_finish_msg = "Those were <<delicious ^ great>>."
|
|
"""
|
|
def at_object_creation(self):
|
|
self.cmdset.add_default(CmdSetMakeConsumable)
|
|
|
|
def at_pre_get(self, getter, **kwargs):
|
|
"""
|
|
Can't get a producer.
|
|
"""
|
|
self.do_make(getter)
|
|
return False
|
|
|
|
def do_make(self, picker, **kwargs):
|
|
"""
|
|
Create a configurable consumable, given to picker.
|
|
"""
|
|
consumable = spawn({
|
|
"typeclass": self.db.make_class or (kwargs['type']
|
|
if 'type' in kwargs else
|
|
"typeclasses.consumables.Consumable"),
|
|
"key": self.db.make_name,
|
|
"aliases": self.db.make_aliases,
|
|
"desc": routput(self.db.make_desc),
|
|
})[0]
|
|
consumable.db.amount = self.db.make_amount or 3
|
|
consumable.db.eat_amount = self.db.make_eat_amount or 1
|
|
|
|
if self.db.make_eat_msg:
|
|
consumable.db.eat_msg = self.db.make_eat_msg
|
|
if self.db.make_eat_msgs:
|
|
consumable.db.eat_msgs = self.db.make_eat_msgs
|
|
if self.db.make_finish_msg:
|
|
consumable.db.finish_msg = self.db.make_finish_msg
|
|
if self.db.make_finish_msgs:
|
|
consumable.db.finish_msgs = self.db.make_finish_msgs
|
|
|
|
if self.db.make_spell:
|
|
consumable.db.spell = self.db.make_spell
|
|
if self.db.make_spell_msgs:
|
|
consumable.db.spell_msgs = self.db.make_spell_msgs
|
|
|
|
consumable.location = picker
|
|
picker.announce_action(f"$You() {self.db.make_verb or '$conj(get)'} {self.db.make_name}{self.db.make_note or ''}.")
|
|
|
|
|
|
# ----------------------------------------------------------------------
|
|
|
|
TEACUP_DESCS = [
|
|
"A rustic, clay teacup carefully crafted on a wheel. Beautiful <<dark red ^ olive green ^ navy blue>> glaze.",
|
|
"A fine example of Royal Albert teacup, sporting a design of violet azaleas. Perfect for a black tea.",
|
|
"A Wings of Grace style teacup with blue butterflies. Perfect for some Earl Grey.",
|
|
"A dark brown Yixing clay teacup. Perfect for an Oolong tea.",
|
|
"A light jade green handle-less teacup. A good choice for a green tea.",
|
|
]
|
|
|
|
|
|
class Trolley(Producer):
|
|
"""
|
|
A special producer that has a plate of specific dishes for
|
|
that day. I need this special because I'm not sure how to populate
|
|
the database with complex arrays of data.
|
|
"""
|
|
scones = [
|
|
{
|
|
"name": "blueberry scone",
|
|
"taste": "blueberries",
|
|
},
|
|
{
|
|
"name": "chocolate chip scone",
|
|
"taste": "chocolate",
|
|
},
|
|
{
|
|
"name": "lemon poppy seed scone",
|
|
"taste": "lemon",
|
|
},
|
|
{
|
|
"name": "cinnamon scone",
|
|
"taste": "spice",
|
|
},
|
|
{
|
|
"name": "cranberry orange scone",
|
|
"tastes": ["tartness of the cranberries", "orange"],
|
|
},
|
|
{
|
|
"name": "pumpkin scone",
|
|
"taste": "spices",
|
|
},
|
|
{
|
|
"name": "cheddar cheese and chive scone",
|
|
"expression": "cheesy"
|
|
},
|
|
{
|
|
"name": "cherry almond scone",
|
|
"expression": "nutty",
|
|
},
|
|
{
|
|
"name": "apple cinnamon scone",
|
|
"tastes": ["apple", "cinnamon"],
|
|
},
|
|
]
|
|
|
|
teacup_prototype = {
|
|
"typeclass": "typeclasses.drinkables.TeaCup",
|
|
"key": "teacup",
|
|
"aliases": "cup",
|
|
"desc": "A nice teacup.",
|
|
}
|
|
|
|
def at_object_creation(self):
|
|
self.cmdset.add_default(CmdSetTrolley)
|
|
TICKER_HANDLER.add(interval=60 * 60 * 24,
|
|
callback=self.do_bake)
|
|
|
|
def produce_teacup(self, caller):
|
|
"""
|
|
Create and associate with 'caller', a newly created teacup.
|
|
"""
|
|
if caller.has("teacup"):
|
|
caller.msg("You already have a teacup.")
|
|
else:
|
|
cuptype = self.teacup_prototype
|
|
cuptype['desc'] = routput(random.choice(TEACUP_DESCS))
|
|
|
|
cup = spawn(cuptype)[0]
|
|
cup.location = caller
|
|
caller.msg("You pick up a teacup.")
|
|
|
|
def produce_wood(self, caller):
|
|
"""
|
|
Create and give to 'caller' a log of wood.
|
|
"""
|
|
wood = spawn({
|
|
"creator_id": 1,
|
|
"typeclass": "typeclasses.things.Wood",
|
|
"key": "log",
|
|
"aliases": ["wood", "kindling", "logs"],
|
|
})[0]
|
|
wood.location = caller
|
|
caller.msg(routput("You <<get ^ pick up ^ grab>> "
|
|
"<<some wood ^ couple logs ^ a log ^ a few pieces of wood>> "
|
|
"<<from the woodbox ^ from the box on the hearth ^ for the fireplace ^ >>."))
|
|
|
|
def do_open(self, opener):
|
|
"""
|
|
Sure we can open the cabinets, but what does that mean?
|
|
"""
|
|
opener.execute_cmd("look cabinet")
|
|
|
|
def do_close(self, opener):
|
|
"""
|
|
Sure we can open the cabinets, but what does that mean?
|
|
"""
|
|
opener.msg("Okay.")
|
|
|
|
def do_bake(self):
|
|
"""
|
|
Set the scone that we bake today.
|
|
"""
|
|
todays_scone = self.scones[date.today().day % len(self.scones)]
|
|
name = todays_scone.get("name")
|
|
|
|
self.db.make_name = name
|
|
self.db.make_aliases = ["scone", "scones"]
|
|
self.db.make_desc = routput("A <<tasty ^ yummy ^ delicious>>-looking {0}", name)
|
|
self.db.make_amount = 3
|
|
self.db.make_eat_amount = 1
|
|
|
|
msgs = [
|
|
"Delicious.",
|
|
"So good",
|
|
"Really good.",
|
|
'Mmmmm',
|
|
]
|
|
if todays_scone.get('taste'):
|
|
msgs += ['You <<can ^ >> <<really ^ >> <<notice ^ taste>> the ' + todays_scone.get('taste') + '.']
|
|
if todays_scone.get('tastes'):
|
|
for taste in todays_scone.get('tastes'):
|
|
msgs += ['You <<can ^ >> <<really ^ >> <<notice ^ taste>> the ' + taste + '.']
|
|
if todays_scone.get('expression'):
|
|
msgs += [f"<<Really ^ So>> {todays_scone.get('expression')}."]
|
|
|
|
self.db.make_eat_msgs = msgs
|
|
self.db.make_finish_msg = "That was <<delicious ^ great ^ really good>>."
|
|
|
|
self.location.msg_contents(routput("<<New ^ Aromatic ^ Fresh ^ Freshly baked>> scones <<magically ^ suddenly ^ mystically ^ enchantingly ^ >> appear <<on a plate ^ on plates ^ >> on the trolley."))
|
|
|
|
|
|
class Sconce(Producer, Opener):
|
|
"""
|
|
A producer that also implements a Push in order to open a door.
|
|
"""
|
|
def do_pull(self, puller):
|
|
"""
|
|
Opens a door, and sets a timer to close it.
|
|
"""
|
|
puller.announce_action(f"$You() $conj(pull) on the {self.name}.")
|
|
if self.db.exit:
|
|
if self.db.pull_msg:
|
|
self.location.msg_contents(self.db.pull_msg)
|
|
self.do_open()
|
|
delay(30, self.do_close)
|
|
delay(31, self.db.room.msg_contents, "The bookcase slams shut.")
|