mima-engine 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mima/__init__.py +4 -0
- mima/backend/__init__.py +1 -0
- mima/backend/pygame_assets.py +401 -0
- mima/backend/pygame_audio.py +78 -0
- mima/backend/pygame_backend.py +603 -0
- mima/backend/pygame_camera.py +63 -0
- mima/backend/pygame_events.py +695 -0
- mima/backend/touch_control_scheme_a.py +126 -0
- mima/backend/touch_control_scheme_b.py +132 -0
- mima/core/__init__.py +0 -0
- mima/core/collision.py +325 -0
- mima/core/database.py +58 -0
- mima/core/engine.py +367 -0
- mima/core/mode_engine.py +81 -0
- mima/core/scene_engine.py +81 -0
- mima/integrated/__init__.py +0 -0
- mima/integrated/entity.py +183 -0
- mima/integrated/layered_map.py +351 -0
- mima/integrated/sprite.py +156 -0
- mima/layered/__init__.py +0 -0
- mima/layered/assets.py +56 -0
- mima/layered/scene.py +415 -0
- mima/layered/shape.py +99 -0
- mima/layered/shaped_sprite.py +78 -0
- mima/layered/virtual_input.py +302 -0
- mima/maps/__init__.py +0 -0
- mima/maps/template.py +71 -0
- mima/maps/tile.py +20 -0
- mima/maps/tile_animation.py +7 -0
- mima/maps/tile_info.py +10 -0
- mima/maps/tile_layer.py +52 -0
- mima/maps/tiled/__init__.py +0 -0
- mima/maps/tiled/tiled_layer.py +48 -0
- mima/maps/tiled/tiled_map.py +95 -0
- mima/maps/tiled/tiled_object.py +79 -0
- mima/maps/tiled/tiled_objectgroup.py +25 -0
- mima/maps/tiled/tiled_template.py +49 -0
- mima/maps/tiled/tiled_tile.py +90 -0
- mima/maps/tiled/tiled_tileset.py +51 -0
- mima/maps/tilemap.py +216 -0
- mima/maps/tileset.py +39 -0
- mima/maps/tileset_info.py +9 -0
- mima/maps/transition_map.py +146 -0
- mima/objects/__init__.py +0 -0
- mima/objects/animated_sprite.py +217 -0
- mima/objects/attribute_effect.py +26 -0
- mima/objects/attributes.py +126 -0
- mima/objects/creature.py +384 -0
- mima/objects/dynamic.py +206 -0
- mima/objects/effects/__init__.py +0 -0
- mima/objects/effects/colorize_screen.py +60 -0
- mima/objects/effects/debug_box.py +133 -0
- mima/objects/effects/light.py +103 -0
- mima/objects/effects/show_sprite.py +50 -0
- mima/objects/effects/walking_on_grass.py +70 -0
- mima/objects/effects/walking_on_water.py +57 -0
- mima/objects/loader.py +111 -0
- mima/objects/projectile.py +111 -0
- mima/objects/sprite.py +116 -0
- mima/objects/world/__init__.py +0 -0
- mima/objects/world/color_gate.py +67 -0
- mima/objects/world/color_switch.py +101 -0
- mima/objects/world/container.py +175 -0
- mima/objects/world/floor_switch.py +109 -0
- mima/objects/world/gate.py +178 -0
- mima/objects/world/light_source.py +121 -0
- mima/objects/world/logic_gate.py +157 -0
- mima/objects/world/movable.py +399 -0
- mima/objects/world/oneway.py +195 -0
- mima/objects/world/pickup.py +157 -0
- mima/objects/world/switch.py +179 -0
- mima/objects/world/teleport.py +308 -0
- mima/py.typed +0 -0
- mima/scripts/__init__.py +2 -0
- mima/scripts/command.py +38 -0
- mima/scripts/commands/__init__.py +0 -0
- mima/scripts/commands/add_quest.py +19 -0
- mima/scripts/commands/change_map.py +34 -0
- mima/scripts/commands/close_dialog.py +9 -0
- mima/scripts/commands/equip_weapon.py +23 -0
- mima/scripts/commands/give_item.py +26 -0
- mima/scripts/commands/give_resource.py +51 -0
- mima/scripts/commands/move_map.py +152 -0
- mima/scripts/commands/move_to.py +49 -0
- mima/scripts/commands/oneway_move.py +58 -0
- mima/scripts/commands/parallel.py +66 -0
- mima/scripts/commands/play_sound.py +13 -0
- mima/scripts/commands/present_item.py +53 -0
- mima/scripts/commands/progress_quest.py +12 -0
- mima/scripts/commands/quit_game.py +8 -0
- mima/scripts/commands/save_game.py +14 -0
- mima/scripts/commands/screen_fade.py +83 -0
- mima/scripts/commands/serial.py +69 -0
- mima/scripts/commands/set_facing_direction.py +21 -0
- mima/scripts/commands/set_spawn_map.py +17 -0
- mima/scripts/commands/show_choices.py +52 -0
- mima/scripts/commands/show_dialog.py +118 -0
- mima/scripts/commands/take_coins.py +23 -0
- mima/scripts/script_processor.py +61 -0
- mima/standalone/__init__.py +0 -0
- mima/standalone/camera.py +153 -0
- mima/standalone/geometry.py +1318 -0
- mima/standalone/multicolumn_list.py +54 -0
- mima/standalone/pixel_font.py +84 -0
- mima/standalone/scripting.py +145 -0
- mima/standalone/spatial.py +186 -0
- mima/standalone/sprite.py +158 -0
- mima/standalone/tiled_map.py +1247 -0
- mima/standalone/transformed_view.py +433 -0
- mima/standalone/user_input.py +563 -0
- mima/states/__init__.py +0 -0
- mima/states/game_state.py +189 -0
- mima/states/memory.py +28 -0
- mima/states/quest.py +71 -0
- mima/types/__init__.py +0 -0
- mima/types/alignment.py +7 -0
- mima/types/blend.py +8 -0
- mima/types/damage.py +42 -0
- mima/types/direction.py +44 -0
- mima/types/gate_color.py +7 -0
- mima/types/graphic_state.py +23 -0
- mima/types/keys.py +64 -0
- mima/types/mode.py +9 -0
- mima/types/nature.py +12 -0
- mima/types/object.py +22 -0
- mima/types/player.py +9 -0
- mima/types/position.py +13 -0
- mima/types/start.py +7 -0
- mima/types/terrain.py +9 -0
- mima/types/tile_collision.py +11 -0
- mima/types/weapon_slot.py +6 -0
- mima/types/window.py +44 -0
- mima/usables/__init__.py +0 -0
- mima/usables/item.py +51 -0
- mima/usables/weapon.py +68 -0
- mima/util/__init__.py +1 -0
- mima/util/colors.py +50 -0
- mima/util/constants.py +55 -0
- mima/util/functions.py +38 -0
- mima/util/input_defaults.py +170 -0
- mima/util/logging.py +51 -0
- mima/util/property.py +8 -0
- mima/util/runtime_config.py +327 -0
- mima/util/trading_item.py +23 -0
- mima/view/__init__.py +0 -0
- mima/view/camera.py +192 -0
- mima/view/mima_mode.py +618 -0
- mima/view/mima_scene.py +231 -0
- mima/view/mima_view.py +12 -0
- mima/view/mima_window.py +244 -0
- mima_engine-0.4.0.dist-info/METADATA +47 -0
- mima_engine-0.4.0.dist-info/RECORD +153 -0
- mima_engine-0.4.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from ..command import Command
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from ...states.quest import Quest
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CommandAddQuest(Command):
|
|
12
|
+
def __init__(self, quest: Quest):
|
|
13
|
+
super().__init__()
|
|
14
|
+
|
|
15
|
+
self._quest: Quest = quest
|
|
16
|
+
|
|
17
|
+
def start(self):
|
|
18
|
+
self.engine.add_quest(self._quest)
|
|
19
|
+
self.completed = True
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from ...types.player import Player
|
|
4
|
+
from ..command import Command
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CommandChangeMap(Command):
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
map_name: str,
|
|
11
|
+
spawn_px: float,
|
|
12
|
+
spawn_py,
|
|
13
|
+
players: Optional[List[Player]] = None,
|
|
14
|
+
):
|
|
15
|
+
if players is None:
|
|
16
|
+
players = [Player.P1]
|
|
17
|
+
|
|
18
|
+
super().__init__(players)
|
|
19
|
+
|
|
20
|
+
self._map_name: str = map_name
|
|
21
|
+
self._spawn_px: float = spawn_px
|
|
22
|
+
self._spawn_py: float = spawn_py
|
|
23
|
+
|
|
24
|
+
def start(self):
|
|
25
|
+
self.engine.get_view().unload_map(self.players[0])
|
|
26
|
+
self.engine.get_view().load_map(
|
|
27
|
+
self._map_name, self._spawn_px, self._spawn_py, self.players[0]
|
|
28
|
+
)
|
|
29
|
+
# self.engine.change_map(self._map_name, self._spawn_px, self._spawn_py)
|
|
30
|
+
self.completed = True
|
|
31
|
+
|
|
32
|
+
def finalize(self):
|
|
33
|
+
self.engine.trigger_teleport(False, self.players[0])
|
|
34
|
+
self.engine.trigger_player_collision(False, self.players[0])
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
from ..command import Command
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from ...objects.creature import Creature
|
|
9
|
+
from ...types.weapon_slot import WeaponSlot
|
|
10
|
+
from ...usables.weapon import Weapon
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CommandEquipWeapon(Command):
|
|
14
|
+
def __init__(self, weapon: Weapon, creature: Creature, slot: WeaponSlot):
|
|
15
|
+
super().__init__()
|
|
16
|
+
|
|
17
|
+
self._weapon: Weapon = weapon
|
|
18
|
+
self._target: Creature = creature
|
|
19
|
+
self._slot: WeaponSlot = slot
|
|
20
|
+
|
|
21
|
+
def start(self):
|
|
22
|
+
self._target.equip_weapon(self._slot, self._weapon)
|
|
23
|
+
self.completed = True
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
from ..command import Command
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from ...objects.dynamic import Dynamic
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CommandGiveItem(Command):
|
|
12
|
+
def __init__(self, item_name: str, dynamic: Optional[Dynamic] = None):
|
|
13
|
+
super().__init__()
|
|
14
|
+
|
|
15
|
+
self._item_name: str = item_name
|
|
16
|
+
|
|
17
|
+
# if dynamic is None:
|
|
18
|
+
# dynamic = self.engine.player
|
|
19
|
+
|
|
20
|
+
self._dynamic: Dynamic = dynamic
|
|
21
|
+
|
|
22
|
+
def start(self):
|
|
23
|
+
# if self._dynamic is None:
|
|
24
|
+
# self._dynamic = self.engine.get_player(self.players[0])
|
|
25
|
+
self.engine.give_item(self._item_name, self.players[0])
|
|
26
|
+
self.completed = True
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Dict, Optional
|
|
4
|
+
|
|
5
|
+
from ..command import Command
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from ...objects.dynamic import Dynamic
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CommandGiveResource(Command):
|
|
12
|
+
def __init__(self, dynamic: Optional[Dynamic] = None, **resources: Dict[str, int]):
|
|
13
|
+
super().__init__()
|
|
14
|
+
|
|
15
|
+
if dynamic is None:
|
|
16
|
+
dynamic = self.engine.player
|
|
17
|
+
|
|
18
|
+
self._dynamic: Dynamic = dynamic
|
|
19
|
+
self._health: int = resources.get("health", 0)
|
|
20
|
+
self._magic: int = resources.get("magic", 0)
|
|
21
|
+
self._stamina: int = resources.get("stamina", 0)
|
|
22
|
+
self._arrows: int = resources.get("arrows", 0)
|
|
23
|
+
self._bombs: int = resources.get("bombs", 0)
|
|
24
|
+
self._coins: int = resources.get("coins", 0)
|
|
25
|
+
self._keys: int = resources.get("keys", 0)
|
|
26
|
+
|
|
27
|
+
def start(self):
|
|
28
|
+
self._dynamic.attributes.health = min(
|
|
29
|
+
self._dynamic.attributes.health + self._health,
|
|
30
|
+
self._dynamic.attributes.health_max,
|
|
31
|
+
)
|
|
32
|
+
self._dynamic.attributes.magic = min(
|
|
33
|
+
self._dynamic.attributes.magic + self._magic,
|
|
34
|
+
self._dynamic.attributes.magic_max,
|
|
35
|
+
)
|
|
36
|
+
self._dynamic.attributes.stamina = min(
|
|
37
|
+
self._dynamic.attributes.stamina + self._stamina,
|
|
38
|
+
self._dynamic.attributes.stamina_max,
|
|
39
|
+
)
|
|
40
|
+
self._dynamic.attributes.arrows = min(
|
|
41
|
+
self._dynamic.attributes.arrows + self._arrows,
|
|
42
|
+
self._dynamic.attributes.arrows_max,
|
|
43
|
+
)
|
|
44
|
+
self._dynamic.attributes.bombs = min(
|
|
45
|
+
self._dynamic.attributes.bombs + self._bombs,
|
|
46
|
+
self._dynamic.attributes.bombs_max,
|
|
47
|
+
)
|
|
48
|
+
self._dynamic.attributes.coins += self._coins
|
|
49
|
+
self._dynamic.attributes.keys += self._keys
|
|
50
|
+
|
|
51
|
+
self.completed = True
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from ...maps.transition_map import TransitionMap
|
|
4
|
+
from ...objects.dynamic import Dynamic
|
|
5
|
+
from ...types.player import Player
|
|
6
|
+
from ...util.constants import HEIGHT, MOVE_MAP_DURATION, WIDTH
|
|
7
|
+
from ..command import Command
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CommandMoveMap(Command):
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
*,
|
|
14
|
+
new_map_name: str,
|
|
15
|
+
obj: Dynamic,
|
|
16
|
+
target_px: float,
|
|
17
|
+
target_py: float,
|
|
18
|
+
vx: float,
|
|
19
|
+
vy: float,
|
|
20
|
+
players: Optional[List[Player]] = None,
|
|
21
|
+
):
|
|
22
|
+
super().__init__()
|
|
23
|
+
|
|
24
|
+
self.players = [obj.is_player()]
|
|
25
|
+
self.src_map = self.engine.scene.tilemap
|
|
26
|
+
self.dst_map = self.engine.assets.get_map(new_map_name)
|
|
27
|
+
self.obj: Dynamic = obj
|
|
28
|
+
self.vx: float = vx
|
|
29
|
+
self.vy: float = vy
|
|
30
|
+
self.start_px: float = 0
|
|
31
|
+
self.start_py: float = 0
|
|
32
|
+
self.start_ox: float = 0
|
|
33
|
+
self.start_oy: float = 0
|
|
34
|
+
self.target_px: float = target_px
|
|
35
|
+
self.target_py: float = target_py
|
|
36
|
+
self.target_ox: float = 0
|
|
37
|
+
self.target_oy: float = 0
|
|
38
|
+
self.final_px: float = target_px
|
|
39
|
+
self.final_py: float = target_py
|
|
40
|
+
|
|
41
|
+
if self.vx == 0 and self.vy == 0:
|
|
42
|
+
# Error
|
|
43
|
+
self.completed = True
|
|
44
|
+
self.started = True
|
|
45
|
+
|
|
46
|
+
self.duration: float = MOVE_MAP_DURATION
|
|
47
|
+
self.time_so_far: float = 0.0
|
|
48
|
+
|
|
49
|
+
def start(self) -> None:
|
|
50
|
+
# Prevent circular import
|
|
51
|
+
# from ...maps.transition_map import TransitionMap
|
|
52
|
+
|
|
53
|
+
self.start_ox = self._get_offset_x(self.obj.px)
|
|
54
|
+
self.start_oy = self._get_offset_y(self.obj.py)
|
|
55
|
+
self.target_ox = self._get_offset_x(self.target_px)
|
|
56
|
+
self.target_oy = self._get_offset_y(self.target_py)
|
|
57
|
+
self.start_px = self.obj.px
|
|
58
|
+
self.start_py = self.obj.py
|
|
59
|
+
|
|
60
|
+
# print(
|
|
61
|
+
# f"start_pos=({self.start_px:.1f}, {self.start_py:.1f}), "
|
|
62
|
+
# f"tar_pos=({self.target_px:.1f}, {self.target_py:.1f}), "
|
|
63
|
+
# f"start_off=({self.start_ox:.1f}, {self.start_oy:.1f}), "
|
|
64
|
+
# f"tar_off=({self.target_ox:.1f}, {self.target_oy:.1f})"
|
|
65
|
+
# )
|
|
66
|
+
|
|
67
|
+
if self.vx != 0:
|
|
68
|
+
if self.vx < 0:
|
|
69
|
+
self.target_px -= self.target_ox
|
|
70
|
+
else:
|
|
71
|
+
self.target_px += self.start_ox
|
|
72
|
+
self.target_py = self.start_py
|
|
73
|
+
|
|
74
|
+
elif self.vy != 0:
|
|
75
|
+
self.target_px = self.start_px
|
|
76
|
+
if self.vy < 0:
|
|
77
|
+
self.target_py -= self.target_oy + 1
|
|
78
|
+
else:
|
|
79
|
+
self.target_py += self.start_oy + 1
|
|
80
|
+
|
|
81
|
+
self.obj.solid_vs_dyn = False
|
|
82
|
+
self.obj.solid_vs_map = False
|
|
83
|
+
self.obj.vx = self.obj.vy = 0
|
|
84
|
+
self.engine.teleport_triggered = True
|
|
85
|
+
self.engine.scene.tilemap = TransitionMap(
|
|
86
|
+
self.src_map, self.dst_map, self.vx, self.vy
|
|
87
|
+
)
|
|
88
|
+
self.engine.scene.delete_map_dynamics()
|
|
89
|
+
|
|
90
|
+
def update(self, elapsed_time):
|
|
91
|
+
self.time_so_far += elapsed_time
|
|
92
|
+
rela_time = self.time_so_far / self.duration
|
|
93
|
+
if rela_time > 1.0:
|
|
94
|
+
rela_time = 1.0
|
|
95
|
+
|
|
96
|
+
self.obj.px = (
|
|
97
|
+
self.target_px - self.start_px
|
|
98
|
+
) * rela_time + self.start_px
|
|
99
|
+
self.obj.py = (
|
|
100
|
+
self.target_py - self.start_py
|
|
101
|
+
) * rela_time + self.start_py
|
|
102
|
+
|
|
103
|
+
ox = self._get_offset_x(self.obj.px)
|
|
104
|
+
oy = self._get_offset_y(self.obj.py)
|
|
105
|
+
self.obj.extra_ox = ox - self.start_ox
|
|
106
|
+
self.obj.extra_oy = oy - self.start_oy
|
|
107
|
+
|
|
108
|
+
if self.time_so_far >= self.duration:
|
|
109
|
+
self.completed = True
|
|
110
|
+
else:
|
|
111
|
+
self.engine.teleport_triggered = True
|
|
112
|
+
|
|
113
|
+
# print(f"obj_pos=({self.obj.px:.1f}, {self.obj.py:.1f})")
|
|
114
|
+
|
|
115
|
+
def finalize(self):
|
|
116
|
+
if self.vy != 0:
|
|
117
|
+
self.obj.px = self.target_px
|
|
118
|
+
if self.vy > 0:
|
|
119
|
+
self.obj.py = self.target_py - self.start_oy - 1
|
|
120
|
+
else:
|
|
121
|
+
self.obj.py = self.target_py + self.target_oy + 1
|
|
122
|
+
|
|
123
|
+
self.obj.vx = self.obj.vy = 0
|
|
124
|
+
self.obj.solid_vs_dyn = True
|
|
125
|
+
self.obj.solid_vs_map = True
|
|
126
|
+
self.obj.extra_ox = self.obj.extra_oy = 0
|
|
127
|
+
self.engine.scene.change_map(
|
|
128
|
+
self.dst_map.name, self.final_px, self.final_py
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
def _get_offset_x(self, px: float) -> float:
|
|
132
|
+
visible_tiles = WIDTH / self.engine.rtc.tile_width
|
|
133
|
+
offset = px - visible_tiles / 2.0
|
|
134
|
+
|
|
135
|
+
if offset < 0:
|
|
136
|
+
offset = 0
|
|
137
|
+
if offset > self.src_map.width - visible_tiles:
|
|
138
|
+
offset = self.src_map.width - visible_tiles
|
|
139
|
+
|
|
140
|
+
return offset
|
|
141
|
+
|
|
142
|
+
def _get_offset_y(self, py: float) -> float:
|
|
143
|
+
visible_tiles = HEIGHT / self.engine.rtc.tile_width - 1
|
|
144
|
+
offset = py - visible_tiles / 2.0
|
|
145
|
+
|
|
146
|
+
if offset < 0:
|
|
147
|
+
offset = 0
|
|
148
|
+
if offset > self.src_map.height - visible_tiles:
|
|
149
|
+
offset = self.src_map.height - visible_tiles
|
|
150
|
+
|
|
151
|
+
offset -= 1
|
|
152
|
+
return offset
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from ...scripts.command import Command
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from ...objects.dynamic import Dynamic
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CommandMoveTo(Command):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
obj: Dynamic,
|
|
15
|
+
target_px: float,
|
|
16
|
+
target_py: float,
|
|
17
|
+
duration: float = 0.0,
|
|
18
|
+
):
|
|
19
|
+
super().__init__()
|
|
20
|
+
|
|
21
|
+
self.obj: Dynamic = obj
|
|
22
|
+
self.start_px: float = 0.0
|
|
23
|
+
self.start_py: float = 0.0
|
|
24
|
+
self.target_px: float = target_px
|
|
25
|
+
self.target_py: float = target_py
|
|
26
|
+
|
|
27
|
+
self.duration: float = max(duration, 0.001)
|
|
28
|
+
self.time_so_far: float = 0.0
|
|
29
|
+
|
|
30
|
+
def start(self):
|
|
31
|
+
self.start_px = self.obj.px
|
|
32
|
+
self.start_py = self.obj.py
|
|
33
|
+
|
|
34
|
+
def update(self, elapsed_time: float):
|
|
35
|
+
self.time_so_far += elapsed_time
|
|
36
|
+
relatime = min(1.0, self.time_so_far / self.duration)
|
|
37
|
+
|
|
38
|
+
self.obj.px = (self.target_px - self.start_px) * relatime + self.start_px
|
|
39
|
+
self.obj.py = (self.target_py - self.start_py) * relatime + self.start_py
|
|
40
|
+
self.obj.vx = (self.target_px - self.start_px) / self.duration
|
|
41
|
+
self.obj.vy = (self.target_py - self.start_py) / self.duration
|
|
42
|
+
|
|
43
|
+
if self.time_so_far >= self.duration:
|
|
44
|
+
self.completed = True
|
|
45
|
+
|
|
46
|
+
def finalize(self):
|
|
47
|
+
self.obj.px = self.target_px
|
|
48
|
+
self.obj.py = self.target_py
|
|
49
|
+
self.obj.vx = self.obj.vy = 0.0
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from ...scripts.command import Command
|
|
7
|
+
from ...util.constants import ONEWAY_SPEED_BOOST
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ...objects.dynamic import Dynamic
|
|
11
|
+
from ...types.player import Player
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CommandOnewayMove(Command):
|
|
15
|
+
def __init__(self, obj: Dynamic, vx: float, vy: float, player: Player):
|
|
16
|
+
super().__init__([player])
|
|
17
|
+
|
|
18
|
+
self.obj: Dynamic = obj
|
|
19
|
+
self.vx: float = vx
|
|
20
|
+
self.vy: float = vy
|
|
21
|
+
self.start_px: float = 0.0
|
|
22
|
+
self.start_py: float = 0.0
|
|
23
|
+
self.target_px: float = 0.0
|
|
24
|
+
self.target_py: float = 0.0
|
|
25
|
+
self.distance: float = 0.0
|
|
26
|
+
|
|
27
|
+
def start(self):
|
|
28
|
+
self.obj.solid_vs_map = False
|
|
29
|
+
self.obj.solid_vs_dyn = False
|
|
30
|
+
self.obj.vx = self.obj.vy = 0.0
|
|
31
|
+
self.obj.vz = 7.5
|
|
32
|
+
|
|
33
|
+
self.start_px = self.obj.px
|
|
34
|
+
self.start_py = self.obj.py
|
|
35
|
+
self.target_px = self.obj.px + self.vx
|
|
36
|
+
self.target_py = self.obj.py + self.vy
|
|
37
|
+
|
|
38
|
+
dx = self.target_px - self.start_px
|
|
39
|
+
dy = self.target_py - self.start_py
|
|
40
|
+
self.distance = math.sqrt(dx * dx + dy * dy)
|
|
41
|
+
|
|
42
|
+
def update(self, elapsed_time):
|
|
43
|
+
self.obj.px += self.vx * elapsed_time * ONEWAY_SPEED_BOOST
|
|
44
|
+
self.obj.py += self.vy * elapsed_time * ONEWAY_SPEED_BOOST
|
|
45
|
+
|
|
46
|
+
dx = self.obj.px - self.start_px
|
|
47
|
+
dy = self.obj.py - self.start_py
|
|
48
|
+
distance = math.sqrt(dx * dx + dy * dy)
|
|
49
|
+
|
|
50
|
+
if distance >= self.distance:
|
|
51
|
+
self.completed = True
|
|
52
|
+
|
|
53
|
+
def finalize(self):
|
|
54
|
+
self.obj.px = self.target_px
|
|
55
|
+
self.obj.py = self.target_py
|
|
56
|
+
self.obj.vx = self.obj.vy = 0.0
|
|
57
|
+
self.obj.solid_vs_dyn = True
|
|
58
|
+
self.obj.solid_vs_map = True
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from ...types.player import Player
|
|
4
|
+
from ..command import Command
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CommandParallel(Command):
|
|
8
|
+
ALL_COMPLETED: int = 0
|
|
9
|
+
ANY_COMPLETED: int = 1
|
|
10
|
+
FIRST_COMPLETED: int = 2
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
cmds: List[Command],
|
|
15
|
+
completed_when: int = ALL_COMPLETED,
|
|
16
|
+
players: Optional[List[Player]] = None,
|
|
17
|
+
):
|
|
18
|
+
super().__init__()
|
|
19
|
+
self._cmds: List[Command] = cmds
|
|
20
|
+
self._completed_when: int = completed_when
|
|
21
|
+
|
|
22
|
+
def start(self):
|
|
23
|
+
for cmd in self._cmds:
|
|
24
|
+
cmd.start()
|
|
25
|
+
|
|
26
|
+
def update(self, delta_time):
|
|
27
|
+
for cmd in self._cmds:
|
|
28
|
+
cmd.update(delta_time)
|
|
29
|
+
|
|
30
|
+
if self._completed_when == self.ALL_COMPLETED:
|
|
31
|
+
self._check_for_all()
|
|
32
|
+
elif self._completed_when == self.ANY_COMPLETED:
|
|
33
|
+
self._check_for_any()
|
|
34
|
+
elif self._completed_when == self.FIRST_COMPLETED:
|
|
35
|
+
self._check_for_first()
|
|
36
|
+
else:
|
|
37
|
+
raise ValueError(
|
|
38
|
+
f"Unknown value {self._completed_when} for "
|
|
39
|
+
"attribute _completed_when"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def finalize(self):
|
|
43
|
+
for cmd in self._cmds:
|
|
44
|
+
cmd.finalize()
|
|
45
|
+
|
|
46
|
+
def _check_for_all(self):
|
|
47
|
+
completed = True
|
|
48
|
+
for cmd in self._cmds:
|
|
49
|
+
completed = completed and cmd.completed
|
|
50
|
+
|
|
51
|
+
self.completed = completed
|
|
52
|
+
|
|
53
|
+
def _check_for_any(self):
|
|
54
|
+
completed = False
|
|
55
|
+
for cmd in self._cmds:
|
|
56
|
+
completed = completed or cmd.completed
|
|
57
|
+
|
|
58
|
+
self.completed = completed
|
|
59
|
+
|
|
60
|
+
def _check_for_first(self):
|
|
61
|
+
self.completed = self._cmds[0].completed
|
|
62
|
+
|
|
63
|
+
def set_players(self, players: List[Player]):
|
|
64
|
+
self.players = players
|
|
65
|
+
for cmd in self._cmds:
|
|
66
|
+
cmd.set_players(players)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from ..command import Command
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class CommandPlaySound(Command):
|
|
5
|
+
def __init__(self, sound: str, delay: float = 0.0):
|
|
6
|
+
super().__init__()
|
|
7
|
+
|
|
8
|
+
self._sound_to_play: str = sound
|
|
9
|
+
self._delay: float = delay
|
|
10
|
+
|
|
11
|
+
def start(self):
|
|
12
|
+
self.engine.audio.play_sound(self._sound_to_play, self._delay)
|
|
13
|
+
self.completed = True
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
from ...objects.projectile import Projectile
|
|
6
|
+
from ...scripts.command import Command
|
|
7
|
+
from ...types.graphic_state import GraphicState
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ...objects.dynamic import Dynamic
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CommandPresentItem(Command):
|
|
14
|
+
def __init__(self, item_name: str, dynamic: Optional[Dynamic] = None):
|
|
15
|
+
super().__init__()
|
|
16
|
+
|
|
17
|
+
self._dynamic: Optional[Dynamic] = dynamic
|
|
18
|
+
self._item_name: str = item_name
|
|
19
|
+
self._item_sprite: Optional[Projectile] = None
|
|
20
|
+
|
|
21
|
+
def start(self):
|
|
22
|
+
if self._dynamic is None:
|
|
23
|
+
self._dynamic = self.engine.get_player(self.players[0])
|
|
24
|
+
item = self.engine.get_item(self._item_name)
|
|
25
|
+
self._item_sprite = Projectile(
|
|
26
|
+
self._dynamic.px,
|
|
27
|
+
self._dynamic.py - 1,
|
|
28
|
+
f"Present {item.name}",
|
|
29
|
+
sprite_name=item.sprite_name,
|
|
30
|
+
tilemap=self._dynamic.tilemap,
|
|
31
|
+
duration=3600,
|
|
32
|
+
alignment=self._dynamic.alignment,
|
|
33
|
+
)
|
|
34
|
+
self._item_sprite.layer = 2
|
|
35
|
+
# self._item_sprite.sprite.name = item.sprite_name
|
|
36
|
+
# self._item_sprite.sprite.ox = item.sprite_ox
|
|
37
|
+
# self._item_sprite.sprite.oy = item.sprite_oy
|
|
38
|
+
# self._item_sprite.sprite.width = item.sprite_width
|
|
39
|
+
# self._item_sprite.sprite.height = item.sprite_height
|
|
40
|
+
self._item_sprite.solid_vs_dyn = False
|
|
41
|
+
self._item_sprite.solid_vs_map = False
|
|
42
|
+
self._item_sprite.one_hit = False
|
|
43
|
+
self._item_sprite.damage = 0
|
|
44
|
+
|
|
45
|
+
self.engine.get_view().add_projectile(
|
|
46
|
+
self._item_sprite, self._dynamic.tilemap.name
|
|
47
|
+
)
|
|
48
|
+
self._dynamic.lock_graphic_state(GraphicState.CELEBRATING)
|
|
49
|
+
self.completed = True
|
|
50
|
+
|
|
51
|
+
def finalize(self):
|
|
52
|
+
self._item_sprite.kill()
|
|
53
|
+
self._dynamic.unlock_graphic_state()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from ..command import Command
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class CommandProgressQuest(Command):
|
|
5
|
+
def __init__(self, quest_name: str, new_state: int):
|
|
6
|
+
super().__init__()
|
|
7
|
+
self._quest_name: str = quest_name
|
|
8
|
+
self._new_state: int = new_state
|
|
9
|
+
|
|
10
|
+
def start(self):
|
|
11
|
+
self.engine.progress_quest(self._quest_name, self._new_state)
|
|
12
|
+
self.completed = True
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from ...scripts.command import Command
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class CommandSaveGame(Command):
|
|
5
|
+
def start(self):
|
|
6
|
+
# print(self.engine.game_state._state["player"])
|
|
7
|
+
# print(self.engine.items)
|
|
8
|
+
for quest in self.engine.quests:
|
|
9
|
+
quest.save_state()
|
|
10
|
+
self.engine.game_state.save_to_disk()
|
|
11
|
+
self.completed = True
|
|
12
|
+
print(f"Saved the game to {self.engine.game_state.state_name}")
|
|
13
|
+
|
|
14
|
+
# print(self.engine.game_state._state["player"])
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from ...objects.effects.colorize_screen import ColorizeScreen
|
|
4
|
+
from ...util.colors import BLACK, Color
|
|
5
|
+
from ..command import Command
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CommandScreenFade(Command):
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
duration: float = 0.5,
|
|
12
|
+
color: Optional[Color] = None,
|
|
13
|
+
fadein: bool = False,
|
|
14
|
+
map_name: Optional[str] = None,
|
|
15
|
+
):
|
|
16
|
+
super().__init__()
|
|
17
|
+
|
|
18
|
+
self.duration: float = duration
|
|
19
|
+
if color is None:
|
|
20
|
+
color = self.engine.rtc.color_black
|
|
21
|
+
|
|
22
|
+
self.color: Color = color
|
|
23
|
+
self.fadein: bool = fadein
|
|
24
|
+
self.time_so_far: float = 0.0
|
|
25
|
+
self._start: int = 0
|
|
26
|
+
self._end: int = 255
|
|
27
|
+
self._iter: int = 15
|
|
28
|
+
|
|
29
|
+
if fadein:
|
|
30
|
+
self._start = 255
|
|
31
|
+
self._end = 0
|
|
32
|
+
self._iter = -self._iter
|
|
33
|
+
|
|
34
|
+
self._map_name = map_name
|
|
35
|
+
|
|
36
|
+
self._effect: Optional[ColorizeScreen] = None
|
|
37
|
+
# self.duration -= 0.1
|
|
38
|
+
|
|
39
|
+
def start(self):
|
|
40
|
+
|
|
41
|
+
self._effect = ColorizeScreen(
|
|
42
|
+
cameras=[
|
|
43
|
+
self.engine.get_view().get_camera_name(p) for p in self.players
|
|
44
|
+
]
|
|
45
|
+
)
|
|
46
|
+
self._effect.alpha = self._start
|
|
47
|
+
if self._map_name is None:
|
|
48
|
+
map_names = list(
|
|
49
|
+
set(
|
|
50
|
+
[
|
|
51
|
+
self.engine.get_player(p).tilemap.name
|
|
52
|
+
for p in self.players
|
|
53
|
+
]
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
for map_name in map_names:
|
|
57
|
+
self.engine.get_view().add_effect(self._effect, map_name)
|
|
58
|
+
else:
|
|
59
|
+
self.engine.get_view().add_effect(self._effect, self._map_name)
|
|
60
|
+
for p in self.players:
|
|
61
|
+
self.engine.get_player(p).halt()
|
|
62
|
+
|
|
63
|
+
def update(self, elapsed_time: float):
|
|
64
|
+
self.time_so_far += elapsed_time
|
|
65
|
+
|
|
66
|
+
progress = self.time_so_far / self.duration
|
|
67
|
+
|
|
68
|
+
alpha = progress * 256
|
|
69
|
+
if self.fadein:
|
|
70
|
+
alpha = 255 - alpha
|
|
71
|
+
|
|
72
|
+
self._effect.alpha = min(255, max(0, alpha))
|
|
73
|
+
|
|
74
|
+
for p in self.players:
|
|
75
|
+
self.engine.get_player(p).halt()
|
|
76
|
+
|
|
77
|
+
if self.time_so_far >= self.duration:
|
|
78
|
+
self._effect.alpha = self._end
|
|
79
|
+
self.completed = True
|
|
80
|
+
|
|
81
|
+
def finalize(self):
|
|
82
|
+
self.completed = True
|
|
83
|
+
self._effect.kill()
|