Added normalize_input() function to BaseModule for consistent lowercase conversion of user input. Updated all command modules to use normalization for commands, arguments, pet names, location names, gym names, and item names. Players can now use any capitalization for commands and arguments. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
187 lines
No EOL
8 KiB
Python
187 lines
No EOL
8 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", "nickname"]
|
|
|
|
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)
|
|
elif command == "nickname":
|
|
await self.cmd_nickname(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"]
|
|
|
|
# Calculate EXP progress
|
|
current_exp = pet.get("experience", 0)
|
|
next_level_exp = self.database.calculate_exp_for_level(pet["level"] + 1)
|
|
current_level_exp = self.database.calculate_exp_for_level(pet["level"])
|
|
exp_needed = next_level_exp - current_exp
|
|
|
|
if pet["level"] >= 100:
|
|
exp_display = "MAX"
|
|
else:
|
|
exp_display = f"{exp_needed} to next"
|
|
|
|
team_info.append(f"⭐{name} (Lv.{pet['level']}) - {pet['hp']}/{pet['max_hp']} HP | EXP: {exp_display}")
|
|
|
|
# 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://petz.rdx4.com/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(self.normalize_input(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(self.normalize_input(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!")
|
|
|
|
async def cmd_nickname(self, channel, nickname, args):
|
|
"""Set a nickname for a pet"""
|
|
if len(args) < 2:
|
|
self.send_message(channel, f"{nickname}: Usage: !nickname <pet> <new_nickname>")
|
|
self.send_message(channel, f"Example: !nickname Charmander Flamey")
|
|
return
|
|
|
|
player = await self.require_player(channel, nickname)
|
|
if not player:
|
|
return
|
|
|
|
# Split args into pet identifier and new nickname
|
|
pet_identifier = self.normalize_input(args[0])
|
|
new_nickname = " ".join(args[1:])
|
|
|
|
result = await self.database.set_pet_nickname(player["id"], pet_identifier, new_nickname)
|
|
|
|
if result["success"]:
|
|
old_name = result["old_name"]
|
|
new_name = result["new_nickname"]
|
|
self.send_message(channel, f"✨ {nickname}: {old_name} is now nicknamed '{new_name}'!")
|
|
else:
|
|
self.send_message(channel, f"❌ {nickname}: {result['error']}") |