mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-31 10:03:38 -07:00
* APQuest * Add confetti cannon * ID change on enemy drop * nevermind * Write the apworld * Actually implement hard mode * split everything into multiple files * Push out webworld into a file * Comment * Enemy health graphics * more ruff rules * graphics :) * heal player when receiving health upgrade * the dumbest client of all time * Fix typo * You can kinda play it now! Now we just need to render the game... :))) * fix kvui imports again * It's playable. Kind of * oops * Sounds and stuff * exceptions for audio * player sprite stuff * Not attack without sword * Make sure it plays correctly * Collect behavior * ruff * don't need to clear checked_locations, but do need to still clear finished_game * Connect calls disconnect, so this is not necessary * more seemless reconnection * Ok now I think it's correct * Bgm * Bgm * minor adjustment * More refactoring of graphics and sound * add graphics * Item column * Fix enemies not regaining their health * oops * oops * oops * 6 health final boss on hard mode * boss_6.png * Display APQuest items correctly * auto switch tabs * some mypy stuff * Intro song * Confetti Cannon * a bit more confetti work * launcher component * Graphics change * graphics and cleanup * fix apworld * comment out horse and cat for now * add docs * copypasta * ruff made my comment look unhinged * Move that comment * Fix typing and don't import kvui in nogui * lmao that already exists I don't need to do it myself * Must've just copied this from somewhere * order change * Add unit tests * Notes about the client * oops * another intro song case * Write WebWorld and setup guides * Yes description provided * thing * how to play * Music and Volume * Add cat and horse player sprites * updates * Add hammer and breakable wall * TODO * replace wav with ogg * Codeowners and readme * finish unit tests * lint * Todid * Update worlds/apquest/client/ap_quest_client.py Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> * Update worlds/apquest/client/custom_views.py Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> * Filler pattern * __future__ annotations * twebhost * Allow wasd and arrow keys * correct wording * oops * just say the website * append instead of += * qwint is onto my favoritism * kitty alias * Add a comment about preplaced items for assertAccessDependency * Use classvar_matrix instead of MultiworldTestBase * actually remove multiworld stuff from those tests * missed one more * Refactor a bit more * Fix getting of the user path * Actually explain components * Meh * Be a bit clearer about what's what * oops * More comments in the regions.py file * Nevermind * clarify regions further * I use too many brackets * Ok I'm done fr * simplify wording * missing . * Add precollected example * add note about precollected advancements * missing s * APQuest sound rework * Volume slider * I forgot I made this * a * fix volume of jingles * Add math trap to game (only works in play_in_console mode so far) * Math trap in apworld and client side * Fix background during math trap * fix leading 0 * Sound and further ui improvements for Math Trap * fix music bug * rename apquest subfolder to game * Move comment to where it belongs * Clear up language around components (hopefully) * Clear up what CommonClient is * Reword some more * Mention Archipelago (the program) explicitly * Update worlds/apquest/docs/en_APQuest.md Co-authored-by: Ixrec <ericrhitchcock@gmail.com> * Explain a bit more why you would use classvar matrix * reword the assert raises stuff * the volume slider thing is no longer true * german game page * Be more clear about why we're overriding Item and Location * default item classification * logically considered -> relevant to logic () * Update worlds/apquest/items.py Co-authored-by: Ixrec <ericrhitchcock@gmail.com> * a word on the ambiguity of the word 'filler' * more rewording * amount -> number * stress the necessity of appending to the multiworld itempool * Update worlds/apquest/locations.py Co-authored-by: Ixrec <ericrhitchcock@gmail.com> * get_location_names_with_ids * slight rewording of the new helper method * add some words about creating known location+item pairs * Add some more words to worlds/apqeust/options.py * more words in options.py * 120 chars (thanks Ixrec >:((( LOL) * Less confusing wording about rules, hopefully? * victory -> completion * remove the immediate creation of the hammer rule on the option region entrance * access rule performance * Make all imports module-level in world.py * formatting * get rid of noqa RUF012 (and also disable the rule in my local ruff.toml * move comment for docstring closer to docstring in another place * advancement???? * Missing function type annotations * pass mypy again (I don't love this one but all the alternatives are equally bad) * subclass instead of override * I forgor to remove these * Get rid of classvar_matrix and instead talk about some other stuff * protect people a bit from the assertAccessDependency nonsense * reword a bit more * word * More accessdependency text * More accessdependency text * More accessdependency text * More accessdependency text * oops * this is supposed to be absolute * Add some links to docs * that's called game now * Add an archipelago.json and explain what it means * new line who dis * reorganize a bit * ignore instead of skip * Update archipelago.json * She new on my line till I * Update archipelago.json * add controls tab * new ruff rule? idk * WHOOPS * Pack graphics into fewer files * annoying ruff format thing * Cleanup + mypy * relative import * Update worlds/apquest/client/custom_views.py Co-authored-by: Fabian Dill <Berserker66@users.noreply.github.com> * Update generate_math_problem.py * Update worlds/apquest/game/player.py Co-authored-by: Fabian Dill <Berserker66@users.noreply.github.com> --------- Co-authored-by: Duck <31627079+duckboycool@users.noreply.github.com> Co-authored-by: Ixrec <ericrhitchcock@gmail.com> Co-authored-by: Fabian Dill <Berserker66@users.noreply.github.com>
144 lines
4.5 KiB
Python
144 lines
4.5 KiB
Python
from .events import ConfettiFired, MathProblemSolved
|
|
|
|
try:
|
|
from pynput import keyboard
|
|
from pynput.keyboard import Key, KeyCode
|
|
except ImportError as e:
|
|
raise ImportError("In order to play APQuest from console, you have to install pynput.") from e
|
|
|
|
from .game import Game
|
|
from .graphics import Graphic
|
|
from .inputs import Input
|
|
from .items import ITEM_TO_GRAPHIC
|
|
|
|
graphic_to_char = {
|
|
Graphic.EMPTY: " ",
|
|
Graphic.WALL: "W",
|
|
Graphic.BUTTON_NOT_ACTIVATED: "B",
|
|
Graphic.BUTTON_ACTIVATED: "A",
|
|
Graphic.KEY_DOOR: "D",
|
|
Graphic.BUTTON_DOOR: "?",
|
|
Graphic.CHEST: "C",
|
|
Graphic.BUSH: "T",
|
|
Graphic.BREAKABLE_BLOCK: "~",
|
|
Graphic.NORMAL_ENEMY_2_HEALTH: "2",
|
|
Graphic.NORMAL_ENEMY_1_HEALTH: "1",
|
|
Graphic.BOSS_5_HEALTH: "5",
|
|
Graphic.BOSS_4_HEALTH: "4",
|
|
Graphic.BOSS_3_HEALTH: "3",
|
|
Graphic.BOSS_2_HEALTH: "2",
|
|
Graphic.BOSS_1_HEALTH: "1",
|
|
Graphic.PLAYER_DOWN: "v",
|
|
Graphic.PLAYER_UP: "^",
|
|
Graphic.PLAYER_LEFT: "<",
|
|
Graphic.PLAYER_RIGHT: ">",
|
|
Graphic.KEY: "K",
|
|
Graphic.SHIELD: "X",
|
|
Graphic.SWORD: "S",
|
|
Graphic.HAMMER: "H",
|
|
Graphic.HEART: "♡",
|
|
Graphic.CONFETTI_CANNON: "?",
|
|
Graphic.REMOTE_ITEM: "I",
|
|
Graphic.UNKNOWN: "ß",
|
|
Graphic.ZERO: "0",
|
|
Graphic.ONE: "1",
|
|
Graphic.TWO: "2",
|
|
Graphic.THREE: "3",
|
|
Graphic.FOUR: "4",
|
|
Graphic.FIVE: "5",
|
|
Graphic.SIX: "6",
|
|
Graphic.SEVEN: "7",
|
|
Graphic.EIGHT: "8",
|
|
Graphic.NINE: "9",
|
|
Graphic.PLUS: "+",
|
|
Graphic.MINUS: "-",
|
|
Graphic.TIMES: "x",
|
|
Graphic.DIVIDE: "/",
|
|
Graphic.LETTER_A: "A",
|
|
Graphic.LETTER_E: "E",
|
|
Graphic.LETTER_H: "H",
|
|
Graphic.LETTER_I: "I",
|
|
Graphic.LETTER_M: "M",
|
|
Graphic.LETTER_T: "T",
|
|
Graphic.EQUALS: "=",
|
|
Graphic.NO: "X",
|
|
}
|
|
|
|
KEY_CONVERSION = {
|
|
keyboard.KeyCode.from_char("w"): Input.UP,
|
|
Key.up: Input.UP,
|
|
keyboard.KeyCode.from_char("s"): Input.DOWN,
|
|
Key.down: Input.DOWN,
|
|
keyboard.KeyCode.from_char("a"): Input.LEFT,
|
|
Key.left: Input.LEFT,
|
|
keyboard.KeyCode.from_char("d"): Input.RIGHT,
|
|
Key.right: Input.RIGHT,
|
|
Key.space: Input.ACTION,
|
|
keyboard.KeyCode.from_char("c"): Input.CONFETTI,
|
|
keyboard.KeyCode.from_char("0"): Input.ZERO,
|
|
keyboard.KeyCode.from_char("1"): Input.ONE,
|
|
keyboard.KeyCode.from_char("2"): Input.TWO,
|
|
keyboard.KeyCode.from_char("3"): Input.THREE,
|
|
keyboard.KeyCode.from_char("4"): Input.FOUR,
|
|
keyboard.KeyCode.from_char("5"): Input.FIVE,
|
|
keyboard.KeyCode.from_char("6"): Input.SIX,
|
|
keyboard.KeyCode.from_char("7"): Input.SEVEN,
|
|
keyboard.KeyCode.from_char("8"): Input.EIGHT,
|
|
keyboard.KeyCode.from_char("9"): Input.NINE,
|
|
Key.backspace: Input.BACKSPACE,
|
|
}
|
|
|
|
|
|
def render_to_text(game: Game) -> str:
|
|
player = game.player
|
|
rendered_graphics = game.render()
|
|
|
|
output_string = f"Health: {player.current_health}/{player.max_health}\n"
|
|
|
|
inventory = []
|
|
for item, count in player.inventory.items():
|
|
inventory += [graphic_to_char[ITEM_TO_GRAPHIC[item]] for _ in range(count)]
|
|
inventory.sort()
|
|
|
|
output_string += f"Inventory: {', '.join(inventory)}\n"
|
|
|
|
if player.has_won:
|
|
output_string += "VICTORY!!!\n"
|
|
|
|
while game.queued_events:
|
|
next_event = game.queued_events.pop(0)
|
|
if isinstance(next_event, ConfettiFired):
|
|
output_string += "Confetti fired! You feel motivated :)\n"
|
|
if isinstance(next_event, MathProblemSolved):
|
|
output_string += "Math problem solved!\n"
|
|
|
|
for row in rendered_graphics:
|
|
output_string += " ".join(graphic_to_char[graphic] for graphic in row)
|
|
output_string += "\n"
|
|
|
|
return output_string
|
|
|
|
|
|
if __name__ == "__main__":
|
|
hard_mode = input("Do you want to play hard mode? (Y/N)").lower().strip() in ("y", "yes")
|
|
hammer_exists = input("Do you want the hammer to exist in the game? (Y/N)").lower().strip() in ("y", "yes")
|
|
extra_chest = input("Do you want the extra starting chest to exist in the game?").lower().strip() in ("y", "yes")
|
|
math_trap_percentage = int(input("What should the percentage of math traps be?"))
|
|
|
|
game = Game(hard_mode, hammer_exists, extra_chest)
|
|
game.gameboard.fill_default_location_content(math_trap_percentage)
|
|
|
|
def input_and_rerender(input_key: Input) -> None:
|
|
game.input(input_key)
|
|
print(render_to_text(game))
|
|
|
|
def on_press(key: Key | KeyCode | None) -> None:
|
|
if key in KEY_CONVERSION:
|
|
input_and_rerender(KEY_CONVERSION[key])
|
|
|
|
print(render_to_text(game))
|
|
|
|
with keyboard.Listener(on_press=on_press) as listener:
|
|
while True:
|
|
listener.join()
|