Merge branch 'master' into 'lighting'

# Conflicts:
#   squirrelbattle/display/mapdisplay.py
#   squirrelbattle/interfaces.py
This commit is contained in:
2021-01-07 16:36:54 +01:00
32 changed files with 1085 additions and 395 deletions

View File

@ -6,6 +6,7 @@ import unittest
from squirrelbattle.entities.items import BodySnatchPotion, Bomb, Heart, Item, \
Explosion
from squirrelbattle.entities.monsters import Tiger, Hedgehog, Rabbit, TeddyBear
from squirrelbattle.entities.friendly import Trumpet
from squirrelbattle.entities.player import Player
from squirrelbattle.interfaces import Entity, Map
from squirrelbattle.resources import ResourceManager
@ -14,7 +15,7 @@ from squirrelbattle.resources import ResourceManager
class TestEntities(unittest.TestCase):
def setUp(self) -> None:
"""
Load example map that can be used in tests.
Loads example map that can be used in tests.
"""
self.map = Map.load(ResourceManager.get_asset_path("example_map.txt"))
self.player = Player()
@ -23,7 +24,7 @@ class TestEntities(unittest.TestCase):
def test_basic_entities(self) -> None:
"""
Test some random stuff with basic entities.
Tests some random stuff with basic entities.
"""
entity = Entity()
entity.move(42, 64)
@ -38,7 +39,7 @@ class TestEntities(unittest.TestCase):
def test_fighting_entities(self) -> None:
"""
Test some random stuff with fighting entities.
Tests some random stuff with fighting entities.
"""
entity = Tiger()
self.map.add_entity(entity)
@ -57,17 +58,17 @@ class TestEntities(unittest.TestCase):
self.map.add_entity(entity)
entity.move(15, 44)
# Move randomly
self.map.tick()
self.map.tick(self.player)
self.assertFalse(entity.y == 15 and entity.x == 44)
# Move to the player
entity.move(3, 6)
self.map.tick()
self.map.tick(self.player)
self.assertTrue(entity.y == 2 and entity.x == 6)
# Rabbit should fight
old_health = self.player.health
self.map.tick()
self.map.tick(self.player)
self.assertTrue(entity.y == 2 and entity.x == 6)
self.assertEqual(old_health - entity.strength, self.player.health)
self.assertEqual(self.map.logs.messages[-1],
@ -89,9 +90,50 @@ class TestEntities(unittest.TestCase):
self.assertTrue(entity.dead)
self.assertGreaterEqual(self.player.current_xp, 3)
# Test the familiars
fam = Trumpet()
entity = Rabbit()
self.map.add_entity(entity)
self.map.add_entity(fam)
self.player.move(1, 6)
entity.move(2, 6)
fam.move(2, 7)
# Test fighting
entity.health = 2
entity.paths = []
entity.recalculate_paths()
fam.target = entity
self.map.tick(self.player)
self.assertTrue(entity.dead)
# Test finding a new target
entity2 = Rabbit()
self.map.add_entity(entity2)
entity2.move(2, 6)
self.map.tick(self.player)
self.assertTrue(fam.target == entity2)
self.map.remove_entity(entity2)
# Test following the player and finding the player as target
self.player.move(5, 5)
fam.move(4, 5)
fam.target = None
self.player.move_down()
self.map.tick(self.player)
self.assertTrue(fam.target == self.player)
self.assertEqual(fam.y, 5)
self.assertEqual(fam.x, 5)
# Test random move
fam.move(13, 20)
fam.target = self.player
self.map.tick(self.player)
self.assertTrue(fam.x != 20 or fam.y != 13)
def test_items(self) -> None:
"""
Test some random stuff with items.
Tests some random stuff with items.
"""
item = Item()
self.map.add_entity(item)
@ -112,7 +154,7 @@ class TestEntities(unittest.TestCase):
def test_bombs(self) -> None:
"""
Test some random stuff with bombs.
Tests some random stuff with bombs.
"""
item = Bomb()
hedgehog = Hedgehog()
@ -156,7 +198,7 @@ class TestEntities(unittest.TestCase):
def test_hearts(self) -> None:
"""
Test some random stuff with hearts.
Tests some random stuff with hearts.
"""
item = Heart()
self.map.add_entity(item)
@ -171,7 +213,7 @@ class TestEntities(unittest.TestCase):
def test_body_snatch_potion(self) -> None:
"""
Test some random stuff with body snatch potions.
Tests some random stuff with body snatch potions.
"""
item = BodySnatchPotion()
self.map.add_entity(item)
@ -189,7 +231,7 @@ class TestEntities(unittest.TestCase):
def test_players(self) -> None:
"""
Test some random stuff with players.
Tests some random stuff with players.
"""
player = Player()
self.map.add_entity(player)

View File

@ -12,6 +12,7 @@ from ..entities.items import Bomb, Heart, Sword, Explosion
from ..entities.player import Player
from ..enums import DisplayActions
from ..game import Game, KeyValues, GameMode
from ..interfaces import Map
from ..menus import MainMenuValues
from ..resources import ResourceManager
from ..settings import Settings
@ -21,17 +22,21 @@ from ..translations import gettext as _, Translator
class TestGame(unittest.TestCase):
def setUp(self) -> None:
"""
Setup game.
Sets the game up.
"""
self.game = Game()
self.game.new_game()
self.game.map = Map.load(
ResourceManager.get_asset_path("example_map.txt"))
self.game.map.add_entity(self.game.player)
self.game.player.move(self.game.map.start_y, self.game.map.start_x)
self.game.logs.add_message("Hello World !")
display = DisplayManager(None, self.game)
self.game.display_actions = display.handle_display_action
def test_load_game(self) -> None:
"""
Save a game and reload it.
Saves a game and reloads it.
"""
bomb = Bomb()
self.game.map.add_entity(bomb)
@ -85,7 +90,7 @@ class TestGame(unittest.TestCase):
def test_bootstrap_fail(self) -> None:
"""
Ensure that the test can't play the game,
Ensures that the test can't play the game,
because there is no associated shell.
Yeah, that's only for coverage.
"""
@ -94,7 +99,7 @@ class TestGame(unittest.TestCase):
def test_key_translation(self) -> None:
"""
Test key bindings.
Tests key bindings.
"""
self.game.settings = Settings()
@ -143,6 +148,9 @@ class TestGame(unittest.TestCase):
self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_WAIT, self.game.settings),
KeyValues.WAIT)
self.assertEqual(KeyValues.translate_key(
self.game.settings.KEY_LADDER, self.game.settings),
KeyValues.LADDER)
self.assertEqual(KeyValues.translate_key(' ', self.game.settings),
KeyValues.SPACE)
self.assertEqual(KeyValues.translate_key('plop', self.game.settings),
@ -150,7 +158,7 @@ class TestGame(unittest.TestCase):
def test_key_press(self) -> None:
"""
Press a key and see what is done.
Presses a key and asserts what is done is correct.
"""
self.assertEqual(self.game.state, GameMode.MAINMENU)
self.assertEqual(self.game.main_menu.validate(),
@ -241,7 +249,7 @@ class TestGame(unittest.TestCase):
def test_mouse_click(self) -> None:
"""
Simulate mouse clicks.
Simulates mouse clicks.
"""
self.game.state = GameMode.MAINMENU
@ -271,7 +279,7 @@ class TestGame(unittest.TestCase):
def test_new_game(self) -> None:
"""
Ensure that the start button starts a new game.
Ensures that the start button starts a new game.
"""
old_map = self.game.map
old_player = self.game.player
@ -294,7 +302,7 @@ class TestGame(unittest.TestCase):
def test_settings_menu(self) -> None:
"""
Ensure that the settings menu is working properly.
Ensures that the settings menu is working properly.
"""
self.game.settings = Settings()
@ -333,7 +341,7 @@ class TestGame(unittest.TestCase):
self.assertEqual(self.game.settings.KEY_LEFT_PRIMARY, 'a')
# Navigate to "texture pack"
for ignored in range(11):
for ignored in range(12):
self.game.handle_key_pressed(KeyValues.DOWN)
# Change texture pack
@ -380,7 +388,7 @@ class TestGame(unittest.TestCase):
def test_dead_screen(self) -> None:
"""
Kill player and render dead screen.
Kills the player and renders the dead message on the fake screen.
"""
self.game.state = GameMode.PLAY
# Kill player
@ -396,13 +404,14 @@ class TestGame(unittest.TestCase):
def test_not_implemented(self) -> None:
"""
Check that some functions are not implemented, only for coverage.
Checks that some functions are not implemented, only for coverage.
"""
self.assertRaises(NotImplementedError, Display.display, None)
self.assertRaises(NotImplementedError, Display.update, None, self.game)
def test_messages(self) -> None:
"""
Display error messages.
Displays error messages.
"""
self.game.message = "I am an error"
self.game.display_actions(DisplayActions.UPDATE)
@ -412,7 +421,7 @@ class TestGame(unittest.TestCase):
def test_inventory_menu(self) -> None:
"""
Open the inventory menu and interact with items.
Opens the inventory menu and interacts with items.
"""
self.game.state = GameMode.PLAY
# Open and close the inventory
@ -473,7 +482,7 @@ class TestGame(unittest.TestCase):
def test_talk_to_sunflowers(self) -> None:
"""
Interact with sunflowers
Interacts with sunflowers.
"""
self.game.state = GameMode.PLAY
@ -524,7 +533,7 @@ class TestGame(unittest.TestCase):
def test_talk_to_merchant(self) -> None:
"""
Interact with merchants
Interacts with merchants.
"""
self.game.state = GameMode.PLAY
@ -546,18 +555,21 @@ class TestGame(unittest.TestCase):
# Navigate in the menu
self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.DOWN)
self.game.handle_key_pressed(KeyValues.LEFT)
self.assertFalse(self.game.is_in_store_menu)
self.game.handle_key_pressed(KeyValues.RIGHT)
self.assertTrue(self.game.is_in_store_menu)
self.game.handle_key_pressed(KeyValues.UP)
self.assertEqual(self.game.store_menu.position, 1)
self.game.player.hazel = 0x7ffff42ff
# The second item is not a heart
merchant.inventory[1] = Sword()
merchant.inventory[1] = sword = Sword()
# Buy the second item by clicking on it
item = self.game.store_menu.validate()
self.assertIn(item, merchant.inventory)
self.game.display_actions(DisplayActions.MOUSE, 7, 25)
self.game.handle_key_pressed(KeyValues.ENTER)
self.assertIn(item, self.game.player.inventory)
self.assertNotIn(item, merchant.inventory)
@ -579,9 +591,71 @@ class TestGame(unittest.TestCase):
self.game.handle_key_pressed(KeyValues.ENTER)
self.assertNotIn(item, self.game.player.inventory)
self.assertIn(item, merchant.inventory)
self.assertEqual(self.game.message, _("You do not have enough money"))
self.assertEqual(self.game.message,
_("The buyer does not have enough money"))
self.game.handle_key_pressed(KeyValues.ENTER)
# Sell an item
self.game.inventory_menu.position = len(self.game.player.inventory) - 1
self.game.handle_key_pressed(KeyValues.LEFT)
self.assertFalse(self.game.is_in_store_menu)
self.assertIn(sword, self.game.player.inventory)
self.assertEqual(self.game.inventory_menu.validate(), sword)
old_player_money, old_merchant_money = self.game.player.hazel,\
merchant.hazel
self.game.handle_key_pressed(KeyValues.ENTER)
self.assertNotIn(sword, self.game.player.inventory)
self.assertIn(sword, merchant.inventory)
self.assertEqual(self.game.player.hazel, old_player_money + sword.price)
self.assertEqual(merchant.hazel, old_merchant_money - sword.price)
# Exit the menu
self.game.handle_key_pressed(KeyValues.SPACE)
self.assertEqual(self.game.state, GameMode.PLAY)
def test_ladders(self) -> None:
"""
Ensure that the player can climb on ladders.
"""
self.game.state = GameMode.PLAY
self.assertEqual(self.game.player.map.floor, 0)
self.game.handle_key_pressed(KeyValues.LADDER)
self.assertEqual(self.game.player.map.floor, 0)
# Move nowhere
self.game.player.move(10, 10)
self.game.handle_key_pressed(KeyValues.LADDER)
self.assertEqual(self.game.player.map.floor, 0)
# Move down
self.game.player.move(3, 40) # Move on a ladder
self.game.handle_key_pressed(KeyValues.LADDER)
self.assertEqual(self.game.map_index, 1)
self.assertEqual(self.game.player.map.floor, 1)
self.assertEqual(self.game.player.y, 1)
self.assertEqual(self.game.player.x, 17)
self.game.display_actions(DisplayActions.UPDATE)
# Move up
self.game.handle_key_pressed(KeyValues.LADDER)
self.assertEqual(self.game.player.map.floor, 0)
self.assertEqual(self.game.player.y, 3)
self.assertEqual(self.game.player.x, 40)
self.game.display_actions(DisplayActions.UPDATE)
def test_credits(self) -> None:
"""
Load credits menu.
"""
self.game.state = GameMode.MAINMENU
self.game.display_actions(DisplayActions.MOUSE, 41, 41)
self.assertEqual(self.game.state, GameMode.CREDITS)
self.game.display_actions(DisplayActions.MOUSE, 21, 21)
self.game.display_actions(DisplayActions.REFRESH)
self.game.state = GameMode.CREDITS
self.game.handle_key_pressed(KeyValues.ENTER)
self.assertEqual(self.game.state, GameMode.MAINMENU)

View File

@ -11,7 +11,7 @@ from squirrelbattle.resources import ResourceManager
class TestInterfaces(unittest.TestCase):
def test_map(self) -> None:
"""
Create a map and check that it is well parsed.
Creates a map and checks that it is well parsed.
"""
m = Map.load_from_string("0 0\n.#\n#.\n")
self.assertEqual(m.width, 2)
@ -20,7 +20,7 @@ class TestInterfaces(unittest.TestCase):
def test_load_map(self) -> None:
"""
Try to load a map from a file.
Tries to load a map from a file.
"""
m = Map.load(ResourceManager.get_asset_path("example_map.txt"))
self.assertEqual(m.width, 52)
@ -28,7 +28,7 @@ class TestInterfaces(unittest.TestCase):
def test_tiles(self) -> None:
"""
Test some things about tiles.
Tests some things about tiles.
"""
self.assertFalse(Tile.FLOOR.is_wall())
self.assertTrue(Tile.WALL.is_wall())

View File

@ -12,8 +12,8 @@ class FakePad:
def addstr(self, y: int, x: int, message: str, color: int = 0) -> None:
pass
def refresh(self, pminrow: int, pmincol: int, sminrow: int,
smincol: int, smaxrow: int, smaxcol: int) -> None:
def noutrefresh(self, pminrow: int, pmincol: int, sminrow: int,
smincol: int, smaxrow: int, smaxcol: int) -> None:
pass
def erase(self) -> None:
@ -24,3 +24,6 @@ class FakePad:
def getmaxyx(self) -> Tuple[int, int]:
return 42, 42
def inch(self, y: int, x: int) -> str:
return "i"

View File

@ -13,7 +13,7 @@ class TestSettings(unittest.TestCase):
def test_settings(self) -> None:
"""
Ensure that settings are well loaded.
Ensures that settings are well loaded.
"""
settings = Settings()
self.assertEqual(settings.KEY_UP_PRIMARY, 'z')

View File

@ -11,7 +11,7 @@ class TestTranslations(unittest.TestCase):
def test_main_menu_translation(self) -> None:
"""
Ensure that the main menu is translated.
Ensures that the main menu is translated.
"""
self.assertEqual(_("New game"), "Nouvelle partie")
self.assertEqual(_("Resume"), "Continuer")
@ -22,7 +22,7 @@ class TestTranslations(unittest.TestCase):
def test_settings_menu_translation(self) -> None:
"""
Ensure that the settings menu is translated.
Ensures that the settings menu is translated.
"""
self.assertEqual(_("Main key to move up"),
"Touche principale pour aller vers le haut")
@ -53,6 +53,8 @@ class TestTranslations(unittest.TestCase):
self.assertEqual(_("Key used to talk to a friendly entity"),
"Touche pour parler à une entité pacifique")
self.assertEqual(_("Key used to wait"), "Touche pour attendre")
self.assertEqual(_("Key used to use ladders"),
"Touche pour utiliser les échelles")
self.assertEqual(_("Texture pack"), "Pack de textures")
self.assertEqual(_("Language"), "Langue")