mima-engine 0.1.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.
Potentially problematic release.
This version of mima-engine might be problematic. Click here for more details.
- mima/__init__.py +1 -0
- mima/backend/__init__.py +1 -0
- mima/backend/pygame_assets.py +345 -0
- mima/backend/pygame_audio.py +75 -0
- mima/backend/pygame_backend.py +399 -0
- mima/backend/pygame_events.py +430 -0
- mima/collision.py +237 -0
- mima/engine.py +197 -0
- mima/maps/__init__.py +0 -0
- mima/maps/template.py +41 -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 +45 -0
- mima/maps/tilemap.py +159 -0
- mima/maps/tileset.py +32 -0
- mima/maps/tileset_info.py +9 -0
- mima/maps/transition_map.py +148 -0
- mima/objects/__init__.py +0 -0
- mima/objects/animated_sprite.py +198 -0
- mima/objects/attribute_effect.py +26 -0
- mima/objects/attributes.py +123 -0
- mima/objects/creature.py +332 -0
- mima/objects/dynamic.py +182 -0
- mima/objects/effects/__init__.py +0 -0
- mima/objects/effects/colorize_screen.py +36 -0
- mima/objects/effects/light.py +107 -0
- mima/objects/effects/walking_on_grass.py +38 -0
- mima/objects/effects/walking_on_water.py +41 -0
- mima/objects/loader.py +103 -0
- mima/objects/projectile.py +86 -0
- mima/objects/sprite.py +110 -0
- mima/objects/world/__init__.py +0 -0
- mima/objects/world/color_gate.py +68 -0
- mima/objects/world/color_switch.py +105 -0
- mima/objects/world/container.py +171 -0
- mima/objects/world/floor_switch.py +111 -0
- mima/objects/world/gate.py +174 -0
- mima/objects/world/light_source.py +124 -0
- mima/objects/world/logic_gate.py +163 -0
- mima/objects/world/movable.py +338 -0
- mima/objects/world/oneway.py +168 -0
- mima/objects/world/pickup.py +88 -0
- mima/objects/world/switch.py +165 -0
- mima/objects/world/teleport.py +288 -0
- mima/scene_engine.py +79 -0
- mima/scripts/__init__.py +2 -0
- mima/scripts/command.py +24 -0
- mima/scripts/commands/__init__.py +0 -0
- mima/scripts/commands/add_quest.py +19 -0
- mima/scripts/commands/change_map.py +15 -0
- mima/scripts/commands/close_dialog.py +8 -0
- mima/scripts/commands/give_item.py +24 -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 +57 -0
- mima/scripts/commands/parallel.py +53 -0
- mima/scripts/commands/play_sound.py +13 -0
- mima/scripts/commands/present_item.py +51 -0
- mima/scripts/commands/progress_quest.py +12 -0
- mima/scripts/commands/quit_game.py +8 -0
- mima/scripts/commands/save_game.py +13 -0
- mima/scripts/commands/screen_fade.py +65 -0
- mima/scripts/commands/serial.py +46 -0
- mima/scripts/commands/set_facing_direction.py +21 -0
- mima/scripts/commands/set_spawn_map.py +14 -0
- mima/scripts/commands/show_choices.py +43 -0
- mima/scripts/commands/show_dialog.py +11 -0
- mima/scripts/commands/take_coins.py +23 -0
- mima/scripts/script_processor.py +40 -0
- mima/states/__init__.py +0 -0
- mima/states/game_state.py +162 -0
- mima/states/quest.py +72 -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 +22 -0
- mima/types/keys.py +16 -0
- mima/types/mode.py +15 -0
- mima/types/nature.py +12 -0
- mima/types/object.py +22 -0
- mima/types/start.py +7 -0
- mima/types/terrain.py +9 -0
- mima/types/weapon_slot.py +6 -0
- mima/usables/__init__.py +0 -0
- mima/usables/item.py +31 -0
- mima/usables/weapon.py +48 -0
- mima/util/__init__.py +1 -0
- mima/util/colors.py +45 -0
- mima/util/constants.py +47 -0
- mima/util/functions.py +13 -0
- mima/util/input_defaults.py +49 -0
- mima/util/logging.py +51 -0
- mima/util/property.py +8 -0
- mima/util/runtime_config.py +133 -0
- mima/view/__init__.py +0 -0
- mima/view/camera.py +51 -0
- mima/view/scene.py +350 -0
- mima_engine-0.1.0.dist-info/METADATA +14 -0
- mima_engine-0.1.0.dist-info/RECORD +114 -0
- mima_engine-0.1.0.dist-info/WHEEL +5 -0
- mima_engine-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
self.engine.give_item(self._item_name)
|
|
24
|
+
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 ...maps.transition_map import TransitionMap
|
|
2
|
+
from ...objects.dynamic import Dynamic
|
|
3
|
+
from ...util.constants import (
|
|
4
|
+
HEIGHT,
|
|
5
|
+
MOVE_MAP_DURATION,
|
|
6
|
+
TILE_HEIGHT,
|
|
7
|
+
TILE_WIDTH,
|
|
8
|
+
WIDTH,
|
|
9
|
+
)
|
|
10
|
+
from ..command import Command
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CommandMoveMap(Command):
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
new_map_name: str,
|
|
17
|
+
obj: Dynamic,
|
|
18
|
+
target_px: float,
|
|
19
|
+
target_py: float,
|
|
20
|
+
vx: float,
|
|
21
|
+
vy: float,
|
|
22
|
+
):
|
|
23
|
+
super().__init__()
|
|
24
|
+
|
|
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 / 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 / TILE_HEIGHT - 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,57 @@
|
|
|
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
|
+
|
|
12
|
+
|
|
13
|
+
class CommandOnewayMove(Command):
|
|
14
|
+
def __init__(self, obj: Dynamic, vx: float, vy: float):
|
|
15
|
+
super().__init__()
|
|
16
|
+
|
|
17
|
+
self.obj: Dynamic = obj
|
|
18
|
+
self.vx: float = vx
|
|
19
|
+
self.vy: float = vy
|
|
20
|
+
self.start_px: float = 0.0
|
|
21
|
+
self.start_py: float = 0.0
|
|
22
|
+
self.target_px: float = 0.0
|
|
23
|
+
self.target_py: float = 0.0
|
|
24
|
+
self.distance: float = 0.0
|
|
25
|
+
|
|
26
|
+
def start(self):
|
|
27
|
+
self.obj.solid_vs_map = False
|
|
28
|
+
self.obj.solid_vs_dyn = False
|
|
29
|
+
self.obj.vx = self.obj.vy = 0.0
|
|
30
|
+
self.obj.vz = 10.0
|
|
31
|
+
|
|
32
|
+
self.start_px = self.obj.px
|
|
33
|
+
self.start_py = self.obj.py
|
|
34
|
+
self.target_px = self.obj.px + self.vx
|
|
35
|
+
self.target_py = self.obj.py + self.vy
|
|
36
|
+
|
|
37
|
+
dx = self.target_px - self.start_px
|
|
38
|
+
dy = self.target_py - self.start_py
|
|
39
|
+
self.distance = math.sqrt(dx * dx + dy * dy)
|
|
40
|
+
|
|
41
|
+
def update(self, elapsed_time):
|
|
42
|
+
self.obj.px += self.vx * elapsed_time * ONEWAY_SPEED_BOOST
|
|
43
|
+
self.obj.py += self.vy * elapsed_time * ONEWAY_SPEED_BOOST
|
|
44
|
+
|
|
45
|
+
dx = self.obj.px - self.start_px
|
|
46
|
+
dy = self.obj.py - self.start_py
|
|
47
|
+
distance = math.sqrt(dx * dx + dy * dy)
|
|
48
|
+
|
|
49
|
+
if distance >= self.distance:
|
|
50
|
+
self.completed = True
|
|
51
|
+
|
|
52
|
+
def finalize(self):
|
|
53
|
+
self.obj.px = self.target_px
|
|
54
|
+
self.obj.py = self.target_py
|
|
55
|
+
self.obj.vx = self.obj.vy = 0.0
|
|
56
|
+
self.obj.solid_vs_dyn = True
|
|
57
|
+
self.obj.solid_vs_map = True
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
from ..command import Command
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CommandParallel(Command):
|
|
6
|
+
ALL_COMPLETED: int = 0
|
|
7
|
+
ANY_COMPLETED: int = 1
|
|
8
|
+
FIRST_COMPLETED: int = 2
|
|
9
|
+
|
|
10
|
+
def __init__(self, cmds: List[Command], completed_when: int = ALL_COMPLETED):
|
|
11
|
+
super().__init__()
|
|
12
|
+
self._cmds: List[Command] = cmds
|
|
13
|
+
self._completed_when: int = completed_when
|
|
14
|
+
|
|
15
|
+
def start(self):
|
|
16
|
+
for cmd in self._cmds:
|
|
17
|
+
cmd.start()
|
|
18
|
+
|
|
19
|
+
def update(self, delta_time):
|
|
20
|
+
for cmd in self._cmds:
|
|
21
|
+
cmd.update(delta_time)
|
|
22
|
+
|
|
23
|
+
if self._completed_when == self.ALL_COMPLETED:
|
|
24
|
+
self._check_for_all()
|
|
25
|
+
elif self._completed_when == self.ANY_COMPLETED:
|
|
26
|
+
self._check_for_any()
|
|
27
|
+
elif self._completed_when == self.FIRST_COMPLETED:
|
|
28
|
+
self._check_for_first()
|
|
29
|
+
else:
|
|
30
|
+
raise ValueError(
|
|
31
|
+
f"Unknown value {self._completed_when} for " "attribute _completed_when"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def finalize(self):
|
|
35
|
+
for cmd in self._cmds:
|
|
36
|
+
cmd.finalize()
|
|
37
|
+
|
|
38
|
+
def _check_for_all(self):
|
|
39
|
+
completed = True
|
|
40
|
+
for cmd in self._cmds:
|
|
41
|
+
completed = completed and cmd.completed
|
|
42
|
+
|
|
43
|
+
self.completed = completed
|
|
44
|
+
|
|
45
|
+
def _check_for_any(self):
|
|
46
|
+
completed = False
|
|
47
|
+
for cmd in self._cmds:
|
|
48
|
+
completed = completed or cmd.completed
|
|
49
|
+
|
|
50
|
+
self.completed = completed
|
|
51
|
+
|
|
52
|
+
def _check_for_first(self):
|
|
53
|
+
self.completed = self._cmds[0].completed
|
|
@@ -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,51 @@
|
|
|
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
|
+
if dynamic is None:
|
|
18
|
+
dynamic = self.engine.player
|
|
19
|
+
|
|
20
|
+
self._dynamic: Dynamic = dynamic
|
|
21
|
+
self._item_name: str = item_name
|
|
22
|
+
self._item_sprite: Optional[Projectile] = None
|
|
23
|
+
|
|
24
|
+
def start(self):
|
|
25
|
+
item = self.engine.get_item(self._item_name)
|
|
26
|
+
self._item_sprite = Projectile(
|
|
27
|
+
self._dynamic.px,
|
|
28
|
+
self._dynamic.py - 1,
|
|
29
|
+
0,
|
|
30
|
+
0,
|
|
31
|
+
3600,
|
|
32
|
+
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.scene.add_projectile(self._item_sprite)
|
|
46
|
+
self._dynamic.lock_graphic_state(GraphicState.CELEBRATING)
|
|
47
|
+
self.completed = True
|
|
48
|
+
|
|
49
|
+
def finalize(self):
|
|
50
|
+
self._item_sprite.kill()
|
|
51
|
+
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,13 @@
|
|
|
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
|
+
|
|
13
|
+
# print(self.engine.game_state._state["player"])
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from ...objects.effects.colorize_screen import ColorizeScreen
|
|
4
|
+
from ..command import Command
|
|
5
|
+
from ...util.colors import BLACK,Color
|
|
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
|
+
):
|
|
15
|
+
super().__init__()
|
|
16
|
+
|
|
17
|
+
self.duration: float = duration
|
|
18
|
+
if color is None:
|
|
19
|
+
color = self.engine.rtc.colors["gb_dark"]
|
|
20
|
+
|
|
21
|
+
self.color: Color = color
|
|
22
|
+
self.fadein: bool = fadein
|
|
23
|
+
self.time_so_far: float = 0.0
|
|
24
|
+
self._start: int = 0
|
|
25
|
+
self._end: int = 255
|
|
26
|
+
self._iter: int = 15
|
|
27
|
+
|
|
28
|
+
if fadein:
|
|
29
|
+
self._start = 255
|
|
30
|
+
self._end = 0
|
|
31
|
+
self._iter = -self._iter
|
|
32
|
+
|
|
33
|
+
# self._alpha = chain([i for i in range(self._start, self._end, self._iter)])
|
|
34
|
+
|
|
35
|
+
self._effect = ColorizeScreen()
|
|
36
|
+
# self.duration -= 0.1
|
|
37
|
+
self._effect.alpha = self._start
|
|
38
|
+
|
|
39
|
+
def start(self):
|
|
40
|
+
self.engine.scene.add_effect(self._effect)
|
|
41
|
+
self.engine.player.vx = 0
|
|
42
|
+
self.engine.player.vy = 0
|
|
43
|
+
|
|
44
|
+
def update(self, elapsed_time: float):
|
|
45
|
+
self.time_so_far += elapsed_time
|
|
46
|
+
|
|
47
|
+
progress = self.time_so_far / self.duration
|
|
48
|
+
|
|
49
|
+
alpha = progress * 256
|
|
50
|
+
if self.fadein:
|
|
51
|
+
alpha = 255 - alpha
|
|
52
|
+
|
|
53
|
+
self._effect.alpha = min(255, max(0, alpha))
|
|
54
|
+
# print(self, self._effect.alpha)
|
|
55
|
+
|
|
56
|
+
self.engine.player.vx = 0
|
|
57
|
+
self.engine.player.vy = 0
|
|
58
|
+
|
|
59
|
+
if self.time_so_far >= self.duration:
|
|
60
|
+
self._effect.alpha = self._end
|
|
61
|
+
self.completed = True
|
|
62
|
+
|
|
63
|
+
def finalize(self):
|
|
64
|
+
self.completed = True
|
|
65
|
+
self._effect.kill()
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import List, Union
|
|
2
|
+
import logging
|
|
3
|
+
from ..command import Command
|
|
4
|
+
|
|
5
|
+
LOG = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
class CommandSerial(Command):
|
|
8
|
+
START_AND_UPDATE: int = 0
|
|
9
|
+
START_WITHOUT_UPDATE: int = 1
|
|
10
|
+
|
|
11
|
+
def __init__(self, cmds: List[Command], update_when: Union[int, List[int]] = START_AND_UPDATE):
|
|
12
|
+
super().__init__()
|
|
13
|
+
self._cmds: List[Command] = cmds
|
|
14
|
+
self._current: int = 0
|
|
15
|
+
self._update_when: List[int]
|
|
16
|
+
|
|
17
|
+
if not isinstance(update_when, list):
|
|
18
|
+
self._update_when = [update_when for _ in range(len(self._cmds)-1)]
|
|
19
|
+
else:
|
|
20
|
+
self._update_when = update_when
|
|
21
|
+
|
|
22
|
+
if len(self._update_when) < len(self._cmds):
|
|
23
|
+
LOG.warning(
|
|
24
|
+
"Unsufficient information for 'update_when' of serial command:"
|
|
25
|
+
f"cmds={self._cmds}, update_when={self._update_when}. Using "
|
|
26
|
+
"default value!"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def start(self):
|
|
30
|
+
self._cmds[self._current].start()
|
|
31
|
+
|
|
32
|
+
def update(self, delta_time):
|
|
33
|
+
if not self._cmds[self._current].completed:
|
|
34
|
+
self._cmds[self._current].update(delta_time)
|
|
35
|
+
else:
|
|
36
|
+
self._current += 1
|
|
37
|
+
if self._current == len(self._cmds):
|
|
38
|
+
self.completed = True
|
|
39
|
+
else:
|
|
40
|
+
self._cmds[self._current].start()
|
|
41
|
+
if self._update_when[self._current-1] == self.START_AND_UPDATE:
|
|
42
|
+
self._cmds[self._current].update(delta_time)
|
|
43
|
+
|
|
44
|
+
def finalize(self):
|
|
45
|
+
for cmd in self._cmds:
|
|
46
|
+
cmd.finalize()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
from ...types.direction import Direction
|
|
6
|
+
from ..command import Command
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from ...objects.dynamic import Dynamic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CommandSetFacingDirection(Command):
|
|
13
|
+
def __init__(self, dynamic: Dynamic, facing_direction: Direction):
|
|
14
|
+
super().__init__()
|
|
15
|
+
|
|
16
|
+
self._dynamic: Dynamic = dynamic
|
|
17
|
+
self._new_direction: Direction = facing_direction
|
|
18
|
+
|
|
19
|
+
def start(self):
|
|
20
|
+
self._dynamic.facing_direction = self._new_direction
|
|
21
|
+
self.completed = True
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from ...scripts.command import Command
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class CommandSetSavePosition(Command):
|
|
5
|
+
def __init__(self, map_name: str, px: float, py: float):
|
|
6
|
+
self._map_name = map_name
|
|
7
|
+
self._px = px
|
|
8
|
+
self._py = py
|
|
9
|
+
|
|
10
|
+
def start(self):
|
|
11
|
+
self.engine.player_state.save_map = self._map_name
|
|
12
|
+
self.engine.player_state.save_px = self._px
|
|
13
|
+
self.engine.player_state.save_py = self._py
|
|
14
|
+
self.completed = True
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
from ...scripts.command import Command
|
|
3
|
+
from ...types.keys import Key as K
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CommandShowChoices(Command):
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
options: List[str],
|
|
10
|
+
replies: List[Command],
|
|
11
|
+
default_option: int = 0,
|
|
12
|
+
):
|
|
13
|
+
super().__init__()
|
|
14
|
+
|
|
15
|
+
self.uninterruptible = True
|
|
16
|
+
self._options: List[str] = options
|
|
17
|
+
self._replies: List[Command] = replies
|
|
18
|
+
self._default_option: int = default_option
|
|
19
|
+
|
|
20
|
+
self._cursor_pos: int = 0
|
|
21
|
+
|
|
22
|
+
def update(self, elapsed_time: float):
|
|
23
|
+
if self.engine.keys.new_key_release(K.UP):
|
|
24
|
+
self._cursor_pos = (self._cursor_pos - 1) % len(self._options)
|
|
25
|
+
elif self.engine.keys.new_key_release(K.DOWN):
|
|
26
|
+
self._cursor_pos = (self._cursor_pos + 1) % len(self._options)
|
|
27
|
+
elif self.engine.keys.new_key_press(K.A):
|
|
28
|
+
self.completed = True
|
|
29
|
+
elif self.engine.keys.new_key_release(K.B):
|
|
30
|
+
self._cursor_pos = self._default_option
|
|
31
|
+
self.completed = True
|
|
32
|
+
|
|
33
|
+
lines = []
|
|
34
|
+
for idx, opt in enumerate(self._options):
|
|
35
|
+
if idx == self._cursor_pos:
|
|
36
|
+
lines.append(f"> {opt}")
|
|
37
|
+
else:
|
|
38
|
+
lines.append(f" {opt}")
|
|
39
|
+
|
|
40
|
+
self.engine.scene.show_dialog(lines)
|
|
41
|
+
|
|
42
|
+
def finalize(self):
|
|
43
|
+
self.engine.script.add_command(self._replies[self._cursor_pos])
|