#!/usr/bin/env python3 """Gym battle module for PetBot""" from .base_module import BaseModule class GymBattles(BaseModule): """Handles gym challenges, battles, and badge tracking""" def get_commands(self): return ["gym"] async def handle_command(self, channel, nickname, command, args): if command == "gym": if not args: await self.cmd_gym_list(channel, nickname) elif args[0] == "list": await self.cmd_gym_list_all(channel, nickname) elif args[0] == "challenge": await self.cmd_gym_challenge(channel, nickname, args[1:]) elif args[0] == "info": await self.cmd_gym_info(channel, nickname, args[1:]) elif args[0] == "status": await self.cmd_gym_status(channel, nickname) else: await self.cmd_gym_list(channel, nickname) async def cmd_gym_list(self, channel, nickname): """List gyms in current location""" player = await self.require_player(channel, nickname) if not player: return # Get player's current location location = await self.database.get_player_location(player["id"]) if not location: self.send_message(channel, f"{nickname}: You are not in a valid location!") return # Get gyms in current location gyms = await self.database.get_gyms_in_location(location["id"], player["id"]) if not gyms: self.send_message(channel, f"πŸ›οΈ {nickname}: No gyms found in {location['name']}.") return self.send_message(channel, f"πŸ›οΈ Gyms in {location['name']}:") for gym in gyms: victories = gym.get("victories", 0) if victories == 0: status = "Not challenged" difficulty = "Beginner" else: status = f"{victories} victories" difficulty = f"Level {victories + 1}" badge_icon = gym["badge_icon"] leader = gym["leader_name"] theme = gym["theme"] self.send_message(channel, f" {badge_icon} {gym['name']} - Leader: {leader} ({theme})") self.send_message(channel, f" Status: {status} | Next difficulty: {difficulty}") self.send_message(channel, f"πŸ’‘ Use '!gym challenge \"\"' to battle!") async def cmd_gym_list_all(self, channel, nickname): """List all gyms across all locations""" player = await self.require_player(channel, nickname) if not player: return # Get all locations and their gyms all_locations = await self.database.get_all_locations() self.send_message(channel, f"πŸ—ΊοΈ {nickname}: All Gym Locations:") total_badges = 0 for location in all_locations: gyms = await self.database.get_gyms_in_location(location["id"], player["id"]) if gyms: for gym in gyms: victories = gym.get("victories", 0) status_icon = "βœ…" if victories > 0 else "❌" if victories > 0: total_badges += 1 self.send_message(channel, f" {status_icon} {location['name']}: {gym['name']} ({gym['theme']}) - {victories} victories") self.send_message(channel, f"πŸ† Total badges earned: {total_badges}") async def cmd_gym_challenge(self, channel, nickname, args): """Challenge a gym""" if not args: self.send_message(channel, f"{nickname}: Specify a gym to challenge! Example: !gym challenge \"Forest Guardian\"") return player = await self.require_player(channel, nickname) if not player: return # Get player's current location first location = await self.database.get_player_location(player["id"]) if not location: self.send_message(channel, f"{nickname}: You are not in a valid location! Use !travel to go somewhere first.") return gym_name = " ".join(args).strip('"') # Look for gym in player's current location (case-insensitive) gym = await self.database.get_gym_by_name_in_location(gym_name, location["id"]) if not gym: # List available gyms in current location for helpful error message available_gyms = await self.database.get_gyms_in_location(location["id"]) if available_gyms: gym_list = ", ".join([f'"{g["name"]}"' for g in available_gyms]) self.send_message(channel, f"{nickname}: No gym named '{gym_name}' found in {location['name']}! Available gyms: {gym_list}") else: self.send_message(channel, f"{nickname}: No gyms found in {location['name']}! Try traveling to a different location.") return # Check if player has active pets active_pets = await self.database.get_active_pets(player["id"]) if not active_pets: self.send_message(channel, f"{nickname}: You need at least one active pet to challenge a gym! Use !activate first.") return # Get player's gym progress progress = await self.database.get_player_gym_progress(player["id"], gym["id"]) difficulty_level = (progress["victories"] if progress else 0) + 1 difficulty_multiplier = 1.0 + (difficulty_level - 1) * 0.2 # 20% increase per victory # Start gym battle await self.start_gym_battle(channel, nickname, player, gym, difficulty_level, difficulty_multiplier) async def start_gym_battle(self, channel, nickname, player, gym, difficulty_level, difficulty_multiplier): """Start a gym battle""" # Get gym team with scaling gym_team = await self.database.get_gym_team(gym["id"], difficulty_multiplier) if not gym_team: self.send_message(channel, f"{nickname}: {gym['name']} gym has no team configured!") return # Display battle start badge_icon = gym["badge_icon"] leader = gym["leader_name"] difficulty_name = f"Level {difficulty_level}" if difficulty_level > 1 else "Beginner" self.send_message(channel, f"πŸ›οΈ {nickname} challenges the {gym['name']} gym!") self.send_message(channel, f"{badge_icon} Leader {leader}: \"Welcome to my {gym['theme']}-type gym! Let's see what you've got!\"") self.send_message(channel, f"βš”οΈ Difficulty: {difficulty_name} ({len(gym_team)} pets)") # For now, simulate battle result (we'll implement actual battle mechanics later) import random # Simple win/loss calculation based on player's active pets active_pets = await self.database.get_active_pets(player["id"]) player_strength = sum(pet["level"] * (pet["attack"] + pet["defense"]) for pet in active_pets) gym_strength = sum(pet["level"] * (pet["attack"] + pet["defense"]) for pet in gym_team) # Add some randomness but favor player slightly for now win_chance = min(0.85, max(0.15, player_strength / (gym_strength * 0.8))) if random.random() < win_chance: await self.handle_gym_victory(channel, nickname, player, gym, difficulty_level) else: await self.handle_gym_defeat(channel, nickname, gym, difficulty_level) async def handle_gym_victory(self, channel, nickname, player, gym, difficulty_level): """Handle gym battle victory""" # Record victory in database result = await self.database.record_gym_victory(player["id"], gym["id"]) badge_icon = gym["badge_icon"] leader = gym["leader_name"] self.send_message(channel, f"πŸŽ‰ {nickname} defeats the {gym['name']} gym!") if result["is_first_victory"]: # First time victory - award badge self.send_message(channel, f"{badge_icon} Leader {leader}: \"Impressive! You've earned the {gym['badge_name']}!\"") self.send_message(channel, f"πŸ† {nickname} earned the {gym['badge_name']} {badge_icon}!") # Award bonus rewards for first victory money_reward = 500 + (difficulty_level * 100) exp_reward = 200 + (difficulty_level * 50) else: # Repeat victory self.send_message(channel, f"{badge_icon} Leader {leader}: \"Well fought! Your skills keep improving!\"") money_reward = 200 + (difficulty_level * 50) exp_reward = 100 + (difficulty_level * 25) # Award rewards (we'll implement this when we have currency/exp systems) victories = result["victories"] next_difficulty = result["next_difficulty"] self.send_message(channel, f"πŸ’° Rewards: ${money_reward} | 🌟 {exp_reward} EXP") self.send_message(channel, f"πŸ“Š {gym['name']} record: {victories} victories | Next challenge: Level {next_difficulty}") async def handle_gym_defeat(self, channel, nickname, gym, difficulty_level): """Handle gym battle defeat""" badge_icon = gym["badge_icon"] leader = gym["leader_name"] self.send_message(channel, f"πŸ’₯ {nickname} was defeated by the {gym['name']} gym!") self.send_message(channel, f"{badge_icon} Leader {leader}: \"Good battle! Train more and come back stronger!\"") self.send_message(channel, f"πŸ’‘ Tip: Level up your pets, get better items, or try a different strategy!") async def cmd_gym_info(self, channel, nickname, args): """Get detailed information about a gym""" if not args: self.send_message(channel, f"{nickname}: Specify a gym name! Example: !gym info \"Forest Guardian\"") return player = await self.require_player(channel, nickname) if not player: return gym_name = " ".join(args).strip('"') # First try to find gym in player's current location location = await self.database.get_player_location(player["id"]) gym = None if location: gym = await self.database.get_gym_by_name_in_location(gym_name, location["id"]) # If not found in current location, search globally if not gym: gym = await self.database.get_gym_by_name(gym_name) if not gym: self.send_message(channel, f"{nickname}: Gym '{gym_name}' not found!") return # Get gym team info gym_team = await self.database.get_gym_team(gym["id"]) badge_icon = gym["badge_icon"] self.send_message(channel, f"πŸ›οΈ {gym['name']} Gym Information:") self.send_message(channel, f"πŸ“ Location: {gym['location_name']}") self.send_message(channel, f"πŸ‘€ Leader: {gym['leader_name']}") self.send_message(channel, f"🎯 Theme: {gym['theme']}-type") self.send_message(channel, f"πŸ“ {gym['description']}") self.send_message(channel, f"πŸ† Badge: {gym['badge_name']} {badge_icon}") if gym_team: self.send_message(channel, f"βš”οΈ Team ({len(gym_team)} pets):") for pet in gym_team: type_str = pet["type1"] if pet["type2"]: type_str += f"/{pet['type2']}" self.send_message(channel, f" β€’ Level {pet['level']} {pet['species_name']} ({type_str})") async def cmd_gym_status(self, channel, nickname): """Show player's overall gym progress""" player = await self.require_player(channel, nickname) if not player: return # This will show a summary - for detailed view they can use !gym list self.send_message(channel, f"πŸ† {nickname}: Use !gym list to see all gym progress, or check your profile at: http://petz.rdx4.com/player/{nickname}")