sparkytron3000/cogs/pokemon.py

268 lines
11 KiB
Python
Raw Permalink Normal View History

import random
import logging
import os
import json
import math
import time
import aiohttp
from discord.ext import commands
import discord
class PokemonGame(commands.Cog):
2024-01-20 17:39:19 -08:00
def __init__(self, bot):
self.bot = bot
self.working_dir = "tmp/pokemon/"
self.data_dir = "data/pokemon/"
self.folder_setup()
self.http_session = self.create_aiohttp_session()
self.logger = logging.getLogger("bot")
def create_aiohttp_session(self):
return aiohttp.ClientSession()
async def get_json(self, url):
async with self.http_session.get(url) as resp:
json_data = await resp.json()
return json_data
def folder_setup(self):
try:
if not os.path.exists(self.working_dir):
os.mkdir(self.working_dir)
if not os.path.exists(self.data_dir):
os.mkdir(self.data_dir)
except:
self.logger.exception("PokemonGame failed to make directories")
async def starter_picker(self, id): #id = pokedex number
url = "https://pokeapi.co/api/v2/pokemon-species/" + str(id)
2024-02-04 00:23:06 -08:00
json_data = await self.get_json(url)
if (json_data["evolves_from_species"] == None) and (not json_data['is_mythical']) and (not json_data['is_legendary']):
return True
else:
return False
async def shiny_roll(self):
roll = random.randint(0,2047)
return not roll
async def save_pokemon(self, discord_id, pokemon_dict):
path = self.data_dir+str(discord_id)+".json"
pokemon_dict = json.dumps(pokemon_dict)
with open(path, 'w') as f:
f.writelines(pokemon_dict)
return True
async def load_pokemon(self, discord_id):
if os.path.isfile(self.data_dir+str(discord_id)+".json"):
with open(self.data_dir+str(discord_id)+".json", 'r') as f:
json_data = json.loads(f.readline())
return json_data
else:
return False
async def generate_starter(self, discord_id):
random.seed(discord_id)
json_data = await self.get_json('https://pokeapi.co/api/v2/pokemon-species/')
pokemon_count = json_data['count']
base_pokemon = False
while not base_pokemon:
starter_id = random.randint(1,pokemon_count)
base_pokemon = await self.starter_picker(starter_id)
random.seed()
return starter_id
async def get_pkmn_from_id(self, id):
url = 'https://pokeapi.co/api/v2/pokemon/' + str(id)
json_data = await self.get_json(url)
return json_data
async def give_buddy_food(self, pkmn_data):
try:
last_food = pkmn_data['last_food']
except:
last_food = 0
this_food = time.time()
if (this_food - last_food) >= 1800:
pkmn_data['last_food'] = this_food
level = await self.calc_pkmn_buddy_level(pkmn_data)
pkmn_data['buddy_xp'] += (4*level)
return pkmn_data, True
else:
return pkmn_data, False
async def give_buddy_affection(self, pkmn_data):
try:
last_hug = pkmn_data['last_hug']
except:
last_hug = 0
this_hug = time.time()
if (this_hug - last_hug) >= 600:
pkmn_data['last_hug'] = this_hug
level = await self.calc_pkmn_buddy_level(pkmn_data)
pkmn_data['buddy_xp'] += (3*level)
return pkmn_data, True
else:
return pkmn_data, False
async def calc_pkmn_buddy_level(self, pkmn_json): #this uses the 'fast' xp rate
buddy_xp = pkmn_json['buddy_xp']
return min(math.floor(((5*buddy_xp)/4)**(1/3)),100)
async def make_pmkn_embed(self, pkmn_dict):
if pkmn_dict['nickname']:
title = pkmn_dict['nickname'] + ' (' + pkmn_dict['name'].capitalize() + ')'
else:
title = pkmn_dict['name'].capitalize()
embed=discord.Embed(title=title)
if pkmn_dict['shiny']:
embed.set_image(url=pkmn_dict['sprites']['front_shiny'])
else:
embed.set_image(url=pkmn_dict['sprites']['front_default'])
nature = pkmn_dict['nature']
buddy_level = await self.calc_pkmn_buddy_level(pkmn_dict)
buddy_xp = pkmn_dict['buddy_xp']
types = []
for key in pkmn_dict['types']:
types.append(key['type']['name'].capitalize())
type_str = ', '.join(types)
embed.add_field(name="Nature", value=nature.capitalize(), inline=False)
embed.add_field(name="Buddy Level", value=buddy_level , inline=True)
embed.add_field(name="Buddy XP", value=buddy_xp, inline=True)
embed.add_field(name="Types", value=type_str, inline=False)
return embed
async def get_pokemon_evolve_data(self, pkmn_data):
pkmn_id = pkmn_data['id']
url = f"https://pokeapi.co/api/v2/pokemon-species/{pkmn_id}/"
json_data = await self.get_json(url)
evolution_url = json_data['evolution_chain']['url']
evolution_data = await self.get_json(evolution_url)
evolution_level = evolution_data['chain']['evolves_to'][0]['evolution_details'][0]['min_level']
evolution_type = evolution_data['chain']['evolves_to'][0]['evolution_details'][0]['trigger']['name']
new_pokemon_url = evolution_data['chain']['evolves_to'][0]['species']['url']
new_pokemon_url = new_pokemon_url.replace("pokemon-species/","pokemon/")
return evolution_level, evolution_type, new_pokemon_url
# Some bug in this that doesn't allow middle evolution to evolve
'''@commands.command()
async def pkmn_evolve(self, ctx):
if os.path.isfile(self.data_dir+str(ctx.author.id)+'.json'):
pkmn_data = await self.load_pokemon(ctx.author.id)
evolution_level, evolution_type, new_pokemon_url = await self.get_pokemon_evolve_data(pkmn_data)
buddy_level = await self.calc_pkmn_buddy_level(pkmn_data)
if buddy_level > evolution_level and evolution_type == 'level-up':
new_pokemon_json = await self.get_json(new_pokemon_url)
new_pokemon_json['shiny'] = pkmn_data['shiny']
new_pokemon_json['nickname'] = pkmn_data['nickname']
new_pokemon_json['unique_id'] = pkmn_data['unique_id']
new_pokemon_json['nature'] = pkmn_data['nature']
new_pokemon_json['buddy_level'] = pkmn_data['buddy_level']
new_pokemon_json['buddy_xp'] = pkmn_data['buddy_xp']
new_pokemon_json['last_food'] = pkmn_data['last_food']
new_pokemon_json['last_hug'] = pkmn_data['last_hug']
await self.save_pokemon(ctx.author.id, new_pokemon_json)
embed = await self.make_pmkn_embed(new_pokemon_json)
await ctx.send(embed=embed)
else:
await ctx.send("You don't have enough buddy xp to evolve this pokemon.")'''
@commands.command()
async def pkmn_start(self, ctx):
if not os.path.isfile(self.data_dir+str(ctx.author.id)+'.json'):
uniq_id = time.time()
starter_id = await self.generate_starter(ctx.author.id)
json_data = await self.get_pkmn_from_id(starter_id)
is_shiny = await self.shiny_roll()
nature = random.randint(0,19)
nature_data = await self.get_json('https://pokeapi.co/api/v2/nature/')
nature = nature_data['results'][nature]['name']
json_data['shiny'] = is_shiny
json_data['nickname'] = None
json_data['unique_id'] = uniq_id
json_data['nature'] = nature
json_data['buddy_level'] = 1
json_data['buddy_xp'] = 0
json_data['last_food'] = 0
json_data['last_hug'] = 0
await self.save_pokemon(ctx.author.id, json_data)
embed = await self.make_pmkn_embed(json_data)
await ctx.channel.send(embed=embed)
return
else:
await ctx.channel.send("You already have a pokemon!")
return
@commands.command()
async def pkmn_nick(self, ctx, nickname):
json_data = await self.load_pokemon(ctx.author.id)
json_data['nickname'] = nickname
await self.save_pokemon(ctx.author.id, json_data)
message = "You gave " + nickname + " a new name!"
await ctx.channel.send(message)
@commands.command()
@commands.cooldown(1, 3600, commands.BucketType.user)
async def pkmn_feed(self, ctx):
discord_id = ctx.author.id
json_data = await self.load_pokemon(discord_id)
json_data, fed = await self.give_buddy_food(json_data)
if fed:
await self.save_pokemon(ctx.author.id, json_data)
if json_data['nickname']:
message = "You Feed " + json_data['nickname']
else:
message = "You Feed " + json_data['name']
await ctx.channel.send(message)
return
@commands.command()
@commands.cooldown(1, 1800, commands.BucketType.user)
async def pkmn_hug(self, ctx):
discord_id = ctx.author.id
json_data = await self.load_pokemon(discord_id)
json_data, hugged = await self.give_buddy_affection(json_data)
if hugged:
await self.save_pokemon(discord_id, json_data)
if json_data['nickname']:
message = "You " + "hugged" + ' ' + json_data['nickname']
2024-01-20 17:39:19 -08:00
else:
message = "You " + "hugged" + ' ' + json_data['name']
await ctx.channel.send(message)
@commands.command()
async def pokemon(self, ctx):
discord_id = ctx.author.id
buddy_json = await self.load_pokemon(discord_id)
if not buddy_json:
await ctx.channel.send("You don't have a buddy yet. Type ```!pokemon start``` to start your Pokemon journey!")
else:
embed = await self.make_pmkn_embed(buddy_json)
message = await ctx.channel.send(embed=embed)
return
async def pkmn_msg(self, discord_id):
2024-01-21 14:12:56 -08:00
path = self.data_dir+str(discord_id)+'.json'
if os.path.isfile(path):
with open(path, 'r') as f:
json_data = json.loads(f.readline())
json_data['buddy_xp'] += random.randint(1,5)
json_data = json.dumps(json_data)
with open(path, 'w') as f:
f.writelines(json_data)
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
await self.pkmn_msg(message.author.id)
async def setup(bot):
await bot.add_cog(PokemonGame(bot))