Mentions légales du service

Skip to content
Snippets Groups Projects
Commit ee26f661 authored by DETROYAT Alexis's avatar DETROYAT Alexis
Browse files

Merge branch 'main' into 'dev/crepes'

Merge main with dev/crepes (movement fixes)

See merge request !11
parents 90242226 4b4c2ece
No related branches found
No related tags found
4 merge requests!21Merging the multi-character sprite handling system into avoid_monster,!13Merge crepes level with main,!12Merge crepes level with main,!11Merge main with dev/crepes (movement fixes)
......@@ -30,7 +30,8 @@ class Level(AbstractLevel):
player = self.map.player
entry = self.map.coordinates["wop_init"]
wop.place_on(entry)
wop.talks("intro")
wop.send_update()
wop.talk("intro")
self.my_set_reset()
......
......@@ -72,6 +72,10 @@ bool check_password(char* user_input)
return false;
#else
int len = strlen(password);
int ulen = strlen(user_input);
user_input[ulen] = '\0'; // remove trailing '\n'
ulen--;
if (len != ulen) return false;
return ! strncmp(password, user_input, len);
#endif
}
......
......@@ -21,7 +21,7 @@ class Level(AbstractLevel):
wop = self.map.named_objects["wop"]
wop.visible = True
wop.place_at(2,3)
# wop.send_update()
wop.send_update()
wop.talks("intro")
......
......@@ -15,6 +15,7 @@ class Level(AbstractLevel):
trigger = self.map.coordinates["wop_refactor"]
lvl.debug(f"Trigger for wop: {trigger}")
wop.place_on(trigger, side=cst.Direction.UP)
wop.send_update()
player = self.map.player
wop.talks('intro')
......
......@@ -33,6 +33,7 @@ class Level(AbstractLevel):
wop.visible = True
wop_init = self.map.coordinates["wop_traps"]
wop.place_on(wop_init)
wop.send_update()
def player_custom_update(slf, *args):
if player.is_below(wop):
......
......@@ -14,6 +14,7 @@ class Level(AbstractLevel):
wop = self.map.named_objects["wop"]
wop.visible = True
wop.place_on(self.map.coordinates["wop_stairs_start"])
wop.send_update()
player = self.map.player
talks = self.map.coordinates["wop_stairs_talks"]
......@@ -22,13 +23,10 @@ class Level(AbstractLevel):
wop.last_talk = 0
def player_custom_update(player, m):
lvl.debug(f"{trigger} and {player}")
if wop.last_talk == 0 and player.is_on(talks):
wop.last_talk = 1
has_talked = True
pl = wop.payload()
pl["talks"] = True
pl["message"] = wop.message('intro')
wop.send_update(pl)
wop.talk('intro')
elif wop.last_talk <= 1 and player.is_on(trigger):
......@@ -39,21 +37,31 @@ class Level(AbstractLevel):
pl = wop.payload()
wop.send_update(pl)
pl = wop.payload()
pl["action"] = "talks after moving"
pl["message"] = wop.message('toolong')
wop.send_update(pl)
wop.talk('toolong')
pl = {
"topic": "gui_change",
"action": "show_button",
"command": "continue",
}
wop.send_update(pl) # will not contain 'wop' information
pl = wop.payload()
pl['change/speed'] = 2
wop.send_update(pl)
# pl = wop.payload()
# pl['action'] = "talks after moving"
# wop.send_update(wop.payload())
# place WOD near the exit
ex = self.map.exit
wop.place_at(ex.coord_x-1, ex.coord_y-1)
wop.send_update()
wop.direction = cst.Direction.DOWN
wop.send_update()
elif wop.last_talk == 2 and player.is_below(wop):
wop.last_talk += 1
wop.talk('finally')
player.post_update = player_custom_update
......
......@@ -73,6 +73,13 @@
*
*
* PS : Tu peux zoomer et dezoomer avec la molette de la souris.
*
* Rejoins-moi vite !
* EndOfMessage
*
* WOP: message finally
* Ah ! Te voilà enfin.
* Reste bien sur le chemin...
* EndOfMessage
**
**/
......
......@@ -50,7 +50,7 @@ class Level(AbstractLevel):
if player.is_below(panel):
pl = panel.payload()
pl["talks"] = True
pl["action"] = 'talk'
pl["message"] = panel.message('intro')
panel.send_update(pl)
......
......@@ -11,7 +11,7 @@ class Tiles:
SPRITE_SIZE = 32
TILE_SIZE = 32
MIN_SCALE = 0.25
MAX_SCALE = 4
MAX_SCALE = 3
MIN_AUTO_SCALE = 1.5
MAX_AUTO_SCALE = 2
......
......@@ -8,7 +8,7 @@ import arcade
from lib.utils import log
import graphic.constants as cst
from graphic.amap import Amap
from .path import to_absolute
from .path import find_path, to_absolute, to_relative
class SpCoordinates:
......@@ -152,7 +152,13 @@ class SpObject(arcade.Sprite, SpCoordinates):
def idle_frame(self):
pass
def append_action(self, action):
self.action_queue.append(action)
def update(self):
# if self.name == 'WOP':
# log.debug(f"WOP update {self.in_action} queue {len(self.action_queue)}")
if self.in_action:
assert self.action_hook != None
self.action_hook()
......@@ -164,6 +170,7 @@ class SpObject(arcade.Sprite, SpCoordinates):
payload = self.action_queue.popleft()
act = payload['action']
log.debug(f"Next action {act} for {self}")
if act == 'hit':
self.start_hit()
......@@ -177,7 +184,10 @@ class SpObject(arcade.Sprite, SpCoordinates):
elif act == 'talk':
msg = payload['message']
self.talks(msg)
elif act == 'change/speed':
self.frame_rate_factor = payload['value']
elif act == 'move':
self.handle_move_action(payload)
else:
log.error(f"Action {act} not found in action list")
......@@ -291,6 +301,7 @@ class SpObject(arcade.Sprite, SpCoordinates):
# raise Exception(f"Illegal diagonal movement: {(factor_x, factor_y)}")
if factor_x == 0 and factor_y == 0: # No movement, let's skip it
self.idle_frame()
return
if auto_dir:
if factor_x:
......@@ -338,6 +349,68 @@ class SpObject(arcade.Sprite, SpCoordinates):
self.auto_dir = True
self.start_moving()
def handle_move_action(self, payload):
log.debug(f"Handling move action for {self} with {payload}")
# now dealing with movement
appearing = False
if "visible" in payload:
if not self.visible and payload['visible']:
appearing = True # selfect has just appeared
self.visible = payload["visible"]
if "direction" in payload:
self.direction = cst.Direction(payload["direction"])
# lastly, update coordinates if present in payload
if "coord_x" in payload:
assert "coord_y" in payload
else:
return
target_x, target_y = payload["coord_x"], payload["coord_y"]
if target_x is None or target_y is None:
return # No movement to do
if (
self.coord_x is None
or self.coord_x < 0
or self.coord_y is None
or self.coord_y < 0
or appearing # do not animate if was invisible before
or "teleport" in payload
or self.far_move == "teleport"
):
self.set_relative_position(target_x, target_y, direct=self.direction)
return
dx, dy = target_x - self.coord_x, target_y - self.coord_y
# player always go for the straight-line
if abs(dx) + abs(dy) <= 1 or self.far_move == "crowflies":
# log.debug(f"Moving {self.name} only 1 square with move_forward")
self.move_forward((dx, dy))
return
# Otherwise, move selfect / wop from current position to new position
path = find_path(
self,
self.amap.game_view.layers["walls"],
target_x,
target_y,
self.amap
)
log.debug(f"Moving {self.name} along path {path}")
if path:
self.follow_path(path, auto_dir=not self.name=='Player')
else:
log.error(f"Cannot move {self.name} to destination!")
def disappear(self):
self.visible = False
## TODO: really update this list, still used?
......@@ -346,9 +419,6 @@ class SpObject(arcade.Sprite, SpCoordinates):
def reappear(self):
self.visible = True
def append_action(self, action):
self.action_queue.append(action)
# TODO: change name to only "on_resize"?
def rescale(self, scale):
"""Rescale the sprite."""
......
......@@ -813,7 +813,7 @@ class GameView(EmptyView):
position=position
)
def box_message(self, message: str, error=False, buttons=["ok"], position=None):
def box_message(self, message: str, error=False, buttons=["Ok"], position=None):
"""
This method carry out the message box that can be use for the wop for
example.
......@@ -863,11 +863,12 @@ class GameView(EmptyView):
log.debug(f"message box closed with event {event}")
self.clear_box()
run_hook = False
run_hook = True
if self.message_list:
run_hook = False
if event == "more":
self.box_show_message_list()
elif event.startswith == "skip":
elif event.startswith("skip"):
self.message_list = []
run_hook = True
elif event == "close":
......@@ -1092,24 +1093,12 @@ class GameView(EmptyView):
if self.level and not self.level.is_running:
self.on_pause = True
# Move the player
# Update all regular sprites that are always present
self.player.update()
# Not based on coordinates anymore as player update may arrive before
# wop update
# if self.message_box: # WARNING: the previous message box has been removed
# if (
# self.message_box_pos_x != self.player.coord_x
# or self.message_box_pos_y != self.player.coord_y
# ):
# self.remove_box("skip")
# TODO: Florent: probably need to also update wop
if self.wop.visible:
self.wop.update()
self.wop.update()
self.exit.update()
self.breaklight.update()
for obj in self.objects.values():
obj.update()
......@@ -1383,9 +1372,8 @@ class GameView(EmptyView):
if "action" in payload:
act = payload["action"]
if act == "fall" or act == "drown":
assert is_player
obj.append_action({'action' == 'hit'})
obj.append_action({'action' == 'disappear'})
obj.append_action({'action': 'hit'})
obj.append_action({'action': 'disappear'})
elif act == "hit":
obj.append_action(payload)
......@@ -1397,67 +1385,25 @@ class GameView(EmptyView):
self.rescale(self.scale)
else:
raise ValueError("Unknown action for payload: " + act)
return
if 'change/speed' in payload:
obj.frame_rate_factor = payload['change/speed']
appearing = False
if "visible" in payload:
if not obj.visible:
appearing = True # object has just appeared
obj.visible = payload["visible"]
if 'change/speed' in payload:
payload['action'] = 'change/speed'
payload['value'] = payload['change/speed']
obj.append_action(payload)
return
if payload.get("talks", False):
log.error("Must not use the 'talks' field anymore")
# lastly, update coordinates if present in payload
if "coord_x" in payload:
assert "coord_y" in payload
else:
return
target_x, target_y = payload["coord_x"], payload["coord_y"]
log.debug(f"... move action for {obj}")
payload['action'] = 'move'
obj.append_action(payload)
return
if target_x is None or target_y is None:
return # No movement to do
obj.direction = cst.Direction(payload["direction"])
if (
obj.coord_x is None
or obj.coord_x < 0
or obj.coord_y is None
or obj.coord_y < 0
or appearing # do not animate if was invisible before
or "teleport" in payload
or obj.far_move == "teleport"
):
obj.set_relative_position(target_x, target_y, direct=obj.direction)
return
dx, dy = target_x - obj.coord_x, target_y - obj.coord_y
# player always go for the straight-line
if abs(dx) + abs(dy) <= 1 or obj.far_move == "crowflies":
# log.debug(f"Moving {obj.name} only 1 square with move_forward")
obj.move_forward((dx, dy))
return
# Otherwise, move object / wop from current position to new position
path = find_path(
obj,
self.layers["walls"],
target_x,
target_y,
self.amap,
)
log.debug(f"Moving {obj.name} along path {path}")
if path:
obj.follow_path(path, auto_dir=not is_player)
else:
log.error(f"Cannot move {obj.name} to destination!")
def sprites_action(self, payload):
if payload['action'] == 'hide':
......
......@@ -113,7 +113,7 @@ class BaseArcadeWindow(arcade.Window):
def kill_level_tracker(self):
level = self.views["game"].level
if level.tracker is not None:
if level is not None and level.tracker is not None:
level.tracker.terminate()
def finish_input_thread(self):
......
......@@ -172,12 +172,16 @@ class Object:
lvl.debug(f"Message '{msg_label}' not found in language {Config.LANGUAGE}") # TODO: how to convert enum to string to display?
return self.messages[Lang.default][msg_label]
def talks(self, msg_label: str):
def talk(self, msg_label: str):
payload = self.payload()
payload['talks'] = True
payload['action'] = 'talk'
payload['message'] = self.message(msg_label)
self.send_update(payload)
def talks(self, msg_label: str):
# for backward compatibility
self.talk(msg_label)
def update(self, memory, run_hook: bool = True) -> None:
"""
Update object property.
......
......@@ -109,7 +109,7 @@ class LevelChecker(TrackerHelp):
if self.metadata['player_mode'] == 'global_variables':
exit_conditions.append(VerifyCondition("player_x == exit_x"))
exit_conditions.append(VerifyCondition("player_y == exit_y"))
elif self.metadata['player_mode'] == 'simple_map':
elif self.metadata['player_mode'] == 'simple_map' or self.metadata['player_mode'] == 'map_stack':
exit_conditions.append(VerifyCondition("map->player_x == exit_x"))
exit_conditions.append(VerifyCondition("map->player_y == exit_y"))
else:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment