|
|
|
|
@ -6,7 +6,7 @@ import sys
|
|
|
|
|
from os import listdir, path
|
|
|
|
|
# from os.path import join, isfile
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
from random import choice
|
|
|
|
|
from random import choice, randint
|
|
|
|
|
from re import match, IGNORECASE
|
|
|
|
|
from time import time
|
|
|
|
|
|
|
|
|
|
@ -72,9 +72,9 @@ class ChatBot(AI, Puppet):
|
|
|
|
|
return details
|
|
|
|
|
|
|
|
|
|
def other_say(self, speaker, speech):
|
|
|
|
|
logger.info(f"Chatbot hears: '{speech}' from {speaker}.")
|
|
|
|
|
logger.info(f"Characters: {self.characters_here()}")
|
|
|
|
|
if len(self.characters_here()) == 1:
|
|
|
|
|
# logger.info(f"chatbot hears: '{speech}' from {speaker}.")
|
|
|
|
|
# logger.info(f"characters: {self.characters_here(puppets=True)}")
|
|
|
|
|
if len(self.characters_here(puppets=True)) == 1:
|
|
|
|
|
self.other_sayto(speaker, speech)
|
|
|
|
|
|
|
|
|
|
def other_sayto(self, speaker, speech):
|
|
|
|
|
@ -92,269 +92,42 @@ class ChatBot(AI, Puppet):
|
|
|
|
|
super().at_msg_receive(text, from_obj=from_obj, **kwargs)
|
|
|
|
|
self.db.last_event_time = time()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Bartender(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
Like any other Chatbot, but this one hears and responds to
|
|
|
|
|
more things.
|
|
|
|
|
"""
|
|
|
|
|
def backstory(self, personality):
|
|
|
|
|
personality_file = personality + ".md"
|
|
|
|
|
filename = Path(path.join(personality_dir, personality_file))
|
|
|
|
|
if filename.exists():
|
|
|
|
|
self.db.personality = filename.stem
|
|
|
|
|
self.db.personality_file = filename
|
|
|
|
|
|
|
|
|
|
def other_say(self, speaker, speech):
|
|
|
|
|
logger.info(f"Bartender hears: '{speech}' from {speaker}.")
|
|
|
|
|
if len(self.characters_here()) == 3 or \
|
|
|
|
|
match(r".*\b(bartend|barkeep|elendil).*", speech, IGNORECASE):
|
|
|
|
|
self.other_sayto(speaker, speech)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Witch(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
@update Trampoli = typeclasses.chatbots.Witch
|
|
|
|
|
@set/delete Trampoli/arrive
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def visit(self):
|
|
|
|
|
self.execute_cmd("pose reset")
|
|
|
|
|
|
|
|
|
|
hut = self.location
|
|
|
|
|
delay(1, hut.msg_contents,
|
|
|
|
|
"The old lady says, \"I must be off now, dearie, to visit an old friend.\"")
|
|
|
|
|
delay(5, hut.msg_contents,
|
|
|
|
|
"She grabs and old broom, and flies out the door!")
|
|
|
|
|
|
|
|
|
|
dest = self.search("mp04", global_search=True)
|
|
|
|
|
delay(6, self.move_to, dest, quiet=True)
|
|
|
|
|
|
|
|
|
|
delay(7, dest.msg_contents,
|
|
|
|
|
"An old lady flies in on a broom.")
|
|
|
|
|
delay(10, dest.msg_contents,
|
|
|
|
|
"The old lady says, \"Hello Dearie, I'm just here to visit an old friend.\"")
|
|
|
|
|
|
|
|
|
|
knocker = self.search("knocker", global_search=True, location=dest)
|
|
|
|
|
delay(14, knocker.do_knock, self)
|
|
|
|
|
delay(20, dest.msg_contents,
|
|
|
|
|
"\"I think I heard a 'come in',\" says the old lady. \"You heard it too, right?\"")
|
|
|
|
|
|
|
|
|
|
home = self.search("mp03", global_search=True)
|
|
|
|
|
delay(24, self.move_to, home)
|
|
|
|
|
|
|
|
|
|
delay(30, home.msg_contents,
|
|
|
|
|
"\"Now this looks cheery,\" says the old lady, as she places her broom by the door. \"I do believe we are in for a spell of rain.\"")
|
|
|
|
|
|
|
|
|
|
def leave(self):
|
|
|
|
|
self.location.msg_contents("The old lady wraps her shawl tightly around her, and grabs her broom. \"I must be getting home now, dear,\" she says.")
|
|
|
|
|
|
|
|
|
|
dest = self.search("mp04", global_search=True)
|
|
|
|
|
delay(2, self.move_to, dest)
|
|
|
|
|
delay(4, dest.msg_contents,
|
|
|
|
|
"The old lady hops on her broomstick and flies away.")
|
|
|
|
|
|
|
|
|
|
hut = self.search("mp09", global_search=True)
|
|
|
|
|
delay(5, self.move_to, hut, quiet=True)
|
|
|
|
|
delay(6, hut.msg_contents,
|
|
|
|
|
"And old lady flies through the door on her broomstick! \"Hello dearies!\" she exclaims to everyone and everything in her homey hut. \"I have returned from visiting my friend. What have I missed while I was away?\"")
|
|
|
|
|
|
|
|
|
|
sleep_pose = self.attributes.get("pose_sleep")
|
|
|
|
|
if sleep_pose:
|
|
|
|
|
self.execute_cmd(f"pose {sleep_pose}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Traveler(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
Needs to walk from room to room, and greets characters.
|
|
|
|
|
"""
|
|
|
|
|
traveling_path = {}
|
|
|
|
|
|
|
|
|
|
def other_arrive(self, character):
|
|
|
|
|
"""
|
|
|
|
|
Greet a character when it arrives.
|
|
|
|
|
"""
|
|
|
|
|
self.greet(character)
|
|
|
|
|
if character != self:
|
|
|
|
|
delay(4, self.greet, character)
|
|
|
|
|
|
|
|
|
|
def at_post_move(self, past_location, move_type="move", **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Call the 'greet' method.
|
|
|
|
|
"""
|
|
|
|
|
super().at_post_move(past_location, move_type)
|
|
|
|
|
chars = [c for c in self.characters_here() if c.key != 'tree']
|
|
|
|
|
chars = self.characters_here()
|
|
|
|
|
|
|
|
|
|
if len(chars) == 1:
|
|
|
|
|
self.greet(chars[0])
|
|
|
|
|
else:
|
|
|
|
|
self.greet()
|
|
|
|
|
delay(4, self.greet, chars[0])
|
|
|
|
|
elif len(chars) > 1:
|
|
|
|
|
delay(3, self.greet)
|
|
|
|
|
|
|
|
|
|
def greet(self, character=None):
|
|
|
|
|
delay(2, self.do_cmd, "emote waves.")
|
|
|
|
|
|
|
|
|
|
def goodbye(self, character=None):
|
|
|
|
|
delay(2, self.do_cmd, "emote waves good-bye.")
|
|
|
|
|
|
|
|
|
|
def change_direction(self):
|
|
|
|
|
"""
|
|
|
|
|
Hard coded directional change, east <-> west
|
|
|
|
|
Note: Change with the command:
|
|
|
|
|
|
|
|
|
|
@set npc/traveling_direction = "come"
|
|
|
|
|
"""
|
|
|
|
|
self.at_say("Well, I must be going.")
|
|
|
|
|
if self.db.traveling_direction == "east":
|
|
|
|
|
self.db.traveling_direction = "west"
|
|
|
|
|
else:
|
|
|
|
|
self.db.traveling_direction = "east"
|
|
|
|
|
logger.info(f"{self.db.traveling_direction}")
|
|
|
|
|
|
|
|
|
|
def come(self):
|
|
|
|
|
self.db.traveling_direction == "come"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Dragon(Traveler):
|
|
|
|
|
"""
|
|
|
|
|
Travels east-to-west along the path, and has a drink at the
|
|
|
|
|
Wyldwood Tavern.
|
|
|
|
|
"""
|
|
|
|
|
# self.db.direction = "east" # or west or whatever
|
|
|
|
|
|
|
|
|
|
traveling_path = {
|
|
|
|
|
"the Deep Forest": {
|
|
|
|
|
"east": "Grotto",
|
|
|
|
|
"come": "Grotto"
|
|
|
|
|
},
|
|
|
|
|
"Grotto": {
|
|
|
|
|
"east": "Grove of the Matriarchs",
|
|
|
|
|
"west": "the Deep Forest",
|
|
|
|
|
"come": "door"
|
|
|
|
|
},
|
|
|
|
|
"Grove of the Matriarchs": {
|
|
|
|
|
"east": "Frog Meadow",
|
|
|
|
|
"west": "Grotto",
|
|
|
|
|
"come": "Grotto"
|
|
|
|
|
},
|
|
|
|
|
"Frog Meadow": {
|
|
|
|
|
"east": "Glittering Glade",
|
|
|
|
|
"west": "Grove of the Matriarchs",
|
|
|
|
|
"come": "Grove of the Matriarchs"
|
|
|
|
|
},
|
|
|
|
|
"Glittering Glade": {
|
|
|
|
|
"east": "Wyldwood Bar",
|
|
|
|
|
"west": "Frog Meadow",
|
|
|
|
|
"come": "Frog Meadow"
|
|
|
|
|
},
|
|
|
|
|
"Wyldwood Bar": {
|
|
|
|
|
"west": "Glittering Glade",
|
|
|
|
|
"come": "Glittering Glade"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def at_pre_move(self, destination, move_type="move", **kwargs):
|
|
|
|
|
if self.location.key == "Wyldwood Bar":
|
|
|
|
|
self.location.msg_contents("The little dragon tips his wide-brimmed and says, \"A pleasure, but I must be off.\"")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def at_post_move(self, past_location, move_type="move", **kwargs):
|
|
|
|
|
# super().at_post_move(past_location, move_type)
|
|
|
|
|
if self.location.key == "Wyldwood Bar":
|
|
|
|
|
request = choice([
|
|
|
|
|
"a Moonlit Mirage",
|
|
|
|
|
"Puck's Revenge",
|
|
|
|
|
"a Glimmering Gossamer",
|
|
|
|
|
"a Whimsical Willow",
|
|
|
|
|
"a Charmed Chalice",
|
|
|
|
|
"an Enchanted Elixir",
|
|
|
|
|
"a Sylvan Serenade",
|
|
|
|
|
"a Brambleberry Bliss",
|
|
|
|
|
"a Twilight Tonic",
|
|
|
|
|
])
|
|
|
|
|
self.process_thoughts(f"""The little dragon flutters over to the bar, studying the menu. "What am I in the mood for now?" he muses to himself, twiddling a tendril like a mustache with his little claw.
|
|
|
|
|
|
|
|
|
|
"Elendil, dear," he says, "Would you make me {request}?" The little dragon then waves to the band on their mushroom stage.""")
|
|
|
|
|
bartender = self.search("bartender")
|
|
|
|
|
bartender.other_sayto(self,
|
|
|
|
|
f"\"Sir Roblees, the fairy dragon asks, \"Would you make me {request}?\"")
|
|
|
|
|
# from typeclasses.drinkables import Cocktail
|
|
|
|
|
# Cocktail.make(self, bartender, request)
|
|
|
|
|
|
|
|
|
|
def greet(self, character=None):
|
|
|
|
|
logger.info(f"Dragon: greet {character}")
|
|
|
|
|
if character:
|
|
|
|
|
name = character.get_name()
|
|
|
|
|
cmd = choice([
|
|
|
|
|
f"emote \"Hey, {name},\" /me says.",
|
|
|
|
|
f"emote \"Hey there, {name},\" /me says.",
|
|
|
|
|
f"emote \"Hello, {name},\" /me says. \"How are you?\"",
|
|
|
|
|
f"emote waves to {name}."
|
|
|
|
|
])
|
|
|
|
|
else:
|
|
|
|
|
cmd = choice([
|
|
|
|
|
"say Look at all these luscious peoples.",
|
|
|
|
|
"emote waves to everyone.",
|
|
|
|
|
"emote waves to everybody."
|
|
|
|
|
])
|
|
|
|
|
delay(5, self.do_cmd, cmd)
|
|
|
|
|
|
|
|
|
|
def goodbye(self, new_room=None):
|
|
|
|
|
self.do_cmd("drop drink")
|
|
|
|
|
system_prompt = self.setting_and_backstory()
|
|
|
|
|
messages = [{"role": "user", "content": "Say goodbye."}]
|
|
|
|
|
reply = self._think(system_prompt, messages)
|
|
|
|
|
self.process_thoughts(reply)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TravelingNPC(Script):
|
|
|
|
|
"""
|
|
|
|
|
Script to move NPCs along a set path through "rooms".
|
|
|
|
|
|
|
|
|
|
Start the script by running the following:
|
|
|
|
|
|
|
|
|
|
@script npc = typeclasses.scripts.Muttering
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def at_script_creation(self):
|
|
|
|
|
self.key = "Traveling"
|
|
|
|
|
self.desc = "NPCs that Move"
|
|
|
|
|
self.interval = self.obj.db.traveling_interval or 120 # seconds
|
|
|
|
|
self.start_delay = False
|
|
|
|
|
self.persistent = True
|
|
|
|
|
self.reload()
|
|
|
|
|
|
|
|
|
|
def reload(self):
|
|
|
|
|
self.obj.db.last_event_time = time()
|
|
|
|
|
|
|
|
|
|
def at_repeat(self, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Do we move or stay for another iteration?
|
|
|
|
|
"""
|
|
|
|
|
# What can keep a traveling NPC from traveling?
|
|
|
|
|
# What if receiving ANY message resets a timer?
|
|
|
|
|
elapsed_time = time() - self.obj.db.last_event_time
|
|
|
|
|
logger.info(f"TravelingNPC: {elapsed_time} > {3 * 60}")
|
|
|
|
|
# Time needs to be a little longer than the repeat interval.
|
|
|
|
|
if elapsed_time >= 20 * 60:
|
|
|
|
|
self.goodbye()
|
|
|
|
|
self.obj.change_direction()
|
|
|
|
|
|
|
|
|
|
elif elapsed_time >= 3 * 60:
|
|
|
|
|
direction_label = self.obj.db.traveling_direction
|
|
|
|
|
location_details = self.obj.traveling_path.get(self.obj.location.key)
|
|
|
|
|
if location_details:
|
|
|
|
|
logger.info(f"TravelingNPC: {direction_label} :: {location_details}")
|
|
|
|
|
room_name = location_details.get(direction_label)
|
|
|
|
|
if room_name:
|
|
|
|
|
logger.info(f"TravelingNPC: to -> {room_name}")
|
|
|
|
|
new_room = self.obj.search(room_name, global_search=True)
|
|
|
|
|
if new_room:
|
|
|
|
|
logger.info(f"TravelingNPC: to -> {new_room}")
|
|
|
|
|
# Say See ya if it had engaged...
|
|
|
|
|
self.obj.goodbye(new_room)
|
|
|
|
|
delay(5, self.obj.move_to, new_room, move_type="teleport")
|
|
|
|
|
# This process will reset the timer
|
|
|
|
|
|
|
|
|
|
class Bartender(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
Like any other Chatbot, but this one hears and responds to
|
|
|
|
|
more things.
|
|
|
|
|
"""
|
|
|
|
|
def greet(self, character=None):
|
|
|
|
|
if character:
|
|
|
|
|
self.announce_action(f"\"Welcome to the |wWyldwood Bar|n,\" the {self.get_name()} says to the {character.get_name()}, \"Drink list is on the sign.\"")
|
|
|
|
|
|
|
|
|
|
def backstory(self, personality):
|
|
|
|
|
"""
|
|
|
|
|
This overshadows the 'backstory' in the parent Chatbot class.
|
|
|
|
|
|
|
|
|
|
TODO The backstory does too much, and we may want this to be the
|
|
|
|
|
other approach.
|
|
|
|
|
"""
|
|
|
|
|
personality_file = personality + ".md"
|
|
|
|
|
filename = Path(path.join(personality_dir, personality_file))
|
|
|
|
|
if filename.exists():
|
|
|
|
|
@ -363,7 +136,7 @@ class Bartender(ChatBot):
|
|
|
|
|
|
|
|
|
|
def other_say(self, speaker, speech):
|
|
|
|
|
logger.info(f"Bartender hears: '{speech}' from {speaker}.")
|
|
|
|
|
if len(self.characters_here()) == 3 or \
|
|
|
|
|
if len(self.characters_here(puppets=True)) == 3 or \
|
|
|
|
|
match(r".*\b(bartend|barkeep|elendil).*", speech, IGNORECASE):
|
|
|
|
|
self.other_sayto(speaker, speech)
|
|
|
|
|
|
|
|
|
|
@ -380,16 +153,16 @@ class Witch(ChatBot):
|
|
|
|
|
if character and character != self:
|
|
|
|
|
self.announce_action(f"Looking at the {character.sdesc.get()}, {self.get_name()} says, \"Oh, hello, dear. How are you?\"")
|
|
|
|
|
else:
|
|
|
|
|
self.announce_action(f"/me says, \"Hello, dears.\"")
|
|
|
|
|
self.announce_action(f"The {self.get_name()} says, \"Hello, dears.\"")
|
|
|
|
|
|
|
|
|
|
def goodbye(self, character=None):
|
|
|
|
|
delay(2, self.do_cmd, "As she hops on her broom, the little old lady says, \"Well, I must be off.\"")
|
|
|
|
|
delay(2, self.do_cmd, "As she grabs her broom, the little old lady says, \"Well, I must be off.\"")
|
|
|
|
|
|
|
|
|
|
def other_arrive(self, character):
|
|
|
|
|
"""
|
|
|
|
|
Greet a character when it arrives.
|
|
|
|
|
"""
|
|
|
|
|
delay(4, self.greet, character)
|
|
|
|
|
def next_place(self):
|
|
|
|
|
# In not in the Cozy House, Hut, or the Bar, leave:
|
|
|
|
|
if not any(self.location.aliases.get(fav)
|
|
|
|
|
for fav in ["mp03", "mp09", "mp10"]):
|
|
|
|
|
self.leave()
|
|
|
|
|
|
|
|
|
|
def change_direction(self):
|
|
|
|
|
"""
|
|
|
|
|
@ -400,14 +173,16 @@ class Witch(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
if any(self.location.aliases.get(fav)
|
|
|
|
|
for fav in ["mp03", "mp10"]):
|
|
|
|
|
logger.info(f"Witchie is leaving, {self.location}")
|
|
|
|
|
self.leave()
|
|
|
|
|
else:
|
|
|
|
|
logger.info(f"Witchie needs to take off...")
|
|
|
|
|
# Let's go out for a bit ...
|
|
|
|
|
r = randint(100)
|
|
|
|
|
r = randint(1, 100)
|
|
|
|
|
if r < 3:
|
|
|
|
|
destination = "Cozy House"
|
|
|
|
|
elif r < 12:
|
|
|
|
|
destination = "Wyldwood Bar",
|
|
|
|
|
destination = "Wyldwood Bar"
|
|
|
|
|
else:
|
|
|
|
|
destination = choice([
|
|
|
|
|
"mp15", # Shore
|
|
|
|
|
@ -417,12 +192,6 @@ class Witch(ChatBot):
|
|
|
|
|
])
|
|
|
|
|
self.visit(destination)
|
|
|
|
|
|
|
|
|
|
def next_place(self):
|
|
|
|
|
# In not in the Cozy House, Hut, or the Bar, leave:
|
|
|
|
|
if not any(self.location.aliases.get(fav)
|
|
|
|
|
for fav in ["mp03", "mp09", "mp10"]):
|
|
|
|
|
self.leave()
|
|
|
|
|
|
|
|
|
|
def visit(self, location="Cozy House"):
|
|
|
|
|
self.execute_cmd("pose reset")
|
|
|
|
|
dest = self.search(location, global_search=True)
|
|
|
|
|
@ -441,7 +210,7 @@ class Witch(ChatBot):
|
|
|
|
|
delay(1, hut.msg_contents,
|
|
|
|
|
f"The old lady says, \"I must be off now, dearie, to {visit_reason}.\"")
|
|
|
|
|
delay(5, hut.msg_contents,
|
|
|
|
|
"She grabs and old broom, and flies out the door!")
|
|
|
|
|
"She grabs an old broom, and flies out the door!")
|
|
|
|
|
|
|
|
|
|
marsh = self.search("mp08", global_search=True)
|
|
|
|
|
delay(5, marsh.msg_contents,
|
|
|
|
|
@ -452,11 +221,16 @@ class Witch(ChatBot):
|
|
|
|
|
knocker = self.search("knocker", global_search=True,
|
|
|
|
|
location=landing)
|
|
|
|
|
delay(14, knocker.do_knock, self)
|
|
|
|
|
delay(20, landing.msg_contents,
|
|
|
|
|
"\"I think I heard a 'come in',\" says the old lady. \"You heard it too, right?\"")
|
|
|
|
|
delay(24, self.move_to, dest)
|
|
|
|
|
delay(30, dest.msg_contents,
|
|
|
|
|
"\"Now this looks cheery,\" says the old lady, as she places her broom by the door. \"I do believe we are in for a spell of rain.\"")
|
|
|
|
|
if len(dest.characters_here()) > 0:
|
|
|
|
|
delay(20, landing.msg_contents,
|
|
|
|
|
"\"I think I heard a 'come in',\" says the old lady. \"You heard it too, right?\"")
|
|
|
|
|
delay(24, self.move_to, dest)
|
|
|
|
|
delay(30, dest.msg_contents,
|
|
|
|
|
"\"Now this looks cheery,\" says the old lady, as she places her broom by the door. \"I do believe we are in for a spell of rain.\"")
|
|
|
|
|
else:
|
|
|
|
|
delay(20, landing.msg_contents,
|
|
|
|
|
"\"I guess no one is home, eh?\" says the old lady.")
|
|
|
|
|
delay(23, self.leave)
|
|
|
|
|
|
|
|
|
|
elif dest.key == "Wyldwood Bar":
|
|
|
|
|
landing = self.search("mp19", global_search=True)
|
|
|
|
|
@ -487,30 +261,30 @@ class Witch(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
Dramatic departures from the current location.
|
|
|
|
|
"""
|
|
|
|
|
self.location.msg_contents("The old lady wraps her shawl tightly around her, and grabs her broom. \"I must be getting home now, dear,\" she says.")
|
|
|
|
|
self.location.msg_contents("The old lady wraps her shawl tightly around her, and grabs her broom. \"I must be getting home now,\" she says.")
|
|
|
|
|
|
|
|
|
|
visit_reason = "foraging"
|
|
|
|
|
launch_site = self.location
|
|
|
|
|
|
|
|
|
|
if "mp03" in self.location.aliases.get():
|
|
|
|
|
visit_reason = "visiting my friend"
|
|
|
|
|
here = self.search("mp04", global_search=True)
|
|
|
|
|
delay(2, self.move_to, here)
|
|
|
|
|
launch_site = self.search("mp04", global_search=True)
|
|
|
|
|
delay(2, self.move_to, launch_site)
|
|
|
|
|
if "mp10" in self.location.aliases.get():
|
|
|
|
|
visit_reason = "visiting my friends at the bar"
|
|
|
|
|
here = self.search("mp19", global_search=True)
|
|
|
|
|
delay(2, self.move_to, here)
|
|
|
|
|
else:
|
|
|
|
|
visit_reason = "foraging"
|
|
|
|
|
here = self.location
|
|
|
|
|
launch_site = self.search("mp19", global_search=True)
|
|
|
|
|
delay(2, self.move_to, launch_site)
|
|
|
|
|
|
|
|
|
|
delay(4, here.msg_contents,
|
|
|
|
|
delay(6, launch_site.msg_contents,
|
|
|
|
|
"The old lady hops on her broomstick and flies away through the trees.\"")
|
|
|
|
|
|
|
|
|
|
marsh = self.search("mp08", global_search=True)
|
|
|
|
|
delay(5, marsh.msg_contents,
|
|
|
|
|
delay(6, marsh.msg_contents,
|
|
|
|
|
"An old lady flies through the air on her broomstick, and right into the hut on stilts!")
|
|
|
|
|
|
|
|
|
|
hut = self.search("mp09", global_search=True)
|
|
|
|
|
delay(6, self.move_to, hut, quiet=True)
|
|
|
|
|
delay(7, hut.msg_contents,
|
|
|
|
|
delay(7, self.move_to, hut, quiet=True)
|
|
|
|
|
delay(8, hut.msg_contents,
|
|
|
|
|
f"An old lady flies through the door on her broomstick! \"Hello dearies!\" she exclaims to everyone and everything in her homey hut. \"I have returned from {visit_reason}. What have I missed while I was away?\"")
|
|
|
|
|
|
|
|
|
|
sleep_pose = self.attributes.get("pose_sleep")
|
|
|
|
|
@ -524,33 +298,11 @@ class Traveler(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
traveling_path = {}
|
|
|
|
|
|
|
|
|
|
def at_msg_receive(self, text=None, from_obj=None, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Reset the timer whenever we get any event.
|
|
|
|
|
This might be too much.
|
|
|
|
|
"""
|
|
|
|
|
super().at_msg_receive(text, from_obj=from_obj, **kwargs)
|
|
|
|
|
self.db.last_event_time = time()
|
|
|
|
|
|
|
|
|
|
def other_arrive(self, character):
|
|
|
|
|
"""
|
|
|
|
|
Greet a character when it arrives.
|
|
|
|
|
"""
|
|
|
|
|
self.greet(character)
|
|
|
|
|
|
|
|
|
|
def at_post_move(self, past_location, move_type="move", **kwargs):
|
|
|
|
|
super().at_post_move(past_location, move_type)
|
|
|
|
|
chars = [c for c in self.characters_here() if c.key != 'tree']
|
|
|
|
|
if len(chars) == 1:
|
|
|
|
|
self.greet(chars[0])
|
|
|
|
|
else:
|
|
|
|
|
self.greet()
|
|
|
|
|
|
|
|
|
|
def greet(self, character=None):
|
|
|
|
|
delay(2, self.do_cmd, "emote waves.")
|
|
|
|
|
self.do_cmd("emote waves.")
|
|
|
|
|
|
|
|
|
|
def goodbye(self, character=None):
|
|
|
|
|
delay(2, self.do_cmd, "emote waves good-bye.")
|
|
|
|
|
self.do_cmd("emote waves good-bye.")
|
|
|
|
|
|
|
|
|
|
def change_direction(self):
|
|
|
|
|
"""
|
|
|
|
|
@ -565,7 +317,7 @@ class Traveler(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
Set traveling to a particular given direction.
|
|
|
|
|
"""
|
|
|
|
|
self.db.traveling_direction == direction
|
|
|
|
|
self.db.traveling_direction = direction
|
|
|
|
|
|
|
|
|
|
def leave(self):
|
|
|
|
|
"""
|
|
|
|
|
@ -587,8 +339,8 @@ class Traveler(ChatBot):
|
|
|
|
|
logger.info(f"TravelingNPC: to -> {new_room}")
|
|
|
|
|
# Say See ya if it had engaged...
|
|
|
|
|
self.goodbye(new_room)
|
|
|
|
|
delay(5, self.move_to, new_room, move_type="teleport")
|
|
|
|
|
# This process will reset the timer
|
|
|
|
|
delay(5, self.move_to, new_room, move_type="teleport")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Dragon(Traveler):
|
|
|
|
|
@ -645,27 +397,29 @@ class Dragon(Traveler):
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def at_post_move(self, past_location, move_type="move", **kwargs):
|
|
|
|
|
# super().at_post_move(past_location, move_type)
|
|
|
|
|
if self.location.key == "Wyldwood Bar":
|
|
|
|
|
request = choice([
|
|
|
|
|
"a Moonlit Mirage",
|
|
|
|
|
"Puck's Revenge",
|
|
|
|
|
"a Glimmering Gossamer",
|
|
|
|
|
"a Whimsical Willow",
|
|
|
|
|
"a Charmed Chalice",
|
|
|
|
|
"an Enchanted Elixir",
|
|
|
|
|
"a Sylvan Serenade",
|
|
|
|
|
"a Brambleberry Bliss",
|
|
|
|
|
"a Twilight Tonic",
|
|
|
|
|
])
|
|
|
|
|
self.process_thoughts(f"""The little dragon flutters over to the bar, studying the menu. "What am I in the mood for now?" he muses to himself, twiddling a tendril like a mustache with his little claw.
|
|
|
|
|
if self.location.key != "Wyldwood Bar":
|
|
|
|
|
super().at_post_move(past_location, move_type)
|
|
|
|
|
else:
|
|
|
|
|
if len(self.characters_here()) > 0:
|
|
|
|
|
request = choice([
|
|
|
|
|
"a Moonlit Mirage",
|
|
|
|
|
"Puck's Revenge",
|
|
|
|
|
"a Glimmering Gossamer",
|
|
|
|
|
"a Whimsical Willow",
|
|
|
|
|
"a Charmed Chalice",
|
|
|
|
|
"an Enchanted Elixir",
|
|
|
|
|
"a Sylvan Serenade",
|
|
|
|
|
"a Brambleberry Bliss",
|
|
|
|
|
"a Twilight Tonic",
|
|
|
|
|
])
|
|
|
|
|
self.process_thoughts(f"""The little dragon flutters over to the bar, studying the menu. "What am I in the mood for now?" he muses to himself, twiddling a tendril like a mustache with his little claw.
|
|
|
|
|
|
|
|
|
|
"Elendil, dear," he says, "Would you make me {request}?" The little dragon then waves to the band on their mushroom stage.""")
|
|
|
|
|
bartender = self.search("bartender")
|
|
|
|
|
bartender.other_sayto(self,
|
|
|
|
|
f"\"Sir Roblees, the fairy dragon asks, \"Would you make me {request}?\"")
|
|
|
|
|
# from typeclasses.drinkables import Cocktail
|
|
|
|
|
# Cocktail.make(self, bartender, request)
|
|
|
|
|
bartender = self.search("bartender")
|
|
|
|
|
bartender.other_sayto(self,
|
|
|
|
|
f"\"Sir Roblees, the fairy dragon asks, \"Would you make me {request}?\"")
|
|
|
|
|
# from typeclasses.drinkables import Cocktail
|
|
|
|
|
# Cocktail.make(self, bartender, request)
|
|
|
|
|
|
|
|
|
|
def greet(self, character=None):
|
|
|
|
|
logger.info(f"Dragon: greet {character}")
|
|
|
|
|
@ -686,7 +440,8 @@ class Dragon(Traveler):
|
|
|
|
|
delay(5, self.do_cmd, cmd)
|
|
|
|
|
|
|
|
|
|
def goodbye(self, new_room=None):
|
|
|
|
|
self.do_cmd("drop drink")
|
|
|
|
|
if self.location.key == "Wyldwood Bar":
|
|
|
|
|
self.do_cmd("drop drink")
|
|
|
|
|
system_prompt = self.setting_and_backstory()
|
|
|
|
|
messages = [{"role": "user", "content": "Say goodbye."}]
|
|
|
|
|
reply = self._think(system_prompt, messages)
|
|
|
|
|
@ -719,348 +474,13 @@ class TravelingNPC(Script):
|
|
|
|
|
"""
|
|
|
|
|
# What can keep a traveling NPC from traveling?
|
|
|
|
|
# What if receiving ANY message resets a timer?
|
|
|
|
|
elapsed_time = time() - self.obj.db.last_event_time
|
|
|
|
|
elapsed_time = int(time() - self.obj.db.last_event_time)
|
|
|
|
|
# Time needs to be a little longer than the repeat interval.
|
|
|
|
|
if elapsed_time >= 20 * 60:
|
|
|
|
|
logger.info(f"TravelingNPC: Long: {elapsed_time} > {20 * 60}")
|
|
|
|
|
logger.info(f"TravelingNPC({self.obj}): Long- {elapsed_time} > {20 * 60}")
|
|
|
|
|
self.obj.goodbye()
|
|
|
|
|
self.obj.change_direction()
|
|
|
|
|
|
|
|
|
|
elif elapsed_time >= 3 * 60:
|
|
|
|
|
logger.info(f"TravelingNPC: Short: {elapsed_time} > {3 * 60}")
|
|
|
|
|
self.obj.next_place()
|
|
|
|
|
|
|
|
|
|
def change_direction(self):
|
|
|
|
|
"""
|
|
|
|
|
Hard coded directional change, east <-> west
|
|
|
|
|
Note: Change with the command:
|
|
|
|
|
|
|
|
|
|
@set npc/traveling_direction = "come"
|
|
|
|
|
"""
|
|
|
|
|
if any(self.location.aliases.get(fav)
|
|
|
|
|
for fav in ["mp03", "mp10"]):
|
|
|
|
|
self.leave()
|
|
|
|
|
else:
|
|
|
|
|
# Let's go out for a bit ...
|
|
|
|
|
destination = choice([
|
|
|
|
|
"Cozy House",
|
|
|
|
|
"Wyldwood Bar",
|
|
|
|
|
"mp15", # Shore
|
|
|
|
|
"Frog Meadow",
|
|
|
|
|
"Boulder Top",
|
|
|
|
|
"Lonely Island"
|
|
|
|
|
])
|
|
|
|
|
self.visit(destination)
|
|
|
|
|
|
|
|
|
|
def next_place(self):
|
|
|
|
|
# In not in the Cozy House, Hut, or the Bar, leave:
|
|
|
|
|
if not any(self.location.aliases.get(fav)
|
|
|
|
|
for fav in ["mp03", "mp09", "mp10"]):
|
|
|
|
|
self.leave()
|
|
|
|
|
|
|
|
|
|
def visit(self, location="Cozy House"):
|
|
|
|
|
self.execute_cmd("pose reset")
|
|
|
|
|
dest = self.search(location, global_search=True)
|
|
|
|
|
if not dest:
|
|
|
|
|
logger.warn(f"Witch attempting to go to unknown {location}.")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if dest.key == "Cozy House":
|
|
|
|
|
visit_reason = "visit an old friend"
|
|
|
|
|
elif dest.key == "Wyldwood Bar":
|
|
|
|
|
visit_reason = "grab a pint"
|
|
|
|
|
else:
|
|
|
|
|
visit_reason = "forage for ingredients"
|
|
|
|
|
|
|
|
|
|
hut = self.location
|
|
|
|
|
delay(1, hut.msg_contents,
|
|
|
|
|
f"The old lady says, \"I must be off now, dearie, to {visit_reason}.\"")
|
|
|
|
|
delay(5, hut.msg_contents,
|
|
|
|
|
"She grabs and old broom, and flies out the door!")
|
|
|
|
|
|
|
|
|
|
marsh = self.search("mp08", global_search=True)
|
|
|
|
|
delay(5, marsh.msg_contents,
|
|
|
|
|
"An old lady flies out the hut on a broomstick!")
|
|
|
|
|
|
|
|
|
|
if dest.key == "Cozy House":
|
|
|
|
|
landing = self.search("mp04", global_search=True)
|
|
|
|
|
knocker = self.search("knocker", global_search=True,
|
|
|
|
|
location=landing)
|
|
|
|
|
delay(14, knocker.do_knock, self)
|
|
|
|
|
delay(20, landing.msg_contents,
|
|
|
|
|
"\"I think I heard a 'come in',\" says the old lady. \"You heard it too, right?\"")
|
|
|
|
|
delay(24, self.move_to, dest)
|
|
|
|
|
delay(30, dest.msg_contents,
|
|
|
|
|
"\"Now this looks cheery,\" says the old lady, as she places her broom by the door. \"I do believe we are in for a spell of rain.\"")
|
|
|
|
|
|
|
|
|
|
elif dest.key == "Wyldwood Bar":
|
|
|
|
|
landing = self.search("mp19", global_search=True)
|
|
|
|
|
delay(14, landing.execute_cmd, "say This young thing needs a drink")
|
|
|
|
|
delay(18, self.move_to, dest)
|
|
|
|
|
delay(30, dest.msg_contents, "The old lady saunters up to the bar, \"How about an ale, Barkeep?\" she asks.")
|
|
|
|
|
else:
|
|
|
|
|
landing = dest
|
|
|
|
|
if dest.key == "Shore":
|
|
|
|
|
ingredient = "yellow flowers from the pine tree"
|
|
|
|
|
elif dest.key == "Frog Meadow":
|
|
|
|
|
ingredient = "giggling tickleweed"
|
|
|
|
|
elif dest.key == "Boulder Top":
|
|
|
|
|
ingredient = "vibrant mushrooms"
|
|
|
|
|
elif dest.key == "Lonely Island":
|
|
|
|
|
ingredient = "blue moonberries"
|
|
|
|
|
delay(30, dest.msg_contents,
|
|
|
|
|
f"The lady looks around, gathers some {ingredient}" +
|
|
|
|
|
" and puts them in her basket.")
|
|
|
|
|
|
|
|
|
|
delay(6, self.move_to, landing, quiet=True)
|
|
|
|
|
delay(7, landing.msg_contents,
|
|
|
|
|
"An old lady flies in on a broom.")
|
|
|
|
|
delay(10, landing.msg_contents,
|
|
|
|
|
f"The old lady says, \"Hello Dearie, I'm just here to {visit_reason}.\"")
|
|
|
|
|
|
|
|
|
|
def leave(self):
|
|
|
|
|
"""
|
|
|
|
|
Dramatic departures from the current location.
|
|
|
|
|
"""
|
|
|
|
|
self.location.msg_contents("The old lady wraps her shawl tightly around her, and grabs her broom. \"I must be getting home now, dear,\" she says.")
|
|
|
|
|
|
|
|
|
|
if "mp03" in self.location.aliases.get():
|
|
|
|
|
visit_reason = "visiting my friend"
|
|
|
|
|
here = self.search("mp04", global_search=True)
|
|
|
|
|
delay(2, self.move_to, here)
|
|
|
|
|
if "mp10" in self.location.aliases.get():
|
|
|
|
|
visit_reason = "visiting my friends at the bar"
|
|
|
|
|
here = self.search("mp19", global_search=True)
|
|
|
|
|
delay(2, self.move_to, here)
|
|
|
|
|
else:
|
|
|
|
|
visit_reason = "foraging"
|
|
|
|
|
here = self.location
|
|
|
|
|
|
|
|
|
|
delay(4, here.msg_contents,
|
|
|
|
|
"The old lady hops on her broomstick and flies away through the trees.\"")
|
|
|
|
|
|
|
|
|
|
marsh = self.search("mp08", global_search=True)
|
|
|
|
|
delay(5, marsh.msg_contents,
|
|
|
|
|
"An old lady flies through the air on her broomstick, and right into the hut on stilts!")
|
|
|
|
|
|
|
|
|
|
hut = self.search("mp09", global_search=True)
|
|
|
|
|
delay(6, self.move_to, hut, quiet=True)
|
|
|
|
|
delay(7, hut.msg_contents,
|
|
|
|
|
f"An old lady flies through the door on her broomstick! \"Hello dearies!\" she exclaims to everyone and everything in her homey hut. \"I have returned from {visit_reason}. What have I missed while I was away?\"")
|
|
|
|
|
|
|
|
|
|
sleep_pose = self.attributes.get("pose_sleep")
|
|
|
|
|
if sleep_pose:
|
|
|
|
|
self.execute_cmd(f"pose {sleep_pose}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Traveler(ChatBot):
|
|
|
|
|
"""
|
|
|
|
|
Needs to walk from room to room, and greets characters.
|
|
|
|
|
"""
|
|
|
|
|
traveling_path = {}
|
|
|
|
|
|
|
|
|
|
def at_msg_receive(self, text=None, from_obj=None, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Reset the timer whenever we get any event.
|
|
|
|
|
This might be too much.
|
|
|
|
|
"""
|
|
|
|
|
super().at_msg_receive(text, from_obj=from_obj, **kwargs)
|
|
|
|
|
self.db.last_event_time = time()
|
|
|
|
|
|
|
|
|
|
def other_arrive(self, character):
|
|
|
|
|
"""
|
|
|
|
|
Greet a character when it arrives.
|
|
|
|
|
"""
|
|
|
|
|
self.greet(character)
|
|
|
|
|
|
|
|
|
|
def at_post_move(self, past_location, move_type="move", **kwargs):
|
|
|
|
|
super().at_post_move(past_location, move_type)
|
|
|
|
|
chars = [c for c in self.characters_here() if c.key != 'tree']
|
|
|
|
|
if len(chars) == 1:
|
|
|
|
|
self.greet(chars[0])
|
|
|
|
|
else:
|
|
|
|
|
self.greet()
|
|
|
|
|
|
|
|
|
|
def greet(self, character=None):
|
|
|
|
|
delay(2, self.do_cmd, "emote waves.")
|
|
|
|
|
|
|
|
|
|
def goodbye(self, character=None):
|
|
|
|
|
delay(2, self.do_cmd, "emote waves good-bye.")
|
|
|
|
|
|
|
|
|
|
def change_direction(self):
|
|
|
|
|
"""
|
|
|
|
|
Hard coded directional change, east <-> west
|
|
|
|
|
Note: Change with the command:
|
|
|
|
|
|
|
|
|
|
@set npc/traveling_direction = "come"
|
|
|
|
|
"""
|
|
|
|
|
logger.info(f"The {self} needs to override change_direction")
|
|
|
|
|
|
|
|
|
|
def come(self, direction="come"):
|
|
|
|
|
"""
|
|
|
|
|
Set traveling to a particular given direction.
|
|
|
|
|
"""
|
|
|
|
|
self.db.traveling_direction == direction
|
|
|
|
|
|
|
|
|
|
def leave(self):
|
|
|
|
|
"""
|
|
|
|
|
Set traveling to a new direction.
|
|
|
|
|
Same as changing direction.
|
|
|
|
|
"""
|
|
|
|
|
self.change_direction()
|
|
|
|
|
|
|
|
|
|
def next_place(self):
|
|
|
|
|
direction_label = self.db.traveling_direction
|
|
|
|
|
location_details = self.traveling_path.get(self.location.key)
|
|
|
|
|
if location_details:
|
|
|
|
|
logger.info(f"TravelingNPC: {direction_label} :: {location_details}")
|
|
|
|
|
room_name = location_details.get(direction_label)
|
|
|
|
|
if room_name:
|
|
|
|
|
logger.info(f"TravelingNPC: to -> {room_name}")
|
|
|
|
|
new_room = self.search(room_name, global_search=True)
|
|
|
|
|
if new_room:
|
|
|
|
|
logger.info(f"TravelingNPC: to -> {new_room}")
|
|
|
|
|
# Say See ya if it had engaged...
|
|
|
|
|
self.goodbye(new_room)
|
|
|
|
|
delay(5, self.move_to, new_room, move_type="teleport")
|
|
|
|
|
# This process will reset the timer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Dragon(Traveler):
|
|
|
|
|
"""
|
|
|
|
|
Travels east-to-west along the path, and has a drink at the
|
|
|
|
|
Wyldwood Tavern.
|
|
|
|
|
"""
|
|
|
|
|
# self.db.direction = "east" # or west or whatever
|
|
|
|
|
|
|
|
|
|
traveling_path = {
|
|
|
|
|
"the Deep Forest": {
|
|
|
|
|
"east": "Grotto",
|
|
|
|
|
"come": "Grotto"
|
|
|
|
|
},
|
|
|
|
|
"Grotto": {
|
|
|
|
|
"east": "Grove of the Matriarchs",
|
|
|
|
|
"west": "the Deep Forest",
|
|
|
|
|
"come": "door"
|
|
|
|
|
},
|
|
|
|
|
"Grove of the Matriarchs": {
|
|
|
|
|
"east": "Frog Meadow",
|
|
|
|
|
"west": "Grotto",
|
|
|
|
|
"come": "Grotto"
|
|
|
|
|
},
|
|
|
|
|
"Frog Meadow": {
|
|
|
|
|
"east": "Glittering Glade",
|
|
|
|
|
"west": "Grove of the Matriarchs",
|
|
|
|
|
"come": "Grove of the Matriarchs"
|
|
|
|
|
},
|
|
|
|
|
"Glittering Glade": {
|
|
|
|
|
"east": "Wyldwood Bar",
|
|
|
|
|
"west": "Frog Meadow",
|
|
|
|
|
"come": "Frog Meadow"
|
|
|
|
|
},
|
|
|
|
|
"Wyldwood Bar": {
|
|
|
|
|
"west": "Glittering Glade",
|
|
|
|
|
"come": "Glittering Glade"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def change_direction(self):
|
|
|
|
|
"""
|
|
|
|
|
Hard coded directional change, east <-> west
|
|
|
|
|
Note: Change with the command:
|
|
|
|
|
|
|
|
|
|
@set npc/traveling_direction = "come"
|
|
|
|
|
"""
|
|
|
|
|
self.db.traveling_direction = "west" \
|
|
|
|
|
if self.db.traveling_direction == "east" else "east"
|
|
|
|
|
|
|
|
|
|
def at_pre_move(self, destination, move_type="move", **kwargs):
|
|
|
|
|
if self.location.key == "Wyldwood Bar":
|
|
|
|
|
self.location.msg_contents("The little dragon tips his wide-brimmed and says, \"A pleasure, but I must be off.\"")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def at_post_move(self, past_location, move_type="move", **kwargs):
|
|
|
|
|
# super().at_post_move(past_location, move_type)
|
|
|
|
|
if self.location.key == "Wyldwood Bar":
|
|
|
|
|
request = choice([
|
|
|
|
|
"a Moonlit Mirage",
|
|
|
|
|
"Puck's Revenge",
|
|
|
|
|
"a Glimmering Gossamer",
|
|
|
|
|
"a Whimsical Willow",
|
|
|
|
|
"a Charmed Chalice",
|
|
|
|
|
"an Enchanted Elixir",
|
|
|
|
|
"a Sylvan Serenade",
|
|
|
|
|
"a Brambleberry Bliss",
|
|
|
|
|
"a Twilight Tonic",
|
|
|
|
|
])
|
|
|
|
|
self.process_thoughts(f"""The little dragon flutters over to the bar, studying the menu. "What am I in the mood for now?" he muses to himself, twiddling a tendril like a mustache with his little claw.
|
|
|
|
|
|
|
|
|
|
"Elendil, dear," he says, "Would you make me {request}?" The little dragon then waves to the band on their mushroom stage.""")
|
|
|
|
|
bartender = self.search("bartender")
|
|
|
|
|
bartender.other_sayto(self,
|
|
|
|
|
f"\"Sir Roblees, the fairy dragon asks, \"Would you make me {request}?\"")
|
|
|
|
|
# from typeclasses.drinkables import Cocktail
|
|
|
|
|
# Cocktail.make(self, bartender, request)
|
|
|
|
|
|
|
|
|
|
def greet(self, character=None):
|
|
|
|
|
logger.info(f"Dragon: greet {character}")
|
|
|
|
|
if character:
|
|
|
|
|
name = character.get_name()
|
|
|
|
|
cmd = choice([
|
|
|
|
|
f"emote \"Hey, {name},\" /me says.",
|
|
|
|
|
f"emote \"Hey there, {name},\" /me says.",
|
|
|
|
|
f"emote \"Hello, {name},\" /me says. \"How are you?\"",
|
|
|
|
|
f"emote waves to {name}."
|
|
|
|
|
])
|
|
|
|
|
else:
|
|
|
|
|
cmd = choice([
|
|
|
|
|
"say Look at all these luscious peoples.",
|
|
|
|
|
"emote waves to everyone.",
|
|
|
|
|
"emote waves to everybody."
|
|
|
|
|
])
|
|
|
|
|
delay(5, self.do_cmd, cmd)
|
|
|
|
|
|
|
|
|
|
def goodbye(self, new_room=None):
|
|
|
|
|
self.do_cmd("drop drink")
|
|
|
|
|
system_prompt = self.setting_and_backstory()
|
|
|
|
|
messages = [{"role": "user", "content": "Say goodbye."}]
|
|
|
|
|
reply = self._think(system_prompt, messages)
|
|
|
|
|
self.process_thoughts(reply)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TravelingNPC(Script):
|
|
|
|
|
"""
|
|
|
|
|
Script to move NPCs along a set path through "rooms".
|
|
|
|
|
|
|
|
|
|
Start the script by running the following:
|
|
|
|
|
|
|
|
|
|
@script npc = typeclasses.chatbots.TravelingNPC
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def at_script_creation(self):
|
|
|
|
|
self.key = "Traveling"
|
|
|
|
|
self.desc = "NPCs that Move"
|
|
|
|
|
self.interval = self.obj.db.traveling_interval or 120 # seconds
|
|
|
|
|
self.start_delay = False
|
|
|
|
|
self.persistent = True
|
|
|
|
|
self.reload()
|
|
|
|
|
|
|
|
|
|
def reload(self):
|
|
|
|
|
self.obj.db.last_event_time = time()
|
|
|
|
|
|
|
|
|
|
def at_repeat(self, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Do we move or stay for another iteration?
|
|
|
|
|
"""
|
|
|
|
|
# What can keep a traveling NPC from traveling?
|
|
|
|
|
# What if receiving ANY message resets a timer?
|
|
|
|
|
elapsed_time = time() - self.obj.db.last_event_time
|
|
|
|
|
# Time needs to be a little longer than the repeat interval.
|
|
|
|
|
if elapsed_time >= 20 * 60:
|
|
|
|
|
logger.info(f"TravelingNPC: Long: {elapsed_time} > {20 * 60}")
|
|
|
|
|
self.obj.goodbye()
|
|
|
|
|
self.obj.change_direction()
|
|
|
|
|
|
|
|
|
|
elif elapsed_time >= 3 * 60:
|
|
|
|
|
logger.info(f"TravelingNPC: Short: {elapsed_time} > {3 * 60}")
|
|
|
|
|
logger.info(f"TravelingNPC({self.obj}): Short- {elapsed_time} > {3 * 60}")
|
|
|
|
|
self.obj.next_place()
|
|
|
|
|
|