Add a Scoring system to character
As character do things, they can now get a "score" for everything I think could be interesting/challenging.
This commit is contained in:
parent
5edc657678
commit
43a1aefb49
13 changed files with 123 additions and 3 deletions
|
|
@ -24,6 +24,7 @@ from commands.everyone import (CmdTake, CmdThink, CmdSay,
|
|||
CmdWhisper, CmdRead, CmdEat, CmdDrink,
|
||||
CmdUse, CmdPush, CmdPull,
|
||||
CmdOpen, CmdClose, CmdFeed)
|
||||
from commands.scoring import CmdScore
|
||||
from commands.hint import CmdHint
|
||||
from commands.misc import CmdLight
|
||||
from commands.wizards import (CmdGM, CmdSpell, CmdGMTrigger,
|
||||
|
|
@ -70,6 +71,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
|||
self.add(CmdMakeCocktail)
|
||||
self.add(CmdGift)
|
||||
self.add(CmdFeed)
|
||||
self.add(CmdScore)
|
||||
|
||||
|
||||
class AccountCmdSet(default_cmds.AccountCmdSet):
|
||||
|
|
|
|||
49
commands/scoring.py
Executable file
49
commands/scoring.py
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from evennia import CmdSet
|
||||
|
||||
from commands.command import Command
|
||||
from utils.scoring import Scores
|
||||
|
||||
|
||||
class CmdScore(Command):
|
||||
"""
|
||||
Display your score.
|
||||
|
||||
Usage:
|
||||
|
||||
score
|
||||
|
||||
The more things you do in this game, the better your scorecard.
|
||||
"""
|
||||
key = "score"
|
||||
aliases = ["scorecard"]
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
Implements the score command.
|
||||
"""
|
||||
def checked(tick):
|
||||
return " |g✔|n " if score & tick.value else " |r-|n "
|
||||
|
||||
score = self.caller.attributes.get('score', 0)
|
||||
total = len([1 for tick in list(Scores) if score & tick.value])
|
||||
|
||||
msg = "Your scorecard is:|/" + "|/".join([
|
||||
checked(Scores.jump) + "Jumped in a puddle",
|
||||
checked(Scores.moss_sit) + "Sat on some moss",
|
||||
checked(Scores.throw_stick) + "Thrown a stick",
|
||||
checked(Scores.catch_fish) + "Caught a fish",
|
||||
checked(Scores.feed_bhb) + "Fed Big Hairy Beast",
|
||||
checked(Scores.eat_candy) + "Eaten a candy",
|
||||
checked(Scores.get_cocktail) + "Got a cocktail",
|
||||
checked(Scores.finish_cocktail) + "Finished a cocktail",
|
||||
checked(Scores.make_tea) + "Made a pot of tea",
|
||||
checked(Scores.read_a_book) + "Read a book from Dabbler's library",
|
||||
checked(Scores.blow_horn) + "Called on the Mist Horn",
|
||||
checked(Scores.get_pipe) + "Received a smoking pipe",
|
||||
checked(Scores.get_blue_medal) + "Found the Blue Medal",
|
||||
checked(Scores.make_potion) + "Made a potion",
|
||||
]) + f"|/Total: {total}"
|
||||
|
||||
self.caller.msg(msg)
|
||||
|
|
@ -12,7 +12,7 @@ from commands.command import Command
|
|||
from typeclasses.objects import Object
|
||||
from typeclasses.scripts import Script
|
||||
from typeclasses.drinkables import Container
|
||||
|
||||
from utils.scoring import Scores
|
||||
|
||||
class CmdEmpty(Command):
|
||||
"""
|
||||
|
|
@ -241,6 +241,7 @@ class Cauldron(Object):
|
|||
|
||||
seq, brew_func = self.can_create_laughter()
|
||||
if seq:
|
||||
maker.score(Scores.make_potion)
|
||||
maker.announce_action(good)
|
||||
for idx, msg in enumerate(seq):
|
||||
delay(idx * 3 + 2, maker.announce_action, msg)
|
||||
|
|
|
|||
|
|
@ -105,6 +105,14 @@ class Character(Object, GenderCharacter, ContribRPCharacter):
|
|||
if obj.is_typeclass(typeclass):
|
||||
obj.delete()
|
||||
|
||||
def score(self, tick):
|
||||
"""
|
||||
Convenience method for keeping track of activities.
|
||||
"""
|
||||
score = self.attributes.get('score', 0)
|
||||
score |= tick.value
|
||||
self.attributes.add('score', score)
|
||||
|
||||
def new_account_setup(self):
|
||||
"""
|
||||
New accounts should connect the tutorial.
|
||||
|
|
@ -137,6 +145,7 @@ class Character(Object, GenderCharacter, ContribRPCharacter):
|
|||
# Reset the "running state" that character may have
|
||||
# experienced. This way, new guests get to _re-experience_ it:
|
||||
|
||||
self.db.score = 0
|
||||
self.db.visited = False
|
||||
self.db.jumped_times = 0
|
||||
self.db.tutorstate = 0
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from evennia.utils import logger
|
|||
|
||||
from typeclasses.objects import Object
|
||||
from commands.consumables import CmdSetTeapot, CmdSetFillable
|
||||
from utils.scoring import Scores
|
||||
from utils.word_list import routput, choices
|
||||
|
||||
import re
|
||||
|
|
@ -282,6 +283,7 @@ class Teapot(Object):
|
|||
self.db.tea_choice = tea_choice
|
||||
self.db.desc = f"A large, brown teapot full of {desc}."
|
||||
drinker.announce_action(f"$You() $conj(make) a teapot of {desc}.")
|
||||
drinker.score(Scores.make_tea)
|
||||
|
||||
def do_fill(self, drinker):
|
||||
teatype = self.db.tea_choice
|
||||
|
|
@ -517,9 +519,10 @@ class Cocktail(Object):
|
|||
|
||||
pre_msg = details.get("pre", "")
|
||||
drink.location.msg(routput(pre_msg + " The << bartender ^ barkeep ^ elf >> << passes ^ slides ^ gives ^ hands >> you a |y{0}|n.", drink.name))
|
||||
owner.score(Scores.get_cocktail)
|
||||
|
||||
theroom = drink.location.location
|
||||
char = owner.db._sdesc or owner.get_display_name(theroom)
|
||||
char = owner.sdesc.get() or owner.get_display_name(theroom)
|
||||
msg = routput(pre_msg + " The << bartender ^ barkeep ^ elf >> << passes ^ slides ^ gives ^ hands >> a {0} to {1}.",
|
||||
drink.db.cocktail_type, char)
|
||||
theroom.msg_contents(msg, exclude=owner)
|
||||
|
|
@ -537,6 +540,7 @@ class Cocktail(Object):
|
|||
drinker.msg(choices(DRINK_COCKTAIL_MSGS, self.key, cocktail_type, flavor))
|
||||
elif amount > 0:
|
||||
drinker.msg(choices(self.db.effects, self.key, cocktail_type))
|
||||
drinker.score(Scores.finish_cocktail)
|
||||
else:
|
||||
self.key = f"{self.db.cocktail_type} glass"
|
||||
self.aliases.add('glass')
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from urllib.request import urlopen
|
|||
from typeclasses.objects import Object
|
||||
from typeclasses.characters import Character
|
||||
from typeclasses.npcs import CarriableNPC
|
||||
from utils.scoring import Scores
|
||||
from utils.word_list import routput
|
||||
|
||||
import random
|
||||
|
|
@ -238,3 +239,4 @@ class FishingPole(Object):
|
|||
})[0]
|
||||
fish.location = fisher
|
||||
fisher.msg(f"You caught a fish!")
|
||||
fisher.score(Scores.catch_fish)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from evennia.prototypes.spawner import spawn
|
|||
from evennia.utils import delay, logger
|
||||
from evennia.utils.search import search_object
|
||||
|
||||
from utils.scoring import Scores
|
||||
from utils.word_list import routput
|
||||
|
||||
|
||||
|
|
@ -562,6 +563,21 @@ class Listener:
|
|||
c.adjust_coins(int(m.group(1)))
|
||||
return
|
||||
|
||||
m = match(r"score_all ([a-z_]+)", cmd)
|
||||
if m:
|
||||
tick = Scores[m.group(1)]
|
||||
for c in self.characters_here(puppets=True):
|
||||
c.score(tick)
|
||||
return
|
||||
|
||||
m = match(r"score ([a-z_]+) *?( to|=)? *([a-z_]+)", cmd)
|
||||
if m:
|
||||
tick = Scores[m.group(1)]
|
||||
c = self.search(m.group(3))
|
||||
if c:
|
||||
c.score(tick)
|
||||
return
|
||||
|
||||
if self.is_typeclass("typeclasses.characters.Character"):
|
||||
self.execute_cmd(cmd)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from evennia.utils.search import search_object
|
|||
from typeclasses.objects import Object
|
||||
from typeclasses.characters import Character
|
||||
from commands.pets import CmdPetSet
|
||||
from utils.scoring import Scores
|
||||
from utils.word_list import squish, choices
|
||||
|
||||
|
||||
|
|
@ -627,10 +628,12 @@ class BHB(Friendly):
|
|||
msg = f"{noun} {how_sniff} sniffs $your() outstretched arm holding a scone. It {how_eat} eats it, and {and_then}."
|
||||
self.adjust_character(feeder, 100)
|
||||
feeder.has('scone').delete()
|
||||
feeder.score(Scores.feed_bhb)
|
||||
elif is_berry(item):
|
||||
msg = f"{noun} {how_sniff} sniffs $your() outstretched arm with a handful of berries. It {how_eat} eats them, and {and_then}."
|
||||
self.adjust_character(feeder, 40)
|
||||
feeder.has('berries').delete()
|
||||
feeder.score(Scores.feed_bhb)
|
||||
else:
|
||||
msg = f"{noun} doesn't appear interested in anything you have."
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from evennia.prototypes.spawner import spawn
|
|||
|
||||
from typeclasses.objects import Object
|
||||
from typeclasses.consumables import Producer
|
||||
from utils.scoring import Scores
|
||||
from utils.user_info import location
|
||||
from utils.word_list import routput
|
||||
|
||||
|
|
@ -135,6 +136,7 @@ class WriteableBook(Book):
|
|||
self.db.post_write_msg or
|
||||
"$You() $conj(put) down the quill, and $conj(stop) writing.")
|
||||
|
||||
writer.score(Scores.sign_guest_book)
|
||||
|
||||
class Journal(WriteableBook):
|
||||
"""
|
||||
|
|
@ -315,6 +317,7 @@ class Bookshelf(Producer):
|
|||
book.location = reader
|
||||
|
||||
reader.msg(f"You pick up {filler} book, |w{title}|n.")
|
||||
reader.score(Scores.read_a_book)
|
||||
|
||||
self.db.last_title = None
|
||||
self.db.last_desc = None
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ from re import match
|
|||
from evennia import CmdSet
|
||||
from evennia.utils import logger, delay, int2str, search
|
||||
|
||||
from commands.command import Command
|
||||
from typeclasses.puzzles import StoryCube
|
||||
from typeclasses.scripts import Script
|
||||
from typeclasses.objects import Object
|
||||
from commands.command import Command
|
||||
from utils.scoring import Scores
|
||||
|
||||
PORT = "Lazy Dock"
|
||||
PORT_EXIT = "dock"
|
||||
|
|
@ -70,6 +71,7 @@ class CallingHorn(Object):
|
|||
blower.announce_action("$You() $conj(blow) $pron(your) horn "
|
||||
"and $conj(create) a long, resonating "
|
||||
"sound echoing over the water.")
|
||||
blower.score(Scores.blow_horn)
|
||||
|
||||
script_results = search.scripts("sailing")
|
||||
if script_results:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
from typeclasses.objects import Object
|
||||
from commands.sittables import CmdSetSit
|
||||
from utils.scoring import Scores
|
||||
from utils.word_list import routput
|
||||
|
||||
|
||||
|
|
@ -50,6 +51,7 @@ class Sittable(Object):
|
|||
|
||||
self.db.sitter = sitter
|
||||
sitter.db.is_sitting = self
|
||||
sitter.score(Scores.moss_sit)
|
||||
sitter.announce_action(f"$You() $conj(sit) {adjective} {article} {self.key}.")
|
||||
|
||||
sitter.location.other_sit(sitter)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from commands.misc import (CmdSetPuddle,
|
|||
from commands.consumables import CmdSetMakeConsumable
|
||||
from commands.wizards import CmdSetWand
|
||||
from utils.word_list import routput, choices, paragraph
|
||||
from utils.scoring import Scores
|
||||
from typeclasses.consumables import Litterable
|
||||
from typeclasses.objects import Object
|
||||
from typeclasses.scripts import KnockScript
|
||||
|
|
@ -339,6 +340,7 @@ class Stick(Object):
|
|||
self.cmdset.add_default(CmdSetStick)
|
||||
|
||||
def do_throw(self, thrower):
|
||||
thrower.score(Scores.throw_stick)
|
||||
beast = thrower.location.search('beast')
|
||||
if beast and beast.db.is_awake:
|
||||
beast.thrown_stick(thrower)
|
||||
|
|
@ -369,6 +371,7 @@ class Puddle(Object):
|
|||
self.cmdset.add_default(CmdSetPuddle)
|
||||
|
||||
def do_jump(self, player):
|
||||
player.score(Scores.jump)
|
||||
player.db.jumped_times = (player.db.jumped_times or 0) + 1
|
||||
if player.db.jumped_times == 1:
|
||||
player.msg("You jump in the puddle! "
|
||||
|
|
|
|||
24
utils/scoring.py
Executable file
24
utils/scoring.py
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Scores(Enum):
|
||||
"""
|
||||
Keep track of the scores we can do.
|
||||
"""
|
||||
jump = 2**0
|
||||
throw_stick = 2**1
|
||||
catch_fish = 2**2
|
||||
feed_bhb = 2**3
|
||||
blow_horn = 2**4
|
||||
make_tea = 2**5
|
||||
read_a_book = 2**6
|
||||
eat_candy = 2**7
|
||||
get_pipe = 2**8
|
||||
get_blue_medal = 2**9
|
||||
get_cocktail = 2**10
|
||||
finish_cocktail = 2**11
|
||||
make_potion = 2**12
|
||||
sign_guest_book = 2**13
|
||||
moss_sit = 2**14
|
||||
Loading…
Reference in a new issue