Skip to content

Commit c703007

Browse files
committed
npc custom move finish
1 parent 1b5222f commit c703007

File tree

4 files changed

+136
-24
lines changed

4 files changed

+136
-24
lines changed

assets/dbs/storage_db.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@
2727
},
2828
"forest_pillar_collision_layer": 0,
2929
"forest_pillar_animation": "pillar",
30-
"play_introduction": false,
30+
"play_introduction": true,
3131
"avimander_battle": true
3232
}

assets/init.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
"hero_key_name": "isaac",
33
"initial_action": "idle",
44
"initial_direction": "down",
5-
"map_key_name": "madra_side",
6-
"initial_scale_factor": 4,
7-
"x_tile_position": 14,
5+
"map_key_name": "madra",
6+
"initial_scale_factor": 2,
7+
"x_tile_position": 30,
88
"y_tile_position": 13,
9-
"collision_layer": 0,
9+
"collision_layer": 1,
1010
"coins": 10000,
11-
"skip_start_menu": true,
11+
"skip_start_menu": false,
1212
"ignore_system_scaling": true,
1313
"start_battle_tester_on_init": false,
1414
"verbose_game_event_fire": false,

base/Map.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,8 @@ export class Map {
11881188
property_info.after_psynergy_cast_events,
11891189
property_info.force_char_stop_in_event,
11901190
property_info.force_idle_action_in_event,
1191-
property_info.custom_movement,
1191+
property_info.custom_movements,
1192+
property_info.loop_custom_move
11921193
);
11931194
this.npcs.push(npc);
11941195
if (npc.label) {

base/NPC.ts

Lines changed: 128 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
range_360,
99
engine_filters,
1010
directions,
11+
get_centered_pos_in_px,
12+
promised_wait,
1113
} from "./utils";
1214
import {ControllableChar} from "./ControllableChar";
1315
import {interaction_patterns} from "./game_events/GameEventManager";
@@ -90,23 +92,30 @@ export class NPC extends ControllableChar {
9092
private _after_psynergy_cast_events: {
9193
[psynergy_key: string]: GameEvent[];
9294
};
93-
private _custom_movement: {
95+
private _custom_movements: {
9496
position?: {
95-
x: number,
96-
y: number,
97-
is_px?: boolean,
98-
incremental?: boolean
99-
}
100-
dashing?: boolean,
101-
look_direction?: directions,
102-
wait?: number,
97+
x: number;
98+
y: number;
99+
is_px?: boolean;
100+
incremental?: boolean;
101+
dashing?: boolean;
102+
extra_speed?: number;
103+
};
104+
look_direction?: string;
105+
wait?: number;
103106
animation?: {
104-
animation: string,
105-
action: string,
106-
frame_rate: number,
107-
reset_before_start?: boolean
108-
}
107+
animation: string;
108+
action: string;
109+
frame_rate: number;
110+
reset_before_start?: boolean;
111+
stop_char_on_finish?: boolean;
112+
};
109113
}[];
114+
private _next_custom_move_available: boolean;
115+
private _custom_move_index: number;
116+
private _custom_move_moving: boolean;
117+
private _loop_custom_move: boolean;
118+
private _custom_move_destination: {x: number; y: number};
110119

111120
/** If true, this NPC will move freely while a game event is happening. */
112121
public move_freely_in_event: boolean;
@@ -164,7 +173,8 @@ export class NPC extends ControllableChar {
164173
after_psynergy_cast_events,
165174
force_char_stop_in_event,
166175
force_idle_action_in_event,
167-
custom_movement
176+
custom_movement,
177+
loop_custom_move
168178
) {
169179
super(
170180
game,
@@ -189,6 +199,10 @@ export class NPC extends ControllableChar {
189199
movement_type = this.data.storage.get(this.storage_keys.movement_type);
190200
}
191201
this.movement_type = movement_type ?? npc_movement_types.IDLE;
202+
this._custom_movements = custom_movement ?? [];
203+
if (this.movement_type === npc_movement_types.CUSTOM && !this._custom_movements.length) {
204+
this.movement_type = npc_movement_types.IDLE;
205+
}
192206
if (this.storage_keys.move_freely_in_event !== undefined) {
193207
move_freely_in_event = this.data.storage.get(this.storage_keys.move_freely_in_event);
194208
}
@@ -240,7 +254,11 @@ export class NPC extends ControllableChar {
240254
this._step_max_variation = step_max_variation;
241255
this._map_index = map_index;
242256
this._allow_interaction_when_inactive = allow_interaction_when_inactive ?? false;
243-
this._custom_movement = custom_movement ?? [];
257+
this._next_custom_move_available = true;
258+
this._custom_move_index = 0;
259+
this._custom_move_moving = false;
260+
this._custom_move_destination = {x: 0, y: 0};
261+
this._loop_custom_move = loop_custom_move ?? true;
244262
}
245263

246264
/** The list of GameEvents related to this NPC. */
@@ -518,9 +536,101 @@ export class NPC extends ControllableChar {
518536

519537
/**
520538
* Do all the necessary steps to execute a list of custom moves.
539+
* Types of custom moves: move to position, face direction, wait and animation.
521540
*/
522541
private execute_custom_moves() {
523-
542+
if (!this._next_custom_move_available) {
543+
if (this._custom_move_moving) {
544+
if (!this.set_speed_factors()) {
545+
this.stop_char(true);
546+
} else {
547+
this.choose_direction_by_speed();
548+
this.set_direction();
549+
this.choose_action_based_on_char_state();
550+
this.calculate_speed();
551+
this.apply_speed();
552+
this.play_current_action(true);
553+
if (
554+
get_sqr_distance(
555+
this.x,
556+
this._custom_move_destination.x,
557+
this.y,
558+
this._custom_move_destination.y
559+
) < NPC.STOP_MINIMAL_DISTANCE_SQR
560+
) {
561+
this.stop_char(true);
562+
this.increase_extra_speed(
563+
-this._custom_movements[this._custom_move_index].position.extra_speed ?? 0
564+
);
565+
this._next_custom_move_available = true;
566+
++this._custom_move_index;
567+
this._custom_move_moving = false;
568+
}
569+
}
570+
}
571+
return;
572+
}
573+
if (this._custom_move_index === this._custom_movements.length) {
574+
if (!this._loop_custom_move) {
575+
return;
576+
}
577+
this._custom_move_index = 0;
578+
}
579+
this._next_custom_move_available = false;
580+
const move = this._custom_movements[this._custom_move_index];
581+
if (move.position) {
582+
let x = move.position.is_px
583+
? move.position.x
584+
: get_centered_pos_in_px(move.position.x, this.data.map.tile_width);
585+
if (move.position.incremental) {
586+
x += this.x;
587+
}
588+
let y = move.position.is_px
589+
? move.position.y
590+
: get_centered_pos_in_px(move.position.y, this.data.map.tile_height);
591+
if (move.position.incremental) {
592+
y += this.y;
593+
}
594+
this._custom_move_destination.x = x;
595+
this._custom_move_destination.y = y;
596+
const speed_vector = new Phaser.Point(x - this.x, y - this.y).normalize();
597+
this.force_diagonal_speed.x = speed_vector.x;
598+
this.force_diagonal_speed.y = speed_vector.y;
599+
this._angle_direction = Math.atan2(speed_vector.y, speed_vector.x);
600+
this._custom_move_moving = true;
601+
this.dashing = move.position.dashing ?? false;
602+
this.increase_extra_speed(move.position.extra_speed ?? 0);
603+
} else if (move.look_direction) {
604+
const direction = directions[move.look_direction];
605+
this.face_direction(direction).then(() => {
606+
this._next_custom_move_available = true;
607+
++this._custom_move_index;
608+
});
609+
} else if (move.animation) {
610+
if (move.animation.animation in directions) {
611+
this.set_direction(directions[move.animation.animation]);
612+
}
613+
const anim = this.play(
614+
move.animation.action,
615+
move.animation.animation,
616+
true,
617+
move.animation.frame_rate,
618+
false,
619+
move.animation.reset_before_start
620+
);
621+
anim.onComplete.addOnce(() => {
622+
if (move.animation.stop_char_on_finish) {
623+
this.stop_char(true);
624+
}
625+
this._next_custom_move_available = true;
626+
++this._custom_move_index;
627+
});
628+
} else if (move.wait) {
629+
promised_wait(this.game, move.wait, () => {
630+
this._next_custom_move_available = true;
631+
++this._custom_move_index;
632+
});
633+
}
524634
}
525635

526636
/**
@@ -560,6 +670,7 @@ export class NPC extends ControllableChar {
560670

561671
/**
562672
* Sets the x-y speed values that this NPC is going to be using to move.
673+
* It's important to have NPC._angle_direction set for correct checking.
563674
* @returns Returns true if the speed values were set. Going towards a collision direction is not acceptable, then returns false.
564675
*/
565676
private set_speed_factors() {

0 commit comments

Comments
 (0)