""" Timmy Academy - Custom Commands Includes: - CmdExamine: Examine objects/rooms in detail - CmdRooms: List available rooms - CmdStatus: Show current agent status - CmdMap: Show ASCII map of current wing - CmdAcademy: Show overview of all 4 wings - CmdSmell: Use atmosphere data for scents - CmdListen: Use atmosphere data for sounds """ from evennia.commands.command import Command as BaseCommand from evennia import default_cmds class Command(BaseCommand): """Base command class for Timmy Academy.""" pass # ============================================================ # Original commands (from first pass) # ============================================================ class CmdExamine(BaseCommand): """ Examine an object, character, or detail in the room. Usage: examine [] ex [] If no object is given, examines the current room in detail. """ key = "examine" aliases = ["ex", "exam"] locks = "cmd:all()" help_category = "General" def func(self): if not self.args: loc = self.caller.location self.caller.msg(f"|c{loc.key}|n") self.caller.msg(f"{loc.db.desc}") # Show atmosphere if available atmo = loc.db.atmosphere if atmo: self.caller.msg("\n|wAtmosphere:|n") for key, val in atmo.items(): self.caller.msg(f" |w{key.capitalize()}:|n {val}") # Show notable objects objs = loc.db.objects if objs: self.caller.msg("\n|wNotable features:|n") for obj in objs: self.caller.msg(f" - {obj}") # Show contents contents = [obj.key for obj in loc.contents if obj != self.caller] if contents: self.caller.msg(f"\n|wPresent:|n {', '.join(contents)}") return target = self.caller.search(self.args.strip()) if not target: return self.caller.msg(f"|c{target.key}|n") if hasattr(target, 'db') and target.db.desc: self.caller.msg(f"{target.db.desc}") else: self.caller.msg("You see nothing special.") class CmdRooms(BaseCommand): """ List available rooms in the game. Usage: rooms """ key = "rooms" locks = "cmd:all()" help_category = "General" def func(self): from evennia.objects.models import ObjectDB rooms = ObjectDB.objects.filter( db_typeclass_path__icontains='room' ).order_by('id') self.caller.msg("|c=== Timmy Academy Rooms ===|n") for room in rooms: wing = room.attributes.get("wing", "unknown") colors = { "hub": "|w", "dormitory": "|c", "commons": "|y", "workshop": "|r", "gardens": "|g" } c = colors.get(wing, "|n") marker = "*" if self.caller.location == room else " " self.caller.msg(f" {marker} {c}{room.db_key}|n [{wing}]") # ============================================================ # New commands (second pass) # ============================================================ class CmdStatus(BaseCommand): """ Show your current status: location, wing, who's online, uptime. Usage: @status """ key = "@status" aliases = ["status"] locks = "cmd:all()" help_category = "Academy" def func(self): caller = self.caller loc = caller.location wing = loc.db.wing if loc else "unknown" mood = "" if loc and loc.db.atmosphere: mood = loc.db.atmosphere.get("mood", "") # Who is online from evennia.accounts.models import AccountDB online = AccountDB.objects.filter(db_is_connected=True) online_names = [a.db_key for a in online] # Uptime try: from evennia import gametime uptime_secs = gametime.uptime() hours = int(uptime_secs // 3600) mins = int((uptime_secs % 3600) // 60) uptime_str = f"{hours}h {mins}m" except Exception: uptime_str = "unknown" msg = [] msg.append("|c============= Agent Status =============|n") msg.append(f" |wAgent:|n {caller.key}") msg.append(f" |wLocation:|n {loc.key if loc else 'Void'}") msg.append(f" |wWing:|n {wing}") if mood: msg.append(f" |wMood:|n {mood}") msg.append(f" |wOnline:|n {', '.join(online_names) if online_names else 'nobody'} ({len(online_names)})") msg.append(f" |wUptime:|n {uptime_str}") msg.append("|c=========================================|n") self.caller.msg("\n".join(msg)) class CmdMap(BaseCommand): """ Show an ASCII map of the current wing or the academy hub. Usage: @map """ key = "@map" aliases = ["map"] locks = "cmd:all()" help_category = "Academy" WING_MAPS = { "hub": ( "\n|c============= Academy Central Hub =============|n\n" "\n" " |c[Dormitory Wing]|n\n" " |\n" " north\n" " |\n" " |g[Gardens Wing]|n --west-- |w[ LIMBO ]|n --east-- |y[Commons Wing]|n\n" " |\n" " south\n" " |\n" " |r[Workshop Wing]|n\n" "\n|c=================================================|n" ), "dormitory": ( "\n|c============= Dormitory Wing =============|n\n" "\n" " |c[Master Suites]|n --w-- |c[Corridor]|n --e-- |c[Novice Hall]|n\n" " |\n" " south\n" " |\n" " |c[Res. Services]|n --n-- |c[Dorm Entrance]|n\n" " |\n" " south\n" " |\n" " |w[LIMBO/Hub]|n\n" "\n|c=============================================|n" ), "commons": ( "\n|y============= Commons Wing =============|n\n" "\n" " |y[Upper Balcony]|n\n" " |\n" " up\n" " |\n" " |y[Scholar's]|n --e-- |y[Grand Commons]|n --s-- |y[Entertainment]|n\n" " |\n" " north\n" " |\n" " |y[Hearthside]|n\n" " |\n" " |w[LIMBO/Hub]|n\n" "\n|y=============================================|n" ), "workshop": ( "\n|r============= Workshop Wing =============|n\n" "\n" " |r[Woodworking]|n --e-- |r[Alchemy Labs]|n\n" " |\n" " north\n" " |\n" " |r[Great Smithy]|n --e-- |r[Workshop Entrance]|n\n" " |\n" " down | north\n" " |\n" " |r[Artificing]|n |w[LIMBO/Hub]|n\n" "\n|r=============================================|n" ), "gardens": ( "\n|g============= Gardens Wing =============|n\n" "\n" " |g[Sacred Grove]|n\n" " |\n" " up\n" " |\n" " |g[Greenhouse]|n --n-- |g[Enchanted Grove]|n\n" " |\n" " west\n" " |\n" " |g[Herb Gardens]|n --s-- |g[Gardens Entrance]|n\n" " |\n" " |w[LIMBO/Hub]|n\n" "\n|g=============================================|n" ), } def func(self): loc = self.caller.location wing = loc.db.wing if loc else "hub" if not wing or wing not in self.WING_MAPS: wing = "hub" self.caller.msg(self.WING_MAPS[wing]) self.caller.msg(f" |wYou are in:|n {loc.key}") class CmdAcademy(BaseCommand): """ Show an overview of all academy wings and room counts. Usage: @academy """ key = "@academy" aliases = ["academy"] locks = "cmd:all()" help_category = "Academy" def func(self): from evennia.objects.models import ObjectDB msg = [] msg.append("|c" + "=" * 52 + "|n") msg.append("|c TIMMY ACADEMY - Agent Training Grounds|n") msg.append("|c" + "=" * 52 + "|n") msg.append("") msg.append(' |x"Together we learn, together we grow."|n') msg.append("") wing_config = { "hub": {"name": "Central Hub", "color": "|w", "ids": [2]}, "dormitory": {"name": "Dormitory Wing", "color": "|c", "ids": [3,4,5,6,7]}, "commons": {"name": "Commons Wing", "color": "|y", "ids": [8,9,10,11,12]}, "workshop": {"name": "Workshop Wing", "color": "|r", "ids": [13,14,15,16,17]}, "gardens": {"name": "Gardens Wing", "color": "|g", "ids": [18,19,20,21,22]}, } total_rooms = 0 for key, info in wing_config.items(): rooms = ObjectDB.objects.filter(id__in=info["ids"]) count = rooms.count() total_rooms += count c = info["color"] msg.append(f" {c}{info['name']:20s}|n {count} rooms") for room in rooms.order_by('id'): marker = "*" if self.caller.location == room else " " msg.append(f" {marker} {c}{room.db_key}|n") exits = ObjectDB.objects.filter(db_typeclass_path__icontains="exit") chars = ObjectDB.objects.filter(db_typeclass_path__icontains="character") msg.append("") msg.append(f" |wTotal:|n {total_rooms} rooms, {exits.count()} exits, {chars.count()} characters") msg.append("") msg.append(" |wConnect:|n telnet 167.99.126.228 4000") msg.append(" |wWeb:|n http://167.99.126.228:4001") msg.append("|c" + "=" * 52 + "|n") self.caller.msg("\n".join(msg)) class CmdSmell(BaseCommand): """ Use your sense of smell to perceive the room. Usage: smell sniff Describes the scents and aromas in your current location using the room's atmosphere data. """ key = "smell" aliases = ["sniff"] locks = "cmd:all()" help_category = "Academy" def func(self): loc = self.caller.location if not loc: self.caller.msg("You smell... nothing. The void has no scent.") return atmo = loc.db.atmosphere if atmo and "smells" in atmo: self.caller.msg(f"|wYou breathe deeply in {loc.key}...|n") self.caller.msg(f"\n {atmo['smells']}") if "temperature" in atmo: self.caller.msg(f"\n The air feels: {atmo['temperature']}") else: self.caller.msg("You sniff the air but detect nothing noteworthy.") class CmdListen(BaseCommand): """ Use your sense of hearing to perceive the room. Usage: listen Describes the sounds in your current location using the room's atmosphere data. """ key = "listen" aliases = ["hear"] locks = "cmd:all()" help_category = "Academy" def func(self): loc = self.caller.location if not loc: self.caller.msg("You listen... but silence stretches forever in the void.") return atmo = loc.db.atmosphere if atmo and "sounds" in atmo: self.caller.msg(f"|wYou pause and listen in {loc.key}...|n") self.caller.msg(f"\n {atmo['sounds']}") if "mood" in atmo: self.caller.msg(f"\n The mood here is: {atmo['mood']}") else: self.caller.msg("You listen carefully but hear nothing unusual.")