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:
parent
bd455f1be5
commit
1ce7158200
7 changed files with 684 additions and 63 deletions
109
src/database.py
109
src/database.py
|
|
@ -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)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue