Merge branch 'master' into map_generation

# Conflicts:
#	squirrelbattle/entities/player.py
#	squirrelbattle/game.py
#	squirrelbattle/interfaces.py
#	squirrelbattle/tests/game_test.py
This commit is contained in:
Yohann D'ANELLO
2021-01-10 22:16:11 +01:00
54 changed files with 1909 additions and 934 deletions

View File

@ -1,20 +1,20 @@
# Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse
# Copyright (C) 2020-2021 by ÿnérant, eichhornchen, nicomarg, charlse
# SPDX-License-Identifier: GPL-3.0-or-later
from json import JSONDecodeError
from typing import Any, Optional, List
import curses
import json
from json import JSONDecodeError
import os
import sys
from typing import Any, List, Optional
from . import menus
from .entities.player import Player
from .enums import GameMode, KeyValues, DisplayActions
from .interfaces import Map, Logs
from .enums import DisplayActions, GameMode, KeyValues
from .interfaces import Logs, Map
from .mapgeneration import broguelike
from .resources import ResourceManager
from .settings import Settings
from . import menus
from .translations import gettext as _, Translator
@ -35,7 +35,9 @@ class Game:
"""
self.state = GameMode.MAINMENU
self.waiting_for_friendly_key = False
self.waiting_for_launch_key = False
self.is_in_store_menu = True
self.is_in_chest_menu = True
self.settings = Settings()
self.settings.load_settings()
self.settings.write_settings()
@ -45,6 +47,7 @@ class Game:
self.settings_menu.update_values(self.settings)
self.inventory_menu = menus.InventoryMenu()
self.store_menu = menus.StoreMenu()
self.chest_menu = menus.ChestMenu()
self.logs = Logs()
self.message = None
@ -119,6 +122,9 @@ class Game:
if self.waiting_for_friendly_key:
# The player requested to talk with a friendly entity
self.handle_friendly_entity_chat(key)
elif self.waiting_for_launch_key:
# The player requested to launch
self.handle_launch(key)
else:
self.handle_key_pressed_play(key)
elif self.state == GameMode.INVENTORY:
@ -129,6 +135,8 @@ class Game:
self.settings_menu.handle_key_pressed(key, raw_key, self)
elif self.state == GameMode.STORE:
self.handle_key_pressed_store(key)
elif self.state == GameMode.CHEST:
self.handle_key_pressed_chest(key)
elif self.state == GameMode.CREDITS:
self.state = GameMode.MAINMENU
self.display_actions(DisplayActions.REFRESH)
@ -157,6 +165,9 @@ class Game:
self.player.equipped_main.use()
if self.player.equipped_secondary:
self.player.equipped_secondary.use()
elif key == KeyValues.LAUNCH:
# Wait for the direction to launch in
self.waiting_for_launch_key = True
elif key == KeyValues.SPACE:
self.state = GameMode.MAINMENU
elif key == KeyValues.CHAT:
@ -166,6 +177,9 @@ class Game:
self.map.tick(self.player)
elif key == KeyValues.LADDER:
self.handle_ladder()
elif key == KeyValues.DANCE:
self.player.dance()
self.map.tick(self.player)
def handle_ladder(self) -> None:
"""
@ -246,6 +260,36 @@ class Game:
self.is_in_store_menu = True
self.store_menu.update_merchant(entity)
self.display_actions(DisplayActions.UPDATE)
elif entity.is_chest():
self.state = GameMode.CHEST
self.is_in_chest_menu = True
self.chest_menu.update_chest(entity)
self.display_actions(DisplayActions.UPDATE)
def handle_launch(self, key: KeyValues) -> None:
"""
If the player tries to throw something in a direction, the game looks
for entities in that direction and within the range of the player's
weapon and adds damage
"""
if not self.waiting_for_launch_key:
return
self.waiting_for_launch_key = False
if key == KeyValues.UP:
direction = 0
elif key == KeyValues.DOWN:
direction = 2
elif key == KeyValues.LEFT:
direction = 3
elif key == KeyValues.RIGHT:
direction = 1
else:
return
if self.player.equipped_main:
if self.player.equipped_main.throw(direction):
self.map.tick(self.player)
def handle_key_pressed_inventory(self, key: KeyValues) -> None:
"""
@ -302,6 +346,36 @@ class Game:
# Ensure that the cursor has a good position
menu.position = min(menu.position, len(menu.values) - 1)
def handle_key_pressed_chest(self, key: KeyValues) -> None:
"""
In a chest menu, we can take or put items or close the menu.
"""
menu = self.chest_menu if self.is_in_chest_menu else self.inventory_menu
if key == KeyValues.SPACE or key == KeyValues.INVENTORY:
self.state = GameMode.PLAY
elif key == KeyValues.UP:
menu.go_up()
elif key == KeyValues.DOWN:
menu.go_down()
elif key == KeyValues.LEFT:
self.is_in_chest_menu = False
self.display_actions(DisplayActions.UPDATE)
elif key == KeyValues.RIGHT:
self.is_in_chest_menu = True
self.display_actions(DisplayActions.UPDATE)
if menu.values and not self.player.dead:
if key == KeyValues.ENTER:
item = menu.validate()
owner = self.chest_menu.chest if self.is_in_chest_menu \
else self.player
buyer = self.player if self.is_in_chest_menu \
else self.chest_menu.chest
item.be_sold(buyer, owner, for_free=True)
self.display_actions(DisplayActions.UPDATE)
# Ensure that the cursor has a good position
menu.position = min(menu.position, len(menu.values) - 1)
def handle_key_pressed_main_menu(self, key: KeyValues) -> None:
"""
In the main menu, we can navigate through different options.
@ -343,9 +417,10 @@ class Game:
self.maps = [Map().load_state(map_dict) for map_dict in d["maps"]]
for i, m in enumerate(self.maps):
m.floor = i
except KeyError:
except KeyError as error:
self.message = _("Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted.")
"Your save seems to be corrupt. It got deleted.")\
+ f"\n{error}"
os.unlink(ResourceManager.get_config_path("save.json"))
self.display_actions(DisplayActions.UPDATE)
return
@ -359,6 +434,7 @@ class Game:
return
self.player = players[0]
self.inventory_menu.update_player(self.player)
self.map.compute_visibility(self.player.y, self.player.x,
self.player.vision)
self.display_actions(DisplayActions.UPDATE)