Last active
August 27, 2022 02:10
-
-
Save Kanin/eca27f515a8f4fc41886782e07a14d79 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__author__ = "Kanin (https://github.com/Kanin)" | |
__copyright__ = "Copyright (C) 2022 Kanin" | |
__license__ = "Public Domain" | |
__version__ = "1.0" | |
import os | |
from pathlib import Path | |
import discord | |
from PIL import Image | |
from discord.ext import commands | |
from discord import app_commands | |
from discord.ext.tasks import loop | |
from discord.ui import View, Button | |
from bot import Bot | |
from pyboy import PyBoy, WindowEvent | |
from io import BytesIO | |
rom_folder = os.path.join(Path(__file__).parent.parent.parent, "utils/assets/ROMs/") | |
game_name = "Pokemon-Yellow" | |
current_game = os.path.join(rom_folder, game_name) | |
game_type = "gbc" | |
rom_path = os.path.join(current_game, f"{game_name}.{game_type}") | |
class BBPlays(commands.Cog): | |
def __init__(self, bot): | |
self.bot: Bot = bot | |
self.buttons = { | |
"up": (WindowEvent.PRESS_ARROW_UP, WindowEvent.RELEASE_ARROW_UP), | |
"down": (WindowEvent.PRESS_ARROW_DOWN, WindowEvent.RELEASE_ARROW_DOWN), | |
"left": (WindowEvent.PRESS_ARROW_LEFT, WindowEvent.RELEASE_ARROW_LEFT), | |
"right": (WindowEvent.PRESS_ARROW_RIGHT, WindowEvent.RELEASE_ARROW_RIGHT), | |
"b": (WindowEvent.PRESS_BUTTON_B, WindowEvent.RELEASE_BUTTON_B), | |
"a": (WindowEvent.PRESS_BUTTON_A, WindowEvent.RELEASE_BUTTON_A), | |
"select": (WindowEvent.PRESS_BUTTON_SELECT, WindowEvent.RELEASE_BUTTON_SELECT), | |
"start": (WindowEvent.PRESS_BUTTON_START, WindowEvent.RELEASE_BUTTON_START) | |
} | |
self.game = None | |
self.inputs = {"up": 0, "down": 0, "left": 0, "right": 0, "select": 0, "start": 0, "b": 0, "a": 0} | |
self.multipliers = {2: 0, 3: 0, 4: 0, 5: 0, 6: 0} | |
self.input_users = [] | |
self.multiplier_users = [] | |
self.loaded = False | |
def skip_frames(self, frames: int): | |
frames = frames * 60 | |
x = 0 | |
while x < frames: | |
self.game.tick() | |
x += 1 | |
async def cog_load(self): | |
if not self.loaded: | |
game = PyBoy(os.path.join(rom_path), window_type="headless") | |
self.game = game | |
if os.path.exists(os.path.join(current_game, "Pokemon-Yellow.state")): | |
self.game.load_state(open(os.path.join(current_game, "Pokemon-Yellow.state"), "rb")) | |
self.game_loop.start() | |
self.loaded = True | |
async def cog_unload(self): | |
self.game_loop.cancel() | |
self.game.stop() | |
self.loaded = False | |
@app_commands.command() | |
async def send_gameboy(self, interaction: discord.Interaction, channel: discord.TextChannel): | |
lbumper = Button(emoji="<:LBumper:1009706435124416574>", disabled=True, style=discord.ButtonStyle.blurple) | |
rbumper = Button(emoji="<:RBumper:1009706434361040957>", disabled=True, style=discord.ButtonStyle.blurple) | |
up = Button(emoji="<:Up:1009706432523939850>", style=discord.ButtonStyle.blurple) | |
down = Button(emoji="<:Down:1009706433421508688>", style=discord.ButtonStyle.blurple) | |
left = Button(emoji="<:Left:1009706429671800832>", style=discord.ButtonStyle.blurple) | |
right = Button(emoji="<:Right:1009706431148204043>", style=discord.ButtonStyle.blurple) | |
a = Button(emoji="<:AButton:1009706436936355842>", style=discord.ButtonStyle.blurple) | |
b = Button(emoji="<:BButton:1009706436265250856>", style=discord.ButtonStyle.blurple) | |
select = Button(emoji="<:Select:1009706428740665394>", style=discord.ButtonStyle.blurple) | |
start = Button(emoji="<:Start:1009706430691033098>", style=discord.ButtonStyle.blurple) | |
m2 = Button(emoji="2️⃣", style=discord.ButtonStyle.blurple) | |
m3 = Button(emoji="3️⃣", style=discord.ButtonStyle.blurple) | |
m4 = Button(emoji="4️⃣", style=discord.ButtonStyle.blurple) | |
m5 = Button(emoji="5️⃣", style=discord.ButtonStyle.blurple) | |
m6 = Button(emoji="6️⃣", style=discord.ButtonStyle.blurple) | |
view = View() | |
view.add_item(lbumper) | |
view.add_item(up) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(rbumper) | |
view.add_item(left) | |
view.add_item( | |
Button(emoji="<a:PikaDance:1009707955412807701>", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(right) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(a) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(down) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(b) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(m2) | |
view.add_item(m3) | |
view.add_item(m4) | |
view.add_item(m5) | |
view.add_item(m6) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(select) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
view.add_item(start) | |
view.add_item(Button(label=" ", disabled=True, style=discord.ButtonStyle.blurple)) | |
message = await channel.send(view=view) | |
em = discord.Embed(title="Gameboy info:", description=message.id) | |
em.add_field(name="Left Bumper:", value=lbumper.custom_id) | |
em.add_field(name="Right Bumper:", value=rbumper.custom_id) | |
em.add_field(name="Up:", value=up.custom_id) | |
em.add_field(name="Down:", value=down.custom_id) | |
em.add_field(name="Left:", value=left.custom_id) | |
em.add_field(name="Right:", value=right.custom_id) | |
em.add_field(name="A:", value=a.custom_id) | |
em.add_field(name="B:", value=b.custom_id) | |
em.add_field(name="Select:", value=select.custom_id) | |
em.add_field(name="Start:", value=start.custom_id) | |
em.add_field(name="2x:", value=m2.custom_id) | |
em.add_field(name="3x:", value=m3.custom_id) | |
em.add_field(name="4x:", value=m4.custom_id) | |
em.add_field(name="5x:", value=m5.custom_id) | |
em.add_field(name="6x:", value=m6.custom_id) | |
await interaction.user.send(embed=em) | |
await interaction.response.send_message("I have sent you the button IDs!") | |
def press_button(self, button: str, multiplier: int = 1): | |
self.game.send_input(self.buttons[button][0]) | |
for _ in range(15 * multiplier): | |
self.game.tick() | |
self.game.send_input(self.buttons[button][1]) | |
@loop(seconds=7) | |
async def game_loop(self): | |
choice = max(self.inputs, key=self.inputs.get) | |
multiplier = max(self.multipliers, key=self.multipliers.get) | |
if self.inputs[choice] > 0: | |
if self.multipliers[multiplier] > 0: | |
self.press_button(choice, multiplier) | |
else: | |
multiplier = 1 | |
self.press_button(choice) | |
else: | |
choice = "none" | |
if self.multipliers[multiplier] == 0: | |
multiplier = 1 | |
self.inputs = {"up": 0, "down": 0, "left": 0, "right": 0, "select": 0, "start": 0, "b": 0, "a": 0} | |
self.input_users = [] | |
self.multipliers = {2: 0, 3: 0, 4: 0, 5: 0, 6: 0} | |
self.multiplier_users = [] | |
if choice == "none": | |
self.skip_frames(5 * int(multiplier)) | |
else: | |
self.skip_frames(5) | |
blank = Image.new("RGB", (500, 426), (0, 0, 0)) | |
frame: Image = self.game.screen_image() | |
frame = frame.resize((426, 426)) | |
blank.paste(frame, (37, 0)) | |
temp = BytesIO() | |
blank.save(temp, "png") | |
temp.seek(0) | |
guild = self.bot.get_guild() | |
chan = guild.get_channel() | |
message = await chan.fetch_message() | |
await message.edit(content=f"Last selection was: {choice}*{multiplier}", attachments=[discord.File(fp=temp, filename="Screen.png")]) | |
self.game.save_state(open(os.path.join(current_game, f"{game_name}.state"), "wb")) | |
@commands.Cog.listener() | |
async def on_interaction(self, interaction: discord.Interaction): | |
data = interaction.data | |
if data and "component_type" in data and data["component_type"] == 2: | |
bid = data["custom_id"] | |
user = interaction.user | |
if bid in [ | |
"", # Up | |
"", # Left | |
"", # Right | |
"", # Down | |
"", # A | |
"", # B | |
"", # Select | |
"" # Start | |
]: | |
if user.id not in self.input_users: | |
if bid == "": | |
self.inputs["up"] += 1 | |
elif bid == "": | |
self.inputs["left"] += 1 | |
elif bid == "": | |
self.inputs["right"] += 1 | |
elif bid == "": | |
self.inputs["down"] += 1 | |
elif bid == "": | |
self.inputs["a"] += 1 | |
elif bid == "": | |
self.inputs["b"] += 1 | |
elif bid == "": | |
self.inputs["select"] += 1 | |
else: | |
self.inputs["start"] += 1 | |
self.input_users.append(user.id) | |
return await interaction.response.defer() | |
await interaction.response.send_message("You've already made a selection!", ephemeral=True) | |
if bid in [ | |
"", # 2 | |
"", # 3 | |
"", # 4 | |
"", # 5 | |
"" # 6 | |
]: | |
if user.id not in self.multiplier_users: | |
if bid == "": | |
self.multipliers[2] += 1 | |
elif bid == "": | |
self.multipliers[3] += 1 | |
elif bid == "": | |
self.multipliers[4] += 1 | |
elif bid == "": | |
self.multipliers[5] += 1 | |
else: | |
self.multipliers[6] += 1 | |
self.multiplier_users.append(user.id) | |
return await interaction.response.defer() | |
await interaction.response.send_message("You've already made a multiplier selection!", ephemeral=True) | |
async def setup(bot): | |
await bot.add_cog(BBPlays(bot)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment