Skip to content

Instantly share code, notes, and snippets.

@whutch
Last active March 15, 2016 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whutch/672570fd8ef046bc5bf0 to your computer and use it in GitHub Desktop.
Save whutch/672570fd8ef046bc5bf0 to your computer and use it in GitHub Desktop.
Example contrib modules for Clockwork
from functools import partial
from cwmud.contrib.crafting import Material
from cwmud.contrib.gathering import GatheringNode
from cwmud.core.characters import CharacterShell
from cwmud.core.commands import COMMANDS
from cwmud.core.items import Item, ITEMS, Trash
from cwmud.core.skills import AbilityCommand, Skill, SKILLS
@SKILLS.register("lumberjacking")
class Lumberjacking(Skill):
gain_rate_success = 0.15 # Percent chance per use?
gain_rate_failure = 0.05
# These probably won't be flat values but scale in some manner based
# on current skill.
@ITEMS.register("material_log")
class Log(Material):
nouns = ("log", "wood")
name = "log of wood"
short_desc = "A log of wood has been dropped here."
@ITEMS.register("trash_wood_scraps")
class WoodScraps(Trash):
nouns = ("wood", "scraps")
name = "wood scraps"
short_desc = "Some wood scraps are piled here."
@ITEMS.register("gathering_node_tree")
class Tree(GatheringNode):
nouns = ("tree",)
name = "a tree"
short_desc = "A tall, leafy tree is here, swaying in the breeze."
restock_time = "15m"
Tree.add_yield(Log, chance=0.66, amount=(1, 2), stock=(4, 8))
Tree.add_yield(WoodScraps, chance=0.80, amount=(1, 3), stock=None)
# Yields with a stock of None never run out.
# The yield table is sorted by chance, from lowest to highest. When an attempt
# to gather is made, it rolls random.random() to get a high precision float
# between 0 and 1, then that roll is compared to each yield via a check of
# (roll >= (1 - chance)), stopping on a success (can allow for multiple rolls
# to gather multiple yields at once). In this manner, a good roll will always
# return the best yield possible.
@COMMANDS.register
class Chop(AbilityCommand):
"""A command for chopping wood."""
requires_skill = ("lumberjacking", 10.0)
# Below 10.0 you are literally don't know how to use an axe and will
# need to find an NPC trainer.
def parse(self, character, args):
"""Called when the command is parsed from the session."""
if not args or not args[0]:
return character.session.send("Chop what?")
# Session.send returns nothing, this just saves the extra line.
target = character.room.find_target(args[0])
if not target:
return character.session.send("You can't seem to find it.")
if not isinstance(target, Tree):
return character.session.send("You can't chop that!")
if not target.has_stock():
# This checks if there is still a stock of yielded items in the
# gathering node. Yields that have a stock of None are ignored
# (make that optional on add_yield?).
return character.session.send("There's not much tree left.")
character.queue_ability(self, args=(target,))
# Character.queue_ability will put the command instance in the
# character's ability queue, to be processed as soon as any other
# abilities are resolved and there are no pending delays.
# If possible, it will be resolved immediately (nothing in queue
# and no pending delays).
def resolve(self, character, target):
"""Called when the command is ready to be resolved."""
character.session.send("You begin chopping away at", target.name)
callback = partial(self.finish, character, target)
character.add_delay("5s", callback=callback)
def finish(self, character, target):
"""Called after the short chopping delay."""
yielded, amount = target.get_yields()
if yielded:
character.session.send("Your chopping yielded {} ({})."
.format(yielded, amount))
character.add_item(yielded, amount)
else:
character.session.send("You chop for a while but don't manage "
"to produce any usable wood.")
character.check_skill_gain("lumberjacking")
CharacterShell.add_verbs(Chop, "chop")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment