Which does both the `cast` and `reel` commands. The fishing messages are alos public notices.
254 lines
8.8 KiB
Python
Executable file
254 lines
8.8 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
from evennia import (
|
|
Command,
|
|
CmdSet,
|
|
TICKER_HANDLER,
|
|
syscmdkeys,
|
|
create_script,
|
|
)
|
|
from evennia.prototypes.spawner import spawn
|
|
from evennia.utils import delay
|
|
|
|
from enum import Enum
|
|
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
|
|
import requests
|
|
|
|
|
|
class Fishing(Enum):
|
|
"The acceptable states of fishing."
|
|
CAST = True
|
|
REEL = False
|
|
|
|
|
|
class CmdThrowFish(Command):
|
|
"""
|
|
Throw the fish, if you are holding one, back in the water.
|
|
|
|
A helper can escort the fish to the nearest body of water if you aren't adjacent to one.
|
|
"""
|
|
key = "throw"
|
|
locks = "holds(fish)"
|
|
|
|
def func(self):
|
|
self.obj.do_delete(self.caller)
|
|
|
|
|
|
class CmdSetFish(CmdSet):
|
|
def at_cmdset_creation(self):
|
|
self.add(CmdThrowFish)
|
|
|
|
|
|
class CmdCast(Command):
|
|
"""
|
|
Cast the pole.
|
|
"""
|
|
key = "cast"
|
|
locks = "holds(pole)"
|
|
|
|
def func(self):
|
|
self.obj.do_cast(self.caller)
|
|
|
|
|
|
class CmdReel(Command):
|
|
"""
|
|
Reel the pole.
|
|
"""
|
|
key = "reel"
|
|
locks = "holds(pole)"
|
|
|
|
def func(self):
|
|
self.obj.do_reel(self.caller)
|
|
|
|
|
|
class CmdSetFishing(CmdSet):
|
|
def at_cmdset_creation(self):
|
|
self.add(CmdCast)
|
|
self.add(CmdReel)
|
|
|
|
|
|
class Fish(CarriableNPC):
|
|
"""
|
|
Everyone wants a fish that tells dad jokes, right!?
|
|
"""
|
|
# The number of seconds to check for the time for a message:
|
|
fish_tick = 3
|
|
|
|
def at_object_creation(self):
|
|
self.cmdset.add_default(CmdSetFish)
|
|
self.db.name = Fish.get_name()
|
|
self.db.spoken = 0
|
|
TICKER_HANDLER.add(interval=self.fish_tick,
|
|
callback=self.do_speak)
|
|
|
|
def at_heard_say(self, message, from_obj):
|
|
"""
|
|
A simple listener and response. This makes it easy to change for
|
|
subclasses of NPCs reacting differently to says.
|
|
|
|
"""
|
|
return "say", "What was that? I must have water in my ear."
|
|
|
|
def at_say(self, message):
|
|
"""
|
|
Spoken out loud to the world, even if owned.
|
|
"""
|
|
owner = self.location
|
|
if owner.is_typeclass(Character) and owner.is_connected:
|
|
self.location.announce_action(f"$Your() fish says, \"{message}\"")
|
|
|
|
def do_speak(self):
|
|
"""
|
|
Called at a repeatable sequence by the ticker, and
|
|
it calls at_say() in order to do a type of monologue.
|
|
"""
|
|
if self.db.spoken == 1:
|
|
self.at_say("Whew! Thanks for removing the sharp hook. Not sure how I got stuck on that.")
|
|
elif self.db.spoken == 5:
|
|
self.at_say(f"My name's {self.db.name}. What's yours?")
|
|
self.db.desc = f"{self.db.name}. {self.db.desc}"
|
|
elif self.db.spoken == 10:
|
|
self.at_say("Did you say something? I think I have water in my ears, as I can't hear a thing.")
|
|
elif self.db.spoken == 20:
|
|
self.at_say("So... how're you getting along?")
|
|
elif self.db.spoken == 30:
|
|
self.at_say("Right, right. Still can't hear. Hrm.")
|
|
elif self.db.spoken == 60:
|
|
self.at_say("Do you know why we fish are so easy to weigh? ")
|
|
elif self.db.spoken == 63:
|
|
self.at_say("Because we have are own scales.")
|
|
elif self.db.spoken == 70:
|
|
self.at_say("I suppose you could |gthrow|n me back in the water at any time.")
|
|
elif self.db.spoken == 120:
|
|
self.at_say("I suppose I should pay you back for helping me out with that hook thing. I guess you know I keep all my money at ... the riverbank.")
|
|
elif self.db.spoken == 200:
|
|
self.at_say("You know the easiest way to catch a fish, right?")
|
|
elif self.db.spoken == 201:
|
|
self.at_say("Have someone toss it to you.")
|
|
elif self.db.spoken == 205:
|
|
self.at_say("Ouch. Tough crowd.")
|
|
elif self.db.spoken == 300:
|
|
self.at_say("Me and my friends started a musical band.")
|
|
elif self.db.spoken == 301:
|
|
self.at_say("We all play bass.")
|
|
elif self.db.spoken == 302:
|
|
self.at_say("Alright guys, I said, drop the instruments. We are singing aquapella.")
|
|
elif self.db.spoken == 400:
|
|
self.at_say("Did you meet the owners of that new fishing store?")
|
|
elif self.db.spoken == 401:
|
|
self.at_say("Their names are Rod and Annette.")
|
|
elif self.db.spoken == 800:
|
|
self.at_say("I'm not that smart.")
|
|
elif self.db.spoken == 801:
|
|
self.at_say("My friends tell me I'm a dumb bass.")
|
|
elif self.db.spoken == 803:
|
|
self.at_say("Sorry for all the puns. I feel so GILL-ty.")
|
|
|
|
# Let's attempt to tell a bad joke once a day:
|
|
elif self.db.spoken > 1000 and self.db.spoken % (24 * 60 * 60 / self.fish_tick) == 0:
|
|
self.at_say(get_joke())
|
|
self.db.spoken += 1
|
|
|
|
def do_delete(self, fisher):
|
|
"""
|
|
A visual way to delete the fish.
|
|
"""
|
|
if fisher.location.key == "Lazy Dock" or fisher.location.key == "Shore":
|
|
fisher.announce_action("$You() <<$conj(toss) ^ $conj(heave) ^ $conj(throw)>> the fish back into the <<water ^ sea>>.")
|
|
fisher.location.msg_contents("The fish says, \"Bye for now. If you want to talk again, just drop me a line!\"")
|
|
else:
|
|
fisher.msg(routput("You <<toss ^ heave ^ throw>> the fish, and an << eagle ^ hawk >> swoops << down ^ >> and snatches it. I'm sure it will carry the fish back to the sea for you."))
|
|
self.delete()
|
|
|
|
def get_name():
|
|
return random.choice([
|
|
"Bennie", "Flipper", "Finegan", "Count Bassie"
|
|
])
|
|
|
|
def get_desc():
|
|
return routput(random.choice([
|
|
"A walleye with big bulbous eyes that clearly doesn't get no respect.",
|
|
"A bass with amazing neck confidence giving it a most excellent head bob.",
|
|
"A rainbow trout missing the <<red ^ yellow ^ green ^ blue>> from its iridescent stripe.",
|
|
"A brown trout colored <<red ^ blue ^ purple ^ orange>>.",
|
|
# "A spiny perch",
|
|
# "A salmon",
|
|
# "A pike",
|
|
]))
|
|
|
|
|
|
def get_joke():
|
|
"Fetch a random joke from the internet."
|
|
r = requests.get("https://icanhazdadjoke.com/",
|
|
headers={'Accept':'text/plain'})
|
|
return r.text
|
|
|
|
|
|
class FishingPole(Object):
|
|
"""
|
|
Can produce a Fish.
|
|
"""
|
|
failure_msgs = [
|
|
"$You() $conj(reel) in an empty line.",
|
|
"$You() didn't catch anything.",
|
|
"$You() caught nothing but a bit of weeds, yeck.",
|
|
"$You() caught nothing, but this sure is enjoyable.",
|
|
"Did $you() catch a boot? Nah, the fishing isn't even that good.",
|
|
"While $you() didn't catch anything, could there be anything better that sitting on the dock of the bay? Watching the clouds roll away?",
|
|
]
|
|
|
|
def at_object_creation(self):
|
|
self.cmdset.add_default(CmdSetFishing)
|
|
|
|
def do_use(self, user, _):
|
|
if self.location != user:
|
|
user.announce_action("$You() $conj(pick) up the pole to go fishing.")
|
|
delay(6, user.announce_action, "$You() $conj(return) the pole << next to the chair ^ >>.")
|
|
if self.do_cast(user):
|
|
delay(5, self.do_reel, user)
|
|
|
|
def do_cast(self, fisher):
|
|
if fisher.location.key != "Lazy Dock" and fisher.location.key != "Shore":
|
|
fisher.msg("You can't do that without being near a large body of water.")
|
|
return False
|
|
elif fisher.db.fishing == Fishing.CAST:
|
|
fisher.msg("You need to reel the line in first.")
|
|
return False
|
|
else:
|
|
fisher.db.fishing = Fishing.CAST
|
|
fisher.announce_action(routput(random.choice([
|
|
"$You() $conj(cast) << out ^ >> << far ^ >> into the <<water ^ sea>>.",
|
|
"$You() $conj(cast) close to the <<dock ^ shore>>.",
|
|
"$You() $conj(cast) off to the <<right ^ left>> where you <<think you ^ >> see a dark pocket.",
|
|
])))
|
|
return True
|
|
|
|
def do_reel(self, fisher):
|
|
if fisher.db.fishing != Fishing.CAST:
|
|
fisher.msg("You need to |gcast|n before you can reel the line back in.")
|
|
else:
|
|
fisher.db.fishing = Fishing.REEL
|
|
if random.randint(1, 100) < 35:
|
|
self.give_fish(fisher)
|
|
else:
|
|
fisher.announce_action(random.choice(self.failure_msgs))
|
|
|
|
def give_fish(self, fisher):
|
|
fish = spawn({
|
|
"typeclass": self.db.make_class or "typeclasses.fishing.Fish",
|
|
"key": "fish",
|
|
"aliases": [Fish.get_name()],
|
|
"desc": Fish.get_desc(),
|
|
})[0]
|
|
fish.location = fisher
|
|
fisher.announce_action(f"$You() caught a fish!")
|
|
fisher.score(Scores.catch_fish)
|