mima-engine 0.2.2__py3-none-any.whl → 0.2.4__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.

Files changed (57) hide show
  1. mima/__init__.py +4 -1
  2. mima/backend/pygame_assets.py +67 -9
  3. mima/backend/pygame_backend.py +5 -2
  4. mima/backend/pygame_events.py +210 -194
  5. mima/backend/touch_control_scheme_a.py +126 -0
  6. mima/backend/touch_control_scheme_b.py +132 -0
  7. mima/core/__init__.py +0 -0
  8. mima/{collision.py → core/collision.py} +45 -28
  9. mima/core/database.py +58 -0
  10. mima/{engine.py → core/engine.py} +51 -33
  11. mima/{mode_engine.py → core/mode_engine.py} +7 -6
  12. mima/{scene_engine.py → core/scene_engine.py} +3 -7
  13. mima/maps/template.py +31 -1
  14. mima/maps/tiled/tiled_object.py +1 -1
  15. mima/maps/tiled/tiled_tileset.py +10 -5
  16. mima/maps/tilemap.py +4 -10
  17. mima/maps/tileset.py +5 -4
  18. mima/objects/animated_sprite.py +79 -68
  19. mima/objects/creature.py +20 -7
  20. mima/objects/dynamic.py +3 -1
  21. mima/objects/effects/colorize_screen.py +9 -1
  22. mima/objects/effects/debug_box.py +11 -2
  23. mima/objects/effects/light.py +6 -1
  24. mima/objects/effects/show_sprite.py +17 -6
  25. mima/objects/effects/walking_on_grass.py +27 -13
  26. mima/objects/effects/walking_on_water.py +36 -31
  27. mima/objects/loader.py +6 -9
  28. mima/objects/projectile.py +15 -5
  29. mima/objects/sprite.py +8 -1
  30. mima/objects/world/color_gate.py +10 -15
  31. mima/objects/world/color_switch.py +18 -28
  32. mima/objects/world/container.py +32 -37
  33. mima/objects/world/floor_switch.py +22 -28
  34. mima/objects/world/gate.py +21 -24
  35. mima/objects/world/light_source.py +27 -32
  36. mima/objects/world/logic_gate.py +30 -37
  37. mima/objects/world/movable.py +106 -89
  38. mima/objects/world/oneway.py +63 -41
  39. mima/objects/world/pickup.py +81 -17
  40. mima/objects/world/switch.py +46 -35
  41. mima/objects/world/teleport.py +21 -22
  42. mima/scripts/commands/oneway_move.py +4 -3
  43. mima/scripts/commands/present_item.py +10 -10
  44. mima/types/graphic_state.py +1 -0
  45. mima/usables/item.py +28 -9
  46. mima/usables/weapon.py +28 -8
  47. mima/util/constants.py +3 -3
  48. mima/util/input_defaults.py +12 -0
  49. mima/util/runtime_config.py +8 -15
  50. mima/util/trading_item.py +4 -1
  51. mima/view/mima_mode.py +8 -2
  52. mima/view/mima_scene.py +6 -0
  53. mima/view/mima_window.py +91 -0
  54. {mima_engine-0.2.2.dist-info → mima_engine-0.2.4.dist-info}/METADATA +4 -4
  55. {mima_engine-0.2.2.dist-info → mima_engine-0.2.4.dist-info}/RECORD +57 -53
  56. {mima_engine-0.2.2.dist-info → mima_engine-0.2.4.dist-info}/WHEEL +1 -1
  57. {mima_engine-0.2.2.dist-info → mima_engine-0.2.4.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  from typing import List, Optional, Union
2
2
 
3
+ from ...maps.tilemap import Tilemap
3
4
  from ...types.alignment import Alignment
4
5
  from ...types.direction import Direction
5
6
  from ...types.graphic_state import GraphicState
@@ -14,42 +15,46 @@ class Switch(Dynamic):
14
15
  self,
15
16
  px: float,
16
17
  py: float,
17
- tileset_name: str,
18
- image_name: str,
19
- sprite_name: str,
20
- facing_direction: Direction,
21
- graphic_state: GraphicState,
22
- initial_signal=True,
23
- tilemap=None,
24
- dyn_id=0,
25
18
  name="Switch",
19
+ *,
20
+ sprite_name: str = "",
21
+ tilemap: Optional[Tilemap] = None,
22
+ dyn_id=0,
23
+ graphic_state: GraphicState = GraphicState.OPEN,
24
+ initial_signal=True,
26
25
  ):
27
- assert graphic_state in [GraphicState.OPEN, GraphicState.CLOSED], (
28
- f"graphic_state of Switch {name}{dyn_id} must be either 'open'"
29
- f" or 'closed', but it {graphic_state}"
30
- )
31
- super().__init__(px, py, name, tilemap, dyn_id)
32
-
33
- self.sprite = AnimatedSprite(
34
- tileset_name,
35
- image_name,
36
- sprite_name,
37
- graphic_state,
38
- facing_direction,
26
+ if graphic_state not in [GraphicState.OPEN, GraphicState.CLOSED]:
27
+ msg = (
28
+ f"graphic_state of Switch {name}{dyn_id} must be either "
29
+ f" 'open' or 'closed', but it is {graphic_state.name}"
30
+ )
31
+ raise ValueError(msg)
32
+
33
+ super().__init__(
34
+ px,
35
+ py,
36
+ name,
37
+ tilemap=tilemap,
38
+ sprite_name=sprite_name,
39
+ dyn_id=dyn_id,
39
40
  )
40
41
 
41
42
  self.type = ObjectType.SWITCH
42
43
  self.alignment = Alignment.NEUTRAL
43
44
  self.graphic_state = graphic_state
44
- self.facing_direction = facing_direction
45
45
  self.signal = self.graphic_state == GraphicState.CLOSED
46
46
  self.listener_ids: List[int] = []
47
47
  self.listeners: List[Dynamic] = []
48
48
  self.send_initial_signal = initial_signal
49
+ self.cooldown = 0.0
50
+ self.cooldown_reset = 0.8
49
51
 
50
52
  # self._gs_map = {False: GraphicState.OPEN, True: GraphicState.CLOSED}
51
53
 
52
54
  def update(self, elapsed_time: float, target: Optional[Dynamic] = None):
55
+ if self.cooldown > 0.0:
56
+ self.cooldown -= elapsed_time
57
+
53
58
  if self.send_initial_signal:
54
59
  self.send_signal(self.signal)
55
60
  self.send_initial_signal = False
@@ -71,25 +76,36 @@ class Switch(Dynamic):
71
76
  def on_interaction(self, target: Dynamic, nature: Nature):
72
77
  # if target.is_player().value > 0:
73
78
  # print(f"{target.is_player()} talked to me({self.name})")
79
+ if self.cooldown > 0.0:
80
+ return False
81
+
74
82
  if (
75
83
  nature == Nature.TALK
76
84
  and target.type == ObjectType.PLAYER
77
85
  and self.visible
78
86
  ):
79
87
  self.state_changed = True
80
- self.engine.audio.play_sound("switch")
88
+ self.engine.audio.play_sound("switch", 0.2)
89
+ self.cooldown = self.cooldown_reset
90
+ print("Player talked")
81
91
 
82
92
  elif nature == Nature.WALK and target.type == ObjectType.PROJECTILE:
83
93
  if self.signal:
84
94
  # Projectiles from the right will activate the switch
85
95
  if target.px > self.px and target.vx < 0:
86
96
  self.state_changed = True
97
+ if "body" not in target.name:
98
+ self.engine.audio.play_sound("switch", 0.2)
99
+ self.cooldown = self.cooldown_reset
87
100
  else:
88
101
  # Projectiles from the left will (de)activate the switch
89
- if target.px <= self.px and target.vx > 0:
102
+ if (
103
+ target.px <= self.px and target.vx > 0
104
+ ): # Sword does not activate because vx=0
90
105
  self.state_changed = True
91
- if "body" not in target.name:
92
- self.engine.audio.play_sound("switch")
106
+ if "body" not in target.name:
107
+ self.engine.audio.play_sound("switch", 0.2)
108
+ self.cooldown = self.cooldown_reset
93
109
 
94
110
  elif nature == Nature.SIGNAL:
95
111
  self.visible = False
@@ -138,23 +154,18 @@ class Switch(Dynamic):
138
154
  switch = Switch(
139
155
  px=px,
140
156
  py=py,
141
- tileset_name=obj.get_string("tileset_name"),
142
- image_name=obj.get_string("tileset_name"),
157
+ name=obj.name,
143
158
  sprite_name=obj.get_string("sprite_name"),
159
+ tilemap=tilemap,
160
+ dyn_id=obj.object_id,
144
161
  graphic_state=GraphicState[
145
162
  obj.get_string("graphic_state", "closed").upper()
146
163
  ],
147
- facing_direction=Direction[
148
- obj.get_string("facing_direction", "south").upper()
149
- ],
150
164
  initial_signal=obj.get_bool("initial_signal", True),
151
- tilemap=tilemap,
152
- dyn_id=obj.object_id,
153
- name=obj.name,
154
165
  )
155
166
 
156
- switch.sprite.width = int(width * Switch.engine.rtc.tile_width)
157
- switch.sprite.height = int(height * Switch.engine.rtc.tile_height)
167
+ # switch.sprite.width = int(width * Switch.engine.rtc.tile_width)
168
+ # switch.sprite.height = int(height * Switch.engine.rtc.tile_height)
158
169
 
159
170
  ctr = 1
160
171
  while True:
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
  from typing import List, Optional
5
5
 
6
+ from ...maps.tilemap import Tilemap
6
7
  from ...scripts.commands.change_map import CommandChangeMap
7
8
  from ...scripts.commands.move_map import CommandMoveMap
8
9
  from ...scripts.commands.parallel import CommandParallel
@@ -25,9 +26,11 @@ class Teleport(Dynamic):
25
26
  self,
26
27
  px: float,
27
28
  py: float,
28
- tileset_name: str,
29
- image_name: str,
30
- sprite_name: str,
29
+ name="Teleport",
30
+ *,
31
+ sprite_name: str = "str",
32
+ tilemap: Optional[Tilemap] = None,
33
+ dyn_id: int = -1,
31
34
  facing_direction: Direction,
32
35
  graphic_state: GraphicState,
33
36
  dst_map_name: str,
@@ -38,20 +41,24 @@ class Teleport(Dynamic):
38
41
  relative: bool = False,
39
42
  sliding: bool = False,
40
43
  vertical: bool = False,
41
- tilemap=None,
42
- dyn_id: int = -1,
43
- name="Teleport",
44
44
  ):
45
- super().__init__(px, py, name, tilemap, dyn_id)
46
-
47
- self.sprite = AnimatedSprite(
48
- tileset_name,
49
- image_name,
50
- sprite_name,
51
- graphic_state,
52
- facing_direction,
45
+ super().__init__(
46
+ px,
47
+ py,
48
+ name,
49
+ sprite_name=sprite_name,
50
+ tilemap=tilemap,
51
+ dyn_id=dyn_id,
53
52
  )
54
53
 
54
+ # self.sprite = AnimatedSprite(
55
+ # tileset_name,
56
+ # image_name,
57
+ # sprite_name,
58
+ # graphic_state,
59
+ # facing_direction,
60
+ # )
61
+
55
62
  self.type = ObjectType.TELEPORT
56
63
  self.graphic_state = graphic_state
57
64
  self.facing_direction = facing_direction
@@ -176,8 +183,6 @@ class Teleport(Dynamic):
176
183
  obj, px, py, width, height, tilemap
177
184
  ) -> List[Teleport]:
178
185
  sprite_name = obj.get_string("sprite_name")
179
- tileset_name = obj.get_string("tileset_name")
180
- image_name = obj.get_string("tileset_name")
181
186
  graphic_state = GraphicState[
182
187
  obj.get_string("graphic_state", "closed").upper()
183
188
  ]
@@ -214,8 +219,6 @@ class Teleport(Dynamic):
214
219
  Teleport(
215
220
  px=from_px,
216
221
  py=from_py,
217
- tileset_name=tileset_name,
218
- image_name=image_name,
219
222
  sprite_name=sprite_name,
220
223
  graphic_state=graphic_state,
221
224
  facing_direction=facing_direction,
@@ -253,8 +256,6 @@ class Teleport(Dynamic):
253
256
  Teleport(
254
257
  px=from_px,
255
258
  py=from_py,
256
- tileset_name=tileset_name,
257
- image_name=image_name,
258
259
  sprite_name=sprite_name,
259
260
  graphic_state=graphic_state,
260
261
  facing_direction=facing_direction,
@@ -285,8 +286,6 @@ class Teleport(Dynamic):
285
286
  Teleport(
286
287
  px=px,
287
288
  py=py,
288
- tileset_name=tileset_name,
289
- image_name=image_name,
290
289
  sprite_name=sprite_name,
291
290
  graphic_state=graphic_state,
292
291
  facing_direction=facing_direction,
@@ -8,11 +8,12 @@ from ...util.constants import ONEWAY_SPEED_BOOST
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from ...objects.dynamic import Dynamic
11
+ from ...types.player import Player
11
12
 
12
13
 
13
14
  class CommandOnewayMove(Command):
14
- def __init__(self, obj: Dynamic, vx: float, vy: float):
15
- super().__init__()
15
+ def __init__(self, obj: Dynamic, vx: float, vy: float, player: Player):
16
+ super().__init__([player])
16
17
 
17
18
  self.obj: Dynamic = obj
18
19
  self.vx: float = vx
@@ -27,7 +28,7 @@ class CommandOnewayMove(Command):
27
28
  self.obj.solid_vs_map = False
28
29
  self.obj.solid_vs_dyn = False
29
30
  self.obj.vx = self.obj.vy = 0.0
30
- self.obj.vz = 10.0
31
+ self.obj.vz = 7.5
31
32
 
32
33
  self.start_px = self.obj.px
33
34
  self.start_py = self.obj.py
@@ -25,18 +25,18 @@ class CommandPresentItem(Command):
25
25
  self._item_sprite = Projectile(
26
26
  self._dynamic.px,
27
27
  self._dynamic.py - 1,
28
- 0,
29
- 0,
30
- 3600,
31
- self._dynamic.alignment,
32
- self._dynamic.tilemap,
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
33
  )
34
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
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
40
  self._item_sprite.solid_vs_dyn = False
41
41
  self._item_sprite.solid_vs_map = False
42
42
  self._item_sprite.one_hit = False
@@ -15,6 +15,7 @@ class GraphicState(Enum):
15
15
  LOCKED = 10
16
16
  OFF = 11
17
17
  ON = 12
18
+ ICON = 13
18
19
 
19
20
 
20
21
  class Until(Enum):
mima/usables/item.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Any, Dict
4
4
 
5
5
  from ..util.constants import DEFAULT_SPRITE_HEIGHT, DEFAULT_SPRITE_WIDTH
6
6
 
@@ -13,20 +13,39 @@ if TYPE_CHECKING:
13
13
  class Item:
14
14
  engine: MimaEngine
15
15
 
16
- def __init__(self, name: str, sprite_name: str, description: str):
17
- self.name: str = name
18
- self.description: str = description
19
- self.sprite_name: str = sprite_name
20
- self.sprite_ox: int = 0
21
- self.sprite_oy: int = 0
22
- self.sprite_width: int = DEFAULT_SPRITE_WIDTH
23
- self.sprite_height: int = DEFAULT_SPRITE_HEIGHT
16
+ def __init__(self):
17
+ self.name: str = ""
18
+ self.description: str = ""
19
+ self.sprite_name: str = ""
20
+ # self.sprite_ox: int = 0
21
+ # self.sprite_oy: int = 0
22
+ # self.sprite_width: int = DEFAULT_SPRITE_WIDTH
23
+ # self.sprite_height: int = DEFAULT_SPRITE_HEIGHT
24
24
  self.key_item: bool = False
25
25
  self.equipable: bool = False
26
26
  self.price: int = 0
27
+ self.stackable: bool = False
28
+ self.stackable_by_merchant: bool = False
29
+
30
+ def init(self, data: Dict[str, Any]):
31
+
32
+ for key, val in data.items():
33
+ setattr(self, key, val)
34
+ # self.usable_id = data["usable_id"]
35
+ # self.name = data["name"]
36
+ # self.description = data["description"]
37
+ # self.price = data.get("attr_price", 0)
38
+ # self.sprite_name = data.get("sprite_name")
27
39
 
28
40
  def on_interaction(self, obj: Dynamic):
29
41
  return False
30
42
 
31
43
  def on_use(self, obj: Creature):
32
44
  return False
45
+
46
+ def __str__(self):
47
+ txt = f"{type(self).__name__}({self.name})"
48
+ return txt
49
+
50
+ def __repr__(self):
51
+ return str(self)
mima/usables/weapon.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Tuple
3
+ from typing import TYPE_CHECKING, Any, Dict, Tuple
4
4
 
5
5
  from ..types.damage import Damage
6
6
  from ..types.direction import Direction
@@ -11,20 +11,37 @@ if TYPE_CHECKING:
11
11
 
12
12
 
13
13
  class Weapon(Item):
14
- def __init__(self, name: str, sprite: str, description: str):
15
- super().__init__(name, sprite, description)
14
+ def __init__(self):
15
+ super().__init__()
16
16
 
17
17
  self.equipable = True
18
18
 
19
19
  self.damage: int = 0
20
20
  self.dtype: Damage = Damage.BODY
21
- self.health_cost: int = 0
22
- self.magic_cost: int = 0
23
- self.stamina_cost: int = 0
21
+ self.health_cost: float = 0.0
22
+ self.magic_cost: float = 0.0
23
+ self.stamina_cost: float = 0.0
24
24
  self.arrow_cost: int = 0
25
25
  self.bomb_cost: int = 0
26
- self.swing_timer: int = 0.2
27
- # self.projectiles: List[Projectile] = []
26
+ self.swing_timer: float = 0.2
27
+
28
+ def init(self, data: Dict[str, Any]):
29
+ for key, val in data.items():
30
+ setattr(self, key, val)
31
+ # self.usable_id = data["usable_id"]
32
+ # self.name = data["display_name"]
33
+ # self.description = data["description"]
34
+ # self.sprite_name = data["sprite_name"]
35
+ # self.price = data["attr_price"]
36
+ # self.swing_timer = data["attr_swing_timer"]
37
+ # self.damage = data["attr_damage"]
38
+ # self.dtype = data["attr_dtype"]
39
+ # self.health_cost = data["attr_health_cost"]
40
+ # self.magic_cost = data["attr_magic_cost"]
41
+ # self.stamina_cost = data["attr_stamina_cost"]
42
+ # self.bomb_cost = data["attr_bomb_cost"]
43
+ # self.arrow_cost = data["attr_arrow_cost"]
44
+ # print()
28
45
 
29
46
  def _determine_attack_origin(self, obj: Creature) -> Tuple[float, float]:
30
47
  vx = 0.0
@@ -46,3 +63,6 @@ class Weapon(Item):
46
63
 
47
64
  def on_unequip(self, obj: Creature):
48
65
  pass
66
+
67
+ def on_interaction(self, target: Creature):
68
+ return True # Add to inventory
mima/util/constants.py CHANGED
@@ -10,8 +10,8 @@ UI_HIGHT: int = 1 # TODO: remove
10
10
  # Map transition
11
11
  MOVE_MAP_DURATION: float = 1.0
12
12
  MAP_TRANSITION_DURATION_FACTOR: float = 0.75
13
- ONEWAY_ACTIVATION_DELAY: float = 0.175
14
- ONEWAY_SPEED_BOOST: float = 2.0
13
+ ONEWAY_ACTIVATION_DELAY: float = 0.075
14
+ ONEWAY_SPEED_BOOST: float = 2.5
15
15
 
16
16
  # Gamepad
17
17
  AXIS_DEADZONE: float = 0.25
@@ -38,7 +38,7 @@ DEFAULT_GRAPHIC_TIMER_DAMAGED: float = 0.075
38
38
  DEFAULT_GRAPHIC_TIMER_DEAD: float = 0.25
39
39
  DEFAULT_GRAPHIC_TIMER: float = 0.5
40
40
  ATTRIBUTE_TIMER: float = 0.25
41
- DEFAULT_KNOCK_SPEED: float = 5.0
41
+ DEFAULT_KNOCK_SPEED: float = 6.0
42
42
 
43
43
  # Gameplay
44
44
  ABYSS_DAMAGE: int = 1
@@ -156,3 +156,15 @@ DEFAULT_TOUCHSCREEN_MAP = {
156
156
  K.P1_B: [[0.5, 0.5], [0.75, 1.0]],
157
157
  K.P1_A: [[0.75, 0.5], [1.0, 1.0]],
158
158
  }
159
+
160
+ ALT_TOUCHSCREEN_MAP = {
161
+ K.P1_UP: {"pos": [0.1, 0.2], "size": [0.4, 0.7]},
162
+ K.P1_A: {"pos": [0.83, 0.84], "size": [0.12, 0.12]},
163
+ K.P1_B: {"pos": [0.70, 0.84], "size": [0.12, 0.12]},
164
+ K.P1_X: {"pos": [0.76, 0.69], "size": [0.12, 0.12]},
165
+ K.P1_Y: {"pos": [0.63, 0.69], "size": [0.12, 0.12]},
166
+ K.P1_START: {"pos": [0.39, 0.02], "size": [0.1, 0.1]},
167
+ K.P1_SELECT: {"pos": [0.51, 0.02], "size": [0.1, 0.1]},
168
+ K.P1_L: {"pos": [0.01, 0.3], "size": [0.05, 0.4]},
169
+ K.P1_R: {"pos": [0.94, 0.3], "size": [0.05, 0.4]},
170
+ }
@@ -106,9 +106,7 @@ class RuntimeConfig:
106
106
  self._converted: Dict[str, Any] = {}
107
107
 
108
108
  if not config_path:
109
- config_path = os.path.abspath(
110
- os.path.join(os.getcwd(), "mima.ini")
111
- )
109
+ config_path = os.path.abspath(os.path.join(os.getcwd(), "mima.ini"))
112
110
 
113
111
  self._config_path = config_path
114
112
  config = configparser.ConfigParser()
@@ -145,6 +143,9 @@ class RuntimeConfig:
145
143
  self.small_font_width = SMALL_FONT_WIDTH
146
144
  self.small_font_height = SMALL_FONT_HEIGHT
147
145
 
146
+ ## Locale
147
+ self.locale = "en"
148
+
148
149
  def _read_config(self, config: configparser.ConfigParser):
149
150
  mappings = [
150
151
  "keyboard_map_p1",
@@ -251,14 +252,10 @@ class RuntimeConfig:
251
252
  if but.value < 12:
252
253
  kbmap[but] = []
253
254
  elif but.value < 24:
254
- kbmap[but] = self._loaded["keyboard_map_p1"][
255
- but.name.split("_")[1]
256
- ]
255
+ kbmap[but] = self._loaded["keyboard_map_p1"][but.name.split("_")[1]]
257
256
 
258
257
  elif but.value < 36:
259
- kbmap[but] = self._loaded["keyboard_map_p2"][
260
- but.name.split("_")[1]
261
- ]
258
+ kbmap[but] = self._loaded["keyboard_map_p2"][but.name.split("_")[1]]
262
259
 
263
260
  else:
264
261
  kbmap[but] = []
@@ -271,14 +268,10 @@ class RuntimeConfig:
271
268
  if but.value < 12:
272
269
  jsmap[but] = []
273
270
  elif but.value < 24:
274
- jsmap[but] = self._loaded["joystick_map_p1"][
275
- but.name.split("_")[1]
276
- ]
271
+ jsmap[but] = self._loaded["joystick_map_p1"][but.name.split("_")[1]]
277
272
 
278
273
  elif but.value < 36:
279
- jsmap[but] = self._loaded["joystick_map_p2"][
280
- but.name.split("_")[1]
281
- ]
274
+ jsmap[but] = self._loaded["joystick_map_p2"][but.name.split("_")[1]]
282
275
 
283
276
  else:
284
277
  jsmap[but] = []
mima/util/trading_item.py CHANGED
@@ -10,11 +10,14 @@ if TYPE_CHECKING:
10
10
  @dataclass
11
11
  class TradingItem:
12
12
  item: Item
13
- price: int
14
13
  count: int = 1
15
14
  factor: float = 1.0
16
15
  available: int = 1
17
16
  tid: int = 0
17
+ price: int = 0
18
+ trading_price: int = 0
19
+ stackable: bool = False
20
+ stackable_merchant: bool = False
18
21
 
19
22
  def __eq__(self, other):
20
23
  return self.tid == other.tid
mima/view/mima_mode.py CHANGED
@@ -4,7 +4,7 @@ import logging
4
4
  import math
5
5
  from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
6
6
 
7
- from ..collision import (
7
+ from ..core.collision import (
8
8
  _chunk_index,
9
9
  add_to_collision_chunk,
10
10
  check_object_to_map_collision,
@@ -141,6 +141,7 @@ class MimaMode(MimaView):
141
141
  ) -> None:
142
142
  p_obj = self.engine.get_player(player)
143
143
  p_obj.stop_shining()
144
+ p_obj.on_exit_map()
144
145
 
145
146
  if map_name not in self.players_on_map:
146
147
  # Map not loaded
@@ -165,6 +166,7 @@ class MimaMode(MimaView):
165
166
  p_obj.tilemap = self.maps[player]
166
167
  p_obj.px = px
167
168
  p_obj.py = py
169
+ p_obj.on_enter_map()
168
170
  self.engine.memory.last_spawn_px[player] = px
169
171
  self.engine.memory.last_spawn_py[player] = py
170
172
 
@@ -366,7 +368,10 @@ class MimaMode(MimaView):
366
368
  return target # , skip
367
369
 
368
370
  def _update_velocity_z(self, obj: Dynamic, elapsed_time: float) -> None:
369
- obj.vz -= obj.attributes.gravity_vz * elapsed_time
371
+ if obj.pz > 0.0:
372
+ obj.vz -= obj.attributes.gravity_vz * elapsed_time
373
+ # else:
374
+ # obj.vz = 0.0
370
375
 
371
376
  def _update_position_z(self, obj: Dynamic, elapsed_time: float) -> None:
372
377
  if obj.gravity:
@@ -385,6 +390,7 @@ class MimaMode(MimaView):
385
390
  max_dist = screen_width + screen_height
386
391
 
387
392
  for map_name, players in self.players_on_map.items():
393
+ # print(f"Collisions for {map_name}: {self.colliders[map_name]}")
388
394
  for obj in self.colliders[map_name]:
389
395
  if obj.occupied:
390
396
  continue
mima/view/mima_scene.py CHANGED
@@ -39,8 +39,10 @@ class MimaScene(MimaView):
39
39
  self._camera_name: str = (
40
40
  camera_name if camera_name is not None else f"C_{player.name}"
41
41
  )
42
+ self._controls_camera_name: str = f"{self._camera_name}_CONTROLS"
42
43
 
43
44
  self.camera: Camera
45
+ self.controls_camera: Camera
44
46
  self._dialog_px: float
45
47
  self._dialog_py: float
46
48
  self._dialog_width: float = DIALOG_WIDTH
@@ -85,6 +87,9 @@ class MimaScene(MimaView):
85
87
  self._dialog_py = height - 4
86
88
 
87
89
  self.camera = Camera(self._camera_name, width, height)
90
+ # self.controls_camera = Camera(
91
+ # self._controls_camera_name, width, height
92
+ # )
88
93
  if position == Position.CENTER:
89
94
  # print(f"Camera setup finished: {width}, {height}")
90
95
  return
@@ -181,6 +186,7 @@ class MimaScene(MimaView):
181
186
  self.skip_draw_ui = False
182
187
  return
183
188
  self._current_window.draw_ui()
189
+ self._current_window.draw_controls()
184
190
 
185
191
  def draw_camera_border(self):
186
192
  self.camera.draw_borders()