Add comprehensive web interface enhancements and encounter tracking

Major Features Added:
- Complete petdex page showing all available pets with stats, types, evolution info
- Encounter tracking system recording pet discoveries and catch statistics
- Gym badges display on player profiles with victory counts and dates
- Enhanced player profiles with discovery progress and completion percentages

Technical Implementation:
- New /petdex route with rarity-organized pet encyclopedia
- Database encounter tracking with automatic integration into exploration/catch
- Updated webserver.py with encounter data fetching and display
- Fixed battle_system.py syntax error in gym battle completion logic
- Organized project by moving unused bot files to backup_bots/ folder

Database Changes:
- Added player_encounters table for tracking discoveries
- Added methods: record_encounter, get_player_encounters, get_encounter_stats
- Enhanced player profile queries to include gym badges and encounters

Web Interface Updates:
- Petdex page with search stats, rarity grouping, and spawn location info
- Player profiles now show species seen, completion %, gym badges earned
- Encounter section displaying discovered pets with catch statistics
- Updated navigation to include petdex link on main game hub

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
megaproxy 2025-07-14 16:32:25 +01:00
parent bd455f1be5
commit 1ce7158200
7 changed files with 684 additions and 63 deletions

View file

@ -271,6 +271,21 @@ class Database:
)
""")
await db.execute("""
CREATE TABLE IF NOT EXISTS player_encounters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
player_id INTEGER NOT NULL,
species_id INTEGER NOT NULL,
first_encounter_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total_encounters INTEGER DEFAULT 1,
last_encounter_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
caught_count INTEGER DEFAULT 0,
FOREIGN KEY (player_id) REFERENCES players (id),
FOREIGN KEY (species_id) REFERENCES pet_species (id),
UNIQUE(player_id, species_id)
)
""")
await db.commit()
async def get_player(self, nickname: str) -> Optional[Dict]:
@ -1209,4 +1224,96 @@ class Database:
await self.record_gym_victory(player_id, battle_dict["gym_id"])
await db.commit()
return result
return result
async def record_encounter(self, player_id: int, species_name: str, was_caught: bool = False) -> bool:
"""Record a player encountering a pet species"""
try:
async with aiosqlite.connect(self.db_path) as db:
# Get species ID
cursor = await db.execute(
"SELECT id FROM pet_species WHERE name = ?", (species_name,)
)
species_row = await cursor.fetchone()
if not species_row:
return False
species_id = species_row[0]
# Check if encounter already exists
cursor = await db.execute("""
SELECT total_encounters, caught_count FROM player_encounters
WHERE player_id = ? AND species_id = ?
""", (player_id, species_id))
existing = await cursor.fetchone()
if existing:
# Update existing encounter
new_total = existing[0] + 1
new_caught = existing[1] + (1 if was_caught else 0)
await db.execute("""
UPDATE player_encounters
SET total_encounters = ?, last_encounter_date = CURRENT_TIMESTAMP, caught_count = ?
WHERE player_id = ? AND species_id = ?
""", (new_total, new_caught, player_id, species_id))
else:
# Create new encounter record
caught_count = 1 if was_caught else 0
await db.execute("""
INSERT INTO player_encounters (player_id, species_id, caught_count)
VALUES (?, ?, ?)
""", (player_id, species_id, caught_count))
await db.commit()
return True
except Exception as e:
print(f"Error recording encounter: {e}")
return False
async def get_player_encounters(self, player_id: int) -> List[Dict]:
"""Get all encounters for a player"""
async with aiosqlite.connect(self.db_path) as db:
db.row_factory = aiosqlite.Row
cursor = await db.execute("""
SELECT pe.*, ps.name as species_name, ps.type1, ps.type2, ps.rarity
FROM player_encounters pe
JOIN pet_species ps ON pe.species_id = ps.id
WHERE pe.player_id = ?
ORDER BY pe.first_encounter_date ASC
""", (player_id,))
rows = await cursor.fetchall()
return [dict(row) for row in rows]
async def get_encounter_stats(self, player_id: int) -> Dict:
"""Get encounter statistics for a player"""
async with aiosqlite.connect(self.db_path) as db:
# Total species encountered
cursor = await db.execute("""
SELECT COUNT(*) FROM player_encounters WHERE player_id = ?
""", (player_id,))
species_encountered = (await cursor.fetchone())[0]
# Total encounters
cursor = await db.execute("""
SELECT SUM(total_encounters) FROM player_encounters WHERE player_id = ?
""", (player_id,))
total_encounters_result = await cursor.fetchone()
total_encounters = total_encounters_result[0] if total_encounters_result[0] else 0
# Total species available
cursor = await db.execute("""
SELECT COUNT(*) FROM pet_species
""")
total_species = (await cursor.fetchone())[0]
# Calculate completion percentage
completion_percentage = (species_encountered / total_species * 100) if total_species > 0 else 0
return {
"species_encountered": species_encountered,
"total_encounters": total_encounters,
"total_species": total_species,
"completion_percentage": round(completion_percentage, 1)
}