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,
|
CmdWhisper, CmdRead, CmdEat, CmdDrink,
|
||||||
CmdUse, CmdPush, CmdPull,
|
CmdUse, CmdPush, CmdPull,
|
||||||
CmdOpen, CmdClose, CmdFeed)
|
CmdOpen, CmdClose, CmdFeed)
|
||||||
|
from commands.scoring import CmdScore
|
||||||
from commands.hint import CmdHint
|
from commands.hint import CmdHint
|
||||||
from commands.misc import CmdLight
|
from commands.misc import CmdLight
|
||||||
from commands.wizards import (CmdGM, CmdSpell, CmdGMTrigger,
|
from commands.wizards import (CmdGM, CmdSpell, CmdGMTrigger,
|
||||||
|
|
@ -70,6 +71,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||||
self.add(CmdMakeCocktail)
|
self.add(CmdMakeCocktail)
|
||||||
self.add(CmdGift)
|
self.add(CmdGift)
|
||||||
self.add(CmdFeed)
|
self.add(CmdFeed)
|
||||||
|
self.add(CmdScore)
|
||||||
|
|
||||||
|
|
||||||
class AccountCmdSet(default_cmds.AccountCmdSet):
|
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.objects import Object
|
||||||
from typeclasses.scripts import Script
|
from typeclasses.scripts import Script
|
||||||
from typeclasses.drinkables import Container
|
from typeclasses.drinkables import Container
|
||||||
|
from utils.scoring import Scores
|
||||||
|
|
||||||
class CmdEmpty(Command):
|
class CmdEmpty(Command):
|
||||||
"""
|
"""
|
||||||
|
|
@ -241,6 +241,7 @@ class Cauldron(Object):
|
||||||
|
|
||||||
seq, brew_func = self.can_create_laughter()
|
seq, brew_func = self.can_create_laughter()
|
||||||
if seq:
|
if seq:
|
||||||
|
maker.score(Scores.make_potion)
|
||||||
maker.announce_action(good)
|
maker.announce_action(good)
|
||||||
for idx, msg in enumerate(seq):
|
for idx, msg in enumerate(seq):
|
||||||
delay(idx * 3 + 2, maker.announce_action, msg)
|
delay(idx * 3 + 2, maker.announce_action, msg)
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,14 @@ class Character(Object, GenderCharacter, ContribRPCharacter):
|
||||||
if obj.is_typeclass(typeclass):
|
if obj.is_typeclass(typeclass):
|
||||||
obj.delete()
|
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):
|
def new_account_setup(self):
|
||||||
"""
|
"""
|
||||||
New accounts should connect the tutorial.
|
New accounts should connect the tutorial.
|
||||||
|
|
@ -137,6 +145,7 @@ class Character(Object, GenderCharacter, ContribRPCharacter):
|
||||||
# Reset the "running state" that character may have
|
# Reset the "running state" that character may have
|
||||||
# experienced. This way, new guests get to _re-experience_ it:
|
# experienced. This way, new guests get to _re-experience_ it:
|
||||||
|
|
||||||
|
self.db.score = 0
|
||||||
self.db.visited = False
|
self.db.visited = False
|
||||||
self.db.jumped_times = 0
|
self.db.jumped_times = 0
|
||||||
self.db.tutorstate = 0
|
self.db.tutorstate = 0
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from evennia.utils import logger
|
||||||
|
|
||||||
from typeclasses.objects import Object
|
from typeclasses.objects import Object
|
||||||
from commands.consumables import CmdSetTeapot, CmdSetFillable
|
from commands.consumables import CmdSetTeapot, CmdSetFillable
|
||||||
|
from utils.scoring import Scores
|
||||||
from utils.word_list import routput, choices
|
from utils.word_list import routput, choices
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
@ -282,6 +283,7 @@ class Teapot(Object):
|
||||||
self.db.tea_choice = tea_choice
|
self.db.tea_choice = tea_choice
|
||||||
self.db.desc = f"A large, brown teapot full of {desc}."
|
self.db.desc = f"A large, brown teapot full of {desc}."
|
||||||
drinker.announce_action(f"$You() $conj(make) a teapot of {desc}.")
|
drinker.announce_action(f"$You() $conj(make) a teapot of {desc}.")
|
||||||
|
drinker.score(Scores.make_tea)
|
||||||
|
|
||||||
def do_fill(self, drinker):
|
def do_fill(self, drinker):
|
||||||
teatype = self.db.tea_choice
|
teatype = self.db.tea_choice
|
||||||
|
|
@ -517,9 +519,10 @@ class Cocktail(Object):
|
||||||
|
|
||||||
pre_msg = details.get("pre", "")
|
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))
|
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
|
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}.",
|
msg = routput(pre_msg + " The << bartender ^ barkeep ^ elf >> << passes ^ slides ^ gives ^ hands >> a {0} to {1}.",
|
||||||
drink.db.cocktail_type, char)
|
drink.db.cocktail_type, char)
|
||||||
theroom.msg_contents(msg, exclude=owner)
|
theroom.msg_contents(msg, exclude=owner)
|
||||||
|
|
@ -537,6 +540,7 @@ class Cocktail(Object):
|
||||||
drinker.msg(choices(DRINK_COCKTAIL_MSGS, self.key, cocktail_type, flavor))
|
drinker.msg(choices(DRINK_COCKTAIL_MSGS, self.key, cocktail_type, flavor))
|
||||||
elif amount > 0:
|
elif amount > 0:
|
||||||
drinker.msg(choices(self.db.effects, self.key, cocktail_type))
|
drinker.msg(choices(self.db.effects, self.key, cocktail_type))
|
||||||
|
drinker.score(Scores.finish_cocktail)
|
||||||
else:
|
else:
|
||||||
self.key = f"{self.db.cocktail_type} glass"
|
self.key = f"{self.db.cocktail_type} glass"
|
||||||
self.aliases.add('glass')
|
self.aliases.add('glass')
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ from urllib.request import urlopen
|
||||||
from typeclasses.objects import Object
|
from typeclasses.objects import Object
|
||||||
from typeclasses.characters import Character
|
from typeclasses.characters import Character
|
||||||
from typeclasses.npcs import CarriableNPC
|
from typeclasses.npcs import CarriableNPC
|
||||||
|
from utils.scoring import Scores
|
||||||
from utils.word_list import routput
|
from utils.word_list import routput
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
@ -238,3 +239,4 @@ class FishingPole(Object):
|
||||||
})[0]
|
})[0]
|
||||||
fish.location = fisher
|
fish.location = fisher
|
||||||
fisher.msg(f"You caught a fish!")
|
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 import delay, logger
|
||||||
from evennia.utils.search import search_object
|
from evennia.utils.search import search_object
|
||||||
|
|
||||||
|
from utils.scoring import Scores
|
||||||
from utils.word_list import routput
|
from utils.word_list import routput
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -562,6 +563,21 @@ class Listener:
|
||||||
c.adjust_coins(int(m.group(1)))
|
c.adjust_coins(int(m.group(1)))
|
||||||
return
|
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"):
|
if self.is_typeclass("typeclasses.characters.Character"):
|
||||||
self.execute_cmd(cmd)
|
self.execute_cmd(cmd)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ from evennia.utils.search import search_object
|
||||||
from typeclasses.objects import Object
|
from typeclasses.objects import Object
|
||||||
from typeclasses.characters import Character
|
from typeclasses.characters import Character
|
||||||
from commands.pets import CmdPetSet
|
from commands.pets import CmdPetSet
|
||||||
|
from utils.scoring import Scores
|
||||||
from utils.word_list import squish, choices
|
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}."
|
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)
|
self.adjust_character(feeder, 100)
|
||||||
feeder.has('scone').delete()
|
feeder.has('scone').delete()
|
||||||
|
feeder.score(Scores.feed_bhb)
|
||||||
elif is_berry(item):
|
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}."
|
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)
|
self.adjust_character(feeder, 40)
|
||||||
feeder.has('berries').delete()
|
feeder.has('berries').delete()
|
||||||
|
feeder.score(Scores.feed_bhb)
|
||||||
else:
|
else:
|
||||||
msg = f"{noun} doesn't appear interested in anything you have."
|
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.objects import Object
|
||||||
from typeclasses.consumables import Producer
|
from typeclasses.consumables import Producer
|
||||||
|
from utils.scoring import Scores
|
||||||
from utils.user_info import location
|
from utils.user_info import location
|
||||||
from utils.word_list import routput
|
from utils.word_list import routput
|
||||||
|
|
||||||
|
|
@ -135,6 +136,7 @@ class WriteableBook(Book):
|
||||||
self.db.post_write_msg or
|
self.db.post_write_msg or
|
||||||
"$You() $conj(put) down the quill, and $conj(stop) writing.")
|
"$You() $conj(put) down the quill, and $conj(stop) writing.")
|
||||||
|
|
||||||
|
writer.score(Scores.sign_guest_book)
|
||||||
|
|
||||||
class Journal(WriteableBook):
|
class Journal(WriteableBook):
|
||||||
"""
|
"""
|
||||||
|
|
@ -315,6 +317,7 @@ class Bookshelf(Producer):
|
||||||
book.location = reader
|
book.location = reader
|
||||||
|
|
||||||
reader.msg(f"You pick up {filler} book, |w{title}|n.")
|
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_title = None
|
||||||
self.db.last_desc = None
|
self.db.last_desc = None
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@ from re import match
|
||||||
from evennia import CmdSet
|
from evennia import CmdSet
|
||||||
from evennia.utils import logger, delay, int2str, search
|
from evennia.utils import logger, delay, int2str, search
|
||||||
|
|
||||||
|
from commands.command import Command
|
||||||
from typeclasses.puzzles import StoryCube
|
from typeclasses.puzzles import StoryCube
|
||||||
from typeclasses.scripts import Script
|
from typeclasses.scripts import Script
|
||||||
from typeclasses.objects import Object
|
from typeclasses.objects import Object
|
||||||
from commands.command import Command
|
from utils.scoring import Scores
|
||||||
|
|
||||||
PORT = "Lazy Dock"
|
PORT = "Lazy Dock"
|
||||||
PORT_EXIT = "dock"
|
PORT_EXIT = "dock"
|
||||||
|
|
@ -70,6 +71,7 @@ class CallingHorn(Object):
|
||||||
blower.announce_action("$You() $conj(blow) $pron(your) horn "
|
blower.announce_action("$You() $conj(blow) $pron(your) horn "
|
||||||
"and $conj(create) a long, resonating "
|
"and $conj(create) a long, resonating "
|
||||||
"sound echoing over the water.")
|
"sound echoing over the water.")
|
||||||
|
blower.score(Scores.blow_horn)
|
||||||
|
|
||||||
script_results = search.scripts("sailing")
|
script_results = search.scripts("sailing")
|
||||||
if script_results:
|
if script_results:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
from typeclasses.objects import Object
|
from typeclasses.objects import Object
|
||||||
from commands.sittables import CmdSetSit
|
from commands.sittables import CmdSetSit
|
||||||
|
from utils.scoring import Scores
|
||||||
from utils.word_list import routput
|
from utils.word_list import routput
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -50,6 +51,7 @@ class Sittable(Object):
|
||||||
|
|
||||||
self.db.sitter = sitter
|
self.db.sitter = sitter
|
||||||
sitter.db.is_sitting = self
|
sitter.db.is_sitting = self
|
||||||
|
sitter.score(Scores.moss_sit)
|
||||||
sitter.announce_action(f"$You() $conj(sit) {adjective} {article} {self.key}.")
|
sitter.announce_action(f"$You() $conj(sit) {adjective} {article} {self.key}.")
|
||||||
|
|
||||||
sitter.location.other_sit(sitter)
|
sitter.location.other_sit(sitter)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ from commands.misc import (CmdSetPuddle,
|
||||||
from commands.consumables import CmdSetMakeConsumable
|
from commands.consumables import CmdSetMakeConsumable
|
||||||
from commands.wizards import CmdSetWand
|
from commands.wizards import CmdSetWand
|
||||||
from utils.word_list import routput, choices, paragraph
|
from utils.word_list import routput, choices, paragraph
|
||||||
|
from utils.scoring import Scores
|
||||||
from typeclasses.consumables import Litterable
|
from typeclasses.consumables import Litterable
|
||||||
from typeclasses.objects import Object
|
from typeclasses.objects import Object
|
||||||
from typeclasses.scripts import KnockScript
|
from typeclasses.scripts import KnockScript
|
||||||
|
|
@ -339,6 +340,7 @@ class Stick(Object):
|
||||||
self.cmdset.add_default(CmdSetStick)
|
self.cmdset.add_default(CmdSetStick)
|
||||||
|
|
||||||
def do_throw(self, thrower):
|
def do_throw(self, thrower):
|
||||||
|
thrower.score(Scores.throw_stick)
|
||||||
beast = thrower.location.search('beast')
|
beast = thrower.location.search('beast')
|
||||||
if beast and beast.db.is_awake:
|
if beast and beast.db.is_awake:
|
||||||
beast.thrown_stick(thrower)
|
beast.thrown_stick(thrower)
|
||||||
|
|
@ -369,6 +371,7 @@ class Puddle(Object):
|
||||||
self.cmdset.add_default(CmdSetPuddle)
|
self.cmdset.add_default(CmdSetPuddle)
|
||||||
|
|
||||||
def do_jump(self, player):
|
def do_jump(self, player):
|
||||||
|
player.score(Scores.jump)
|
||||||
player.db.jumped_times = (player.db.jumped_times or 0) + 1
|
player.db.jumped_times = (player.db.jumped_times or 0) + 1
|
||||||
if player.db.jumped_times == 1:
|
if player.db.jumped_times == 1:
|
||||||
player.msg("You jump in the puddle! "
|
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