🎮 Features implemented: - Pokemon-style pet collection and battles - Multi-location exploration system - Dynamic weather with background updates - Achievement system with location unlocks - Web dashboard for player stats - Modular command system - Async database with SQLite - PM flood prevention - Persistent player data 🌤️ Weather System: - 6 weather types with spawn modifiers - 30min-3hour dynamic durations - Background task for automatic updates - Location-specific weather patterns 🐛 Recent Bug Fixes: - Database persistence on restart - Player page SQLite row conversion - Achievement count calculations - Travel requirement messages - Battle move color coding - Locations page display 🔧 Generated with Claude Code 🤖 Co-Authored-By: Claude <noreply@anthropic.com>
149 lines
No EOL
6.3 KiB
Python
149 lines
No EOL
6.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Pet management commands module for PetBot"""
|
|
|
|
from .base_module import BaseModule
|
|
|
|
class PetManagement(BaseModule):
|
|
"""Handles team, pets, and future pet management commands"""
|
|
|
|
def get_commands(self):
|
|
return ["team", "pets", "activate", "deactivate", "swap"]
|
|
|
|
async def handle_command(self, channel, nickname, command, args):
|
|
if command == "team":
|
|
await self.cmd_team(channel, nickname)
|
|
elif command == "pets":
|
|
await self.cmd_pets(channel, nickname)
|
|
elif command == "activate":
|
|
await self.cmd_activate(channel, nickname, args)
|
|
elif command == "deactivate":
|
|
await self.cmd_deactivate(channel, nickname, args)
|
|
elif command == "swap":
|
|
await self.cmd_swap(channel, nickname, args)
|
|
|
|
async def cmd_team(self, channel, nickname):
|
|
"""Show active pets (channel display)"""
|
|
player = await self.require_player(channel, nickname)
|
|
if not player:
|
|
return
|
|
|
|
pets = await self.database.get_player_pets(player["id"], active_only=False)
|
|
if not pets:
|
|
self.send_message(channel, f"{nickname}: You don't have any pets! Use !catch to find some.")
|
|
return
|
|
|
|
# Show active pets first, then others
|
|
active_pets = [pet for pet in pets if pet.get("is_active")]
|
|
inactive_pets = [pet for pet in pets if not pet.get("is_active")]
|
|
|
|
team_info = []
|
|
|
|
# Active pets with star
|
|
for pet in active_pets:
|
|
name = pet["nickname"] or pet["species_name"]
|
|
team_info.append(f"⭐{name} (Lv.{pet['level']}) - {pet['hp']}/{pet['max_hp']} HP")
|
|
|
|
# Inactive pets
|
|
for pet in inactive_pets[:5]: # Show max 5 inactive
|
|
name = pet["nickname"] or pet["species_name"]
|
|
team_info.append(f"{name} (Lv.{pet['level']}) - {pet['hp']}/{pet['max_hp']} HP")
|
|
|
|
if len(inactive_pets) > 5:
|
|
team_info.append(f"... and {len(inactive_pets) - 5} more in storage")
|
|
|
|
self.send_message(channel, f"🐾 {nickname}'s team: " + " | ".join(team_info))
|
|
|
|
async def cmd_pets(self, channel, nickname):
|
|
"""Show link to pet collection web page"""
|
|
player = await self.require_player(channel, nickname)
|
|
if not player:
|
|
return
|
|
|
|
# Send URL to player's profile page instead of PM spam
|
|
self.send_message(channel, f"{nickname}: View your complete pet collection at: http://localhost:8080/player/{nickname}")
|
|
|
|
async def cmd_activate(self, channel, nickname, args):
|
|
"""Activate a pet for battle (PM only)"""
|
|
# Redirect to PM for privacy
|
|
if not args:
|
|
self.send_pm(nickname, "Usage: !activate <pet_name>")
|
|
self.send_message(channel, f"{nickname}: Pet activation instructions sent via PM!")
|
|
return
|
|
|
|
player = await self.require_player(channel, nickname)
|
|
if not player:
|
|
return
|
|
|
|
pet_name = " ".join(args)
|
|
result = await self.database.activate_pet(player["id"], pet_name)
|
|
|
|
if result["success"]:
|
|
pet = result["pet"]
|
|
display_name = pet["nickname"] or pet["species_name"]
|
|
self.send_pm(nickname, f"✅ {display_name} is now active for battle!")
|
|
self.send_message(channel, f"{nickname}: Pet activated successfully!")
|
|
else:
|
|
self.send_pm(nickname, f"❌ {result['error']}")
|
|
self.send_message(channel, f"{nickname}: Pet activation failed - check PM for details!")
|
|
|
|
async def cmd_deactivate(self, channel, nickname, args):
|
|
"""Deactivate a pet to storage (PM only)"""
|
|
# Redirect to PM for privacy
|
|
if not args:
|
|
self.send_pm(nickname, "Usage: !deactivate <pet_name>")
|
|
self.send_message(channel, f"{nickname}: Pet deactivation instructions sent via PM!")
|
|
return
|
|
|
|
player = await self.require_player(channel, nickname)
|
|
if not player:
|
|
return
|
|
|
|
pet_name = " ".join(args)
|
|
result = await self.database.deactivate_pet(player["id"], pet_name)
|
|
|
|
if result["success"]:
|
|
pet = result["pet"]
|
|
display_name = pet["nickname"] or pet["species_name"]
|
|
self.send_pm(nickname, f"📦 {display_name} moved to storage!")
|
|
self.send_message(channel, f"{nickname}: Pet deactivated successfully!")
|
|
else:
|
|
self.send_pm(nickname, f"❌ {result['error']}")
|
|
self.send_message(channel, f"{nickname}: Pet deactivation failed - check PM for details!")
|
|
|
|
async def cmd_swap(self, channel, nickname, args):
|
|
"""Swap active/storage status of two pets (PM only)"""
|
|
# Redirect to PM for privacy
|
|
if len(args) < 2:
|
|
self.send_pm(nickname, "Usage: !swap <pet1> <pet2>")
|
|
self.send_pm(nickname, "Example: !swap Flamey Aqua")
|
|
self.send_message(channel, f"{nickname}: Pet swap instructions sent via PM!")
|
|
return
|
|
|
|
player = await self.require_player(channel, nickname)
|
|
if not player:
|
|
return
|
|
|
|
# Handle multi-word pet names by splitting on first space vs last space
|
|
if len(args) == 2:
|
|
pet1_name, pet2_name = args
|
|
else:
|
|
# For more complex parsing, assume equal split
|
|
mid_point = len(args) // 2
|
|
pet1_name = " ".join(args[:mid_point])
|
|
pet2_name = " ".join(args[mid_point:])
|
|
|
|
result = await self.database.swap_pets(player["id"], pet1_name, pet2_name)
|
|
|
|
if result["success"]:
|
|
pet1 = result["pet1"]
|
|
pet2 = result["pet2"]
|
|
pet1_display = pet1["nickname"] or pet1["species_name"]
|
|
pet2_display = pet2["nickname"] or pet2["species_name"]
|
|
|
|
self.send_pm(nickname, f"🔄 Swap complete!")
|
|
self.send_pm(nickname, f" • {pet1_display} → {result['pet1_now']}")
|
|
self.send_pm(nickname, f" • {pet2_display} → {result['pet2_now']}")
|
|
self.send_message(channel, f"{nickname}: Pet swap completed!")
|
|
else:
|
|
self.send_pm(nickname, f"❌ {result['error']}")
|
|
self.send_message(channel, f"{nickname}: Pet swap failed - check PM for details!") |