Skip to content

Commit 6e378a9

Browse files
committed
Fixes exult#373
When the Avatar "runs" (via mouse movement) against a closed door, he will open it, go through, turn to the door, close it, turn away. This was bugged as in the Avatar opened and closed it twice, moving through the locked door at times.
1 parent 13cb82a commit 6e378a9

File tree

2 files changed

+40
-21
lines changed

2 files changed

+40
-21
lines changed

actions.cc

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,19 @@ int Path_walking_actor_action::handle_event(Actor* actor) {
211211
set_subseq(nullptr);
212212
// He was stopped, so restore speed.
213213
actor->set_frame_time(speed);
214+
if (!door_sequence_complete) {
215+
// Activate the door after walking past it
216+
Game_object_shared door_ptr = door_obj.lock();
217+
if (door_ptr) {
218+
const int savequal = door_ptr->get_quality();
219+
door_ptr->set_quality(0);
220+
door_ptr->activate();
221+
door_ptr->set_quality(savequal);
222+
}
223+
door_sequence_complete
224+
= true; // Set the flag to prevent re-activation
225+
handling_door = false; // Reset the handling flag
226+
}
214227
return speed; // Come back in a moment.
215228
}
216229
Tile_coord tile;
@@ -353,6 +366,14 @@ int Path_walking_actor_action::handle_event(Actor* actor) {
353366
*/
354367

355368
bool Path_walking_actor_action::open_door(Actor* actor, Game_object* door) {
369+
// Check if already handling a door interaction
370+
if (handling_door || door_sequence_complete) {
371+
return false;
372+
}
373+
// Set the handling flag to indicate a door is being processed
374+
handling_door = true;
375+
door_obj = weak_from_obj(door); // Store the door
376+
356377
const Tile_coord cur = actor->get_tile();
357378
// Get door's footprint in tiles.
358379
const TileRect foot = door->get_footprint();
@@ -389,21 +410,16 @@ bool Path_walking_actor_action::open_door(Actor* actor, Game_object* door) {
389410
#ifdef DEBUG
390411
cout << "Path_walking_actor_action::open_door()" << endl;
391412
#endif
392-
const std::array frames{
393-
static_cast<signed char>(
394-
actor->get_dir_framenum(dir, Actor::standing)),
395-
static_cast<signed char>(
396-
actor->get_dir_framenum(dir, Actor::ready_frame)),
397-
};
398-
signed char standframe = frames[0];
413+
door_sequence_complete = false; // Reset the flag
414+
// Set the actor to walk past the door
399415
set_subseq(create_action_sequence(
400416
actor, past,
401-
new Sequence_actor_action(
402-
new Frames_actor_action(frames.data(), frames.size()),
403-
new Activate_actor_action(door),
404-
new Frames_actor_action(&standframe, 1))));
417+
new Frames_actor_action(
418+
actor->get_dir_framenum(dir, Actor::standing),
419+
100))); // Short delay
405420
return true;
406421
}
422+
handling_door = false;
407423
return false;
408424
}
409425

actions.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,19 @@ class Path_walking_actor_action : public Actor_action {
118118
PathFinder* path; // Allocated pathfinder.
119119
bool deleted = false; // True if the action has been killed.
120120
private:
121-
int original_dir; // From src. to dest. (0-7).
122-
int speed = 0; // Time between frames.
123-
bool from_offscreen = false; // Walking from offscreen.
124-
Actor_action* subseq = nullptr; // For opening doors.
125-
unsigned char blocked = 0; // Blocked-tile retries.
126-
unsigned char max_blocked; // Try this many times.
127-
unsigned char blocked_frame = 0; // Frame for blocked tile.
128-
unsigned char persistence;
129-
Tile_coord blocked_tile; // Tile to retry.
130-
121+
int original_dir; // From src. to dest. (0-7).
122+
int speed = 0; // Time between frames.
123+
bool from_offscreen = false; // Walking from offscreen.
124+
Actor_action* subseq = nullptr; // For opening doors.
125+
Game_object_weak door_obj; // Store the door object
126+
bool handling_door = false;
127+
bool door_sequence_complete = false;
128+
unsigned char blocked = 0; // Blocked-tile retries.
129+
unsigned char max_blocked; // Try this many times.
130+
unsigned char blocked_frame = 0; // Frame for blocked tile.
131+
unsigned char persistence;
132+
Tile_coord blocked_tile; // Tile to retry.
133+
131134
void set_subseq(Actor_action* sub) {
132135
delete subseq;
133136
subseq = sub;

0 commit comments

Comments
 (0)