diff --git a/base/ControllableChar.ts b/base/ControllableChar.ts index 7d0ea3865f..dee6e2b7ce 100644 --- a/base/ControllableChar.ts +++ b/base/ControllableChar.ts @@ -1968,7 +1968,9 @@ export abstract class ControllableChar { undefined, undefined, true, - false + false, + undefined, + undefined ); event.set_fadein_callback(() => { fall_tween.stop(false); diff --git a/base/ParticlesWrapper.ts b/base/ParticlesWrapper.ts index 4c3bd45df8..259014d630 100644 --- a/base/ParticlesWrapper.ts +++ b/base/ParticlesWrapper.ts @@ -70,6 +70,12 @@ export type ParticlesZone = { }[]; }; +enum game_groups { + LOWER = "lower", + MIDDLE = "middle", + OVER = "over", +} + export type Emitter = { emitter_data_key?: string; render_type?: "pixel" | "sprite"; @@ -137,6 +143,7 @@ export type Emitter = { export type ParticlesInfo = { data: {[emitter_data_key: string]: ParticleObject}; + group_type?: game_groups; zones: {[zone_key: string]: ParticlesZone}; emitters: Emitter[]; emission_finish: number; @@ -154,9 +161,37 @@ export class ParticlesWrapper { this.render_callbacks = {}; } + static expanded_xy_pos_getter( + data: GoldenSun, + x: number | EventValue, + y: number | EventValue, + shift_x: number | EventValue, + shift_y: number | EventValue + ) { + let this_x = x as number; + let this_y = y as number; + let this_shift_x = shift_x as number; + let this_shift_y = shift_y as number; + if (x !== undefined && typeof x !== "number") { + this_x = data.game_event_manager.get_value(x); + } + if (y !== undefined && typeof y !== "number") { + this_y = data.game_event_manager.get_value(y); + } + if (shift_x !== undefined && typeof shift_x !== "number") { + this_shift_x = data.game_event_manager.get_value(shift_x); + } + if (shift_y !== undefined && typeof shift_y !== "number") { + this_shift_y = data.game_event_manager.get_value(shift_y); + } + this_x += this_shift_x ?? 0; + this_y += this_shift_y ?? 0; + return {x: this_x, y: this_y}; + } + start_particles( particles_info: ParticlesInfo, - particles_group: Phaser.Group, + particles_group?: Phaser.Group, inner_groups?: { [battle_positions.BEHIND]: Phaser.Group; [battle_positions.BETWEEN]: Phaser.Group; @@ -171,6 +206,7 @@ export class ParticlesWrapper { ) => {x: number; y: number} ) { const promises: Promise[] = []; + const force_destroy_callbacks: (() => void)[] = []; xy_pos_getter = xy_pos_getter ?? ((x: number, y: number, shift_x: number, shift_y: number) => { @@ -299,6 +335,21 @@ export class ParticlesWrapper { (emitter.renderer as Phaser.ParticleStorm.Renderer.Pixel).resize(GAME_WIDTH << 1, GAME_HEIGHT); } + let group = particles_group; + if (!group) { + switch (adv_particles_seq.group_type) { + case game_groups.LOWER: + group = this.data.underlayer_group; + break; + case game_groups.MIDDLE: + group = this.data.middlelayer_group; + break; + case game_groups.OVER: + group = this.data.overlayer_group; + break; + } + } + const displays = emitter.addToWorld(particles_group); if (inner_groups) { displays.forEach(display => { @@ -422,7 +473,15 @@ export class ParticlesWrapper { emitters.push(emitter); }); - this.game.time.events.add(adv_particles_seq.emission_finish, () => { + const timer = this.game.time.create(true); + let destroyed = false; + const force_destroy = () => { + timer.stop(true); + timer.destroy(); + if (destroyed) { + return; + } + destroyed = true; render_callbacks.forEach(key => { delete this.render_callbacks[key]; }); @@ -437,10 +496,16 @@ export class ParticlesWrapper { this.data.particle_manager.clearData(key); } resolve_function(); - }); + }; + timer.add(adv_particles_seq.emission_finish, force_destroy); + timer.start(); + force_destroy_callbacks.push(force_destroy); } - return promises; + return { + promises: promises, + force_destroy_callbacks: force_destroy_callbacks, + }; } render() { diff --git a/base/battle/BattleAnimation.ts b/base/battle/BattleAnimation.ts index 9e91002fad..67bfbb62ee 100644 --- a/base/battle/BattleAnimation.ts +++ b/base/battle/BattleAnimation.ts @@ -1603,7 +1603,7 @@ export class BattleAnimation { this.ability_sprites_groups, this.element, this.get_sprite_xy_pos.bind(this) - ); + ).promises; this.promises.push(...promises); } diff --git a/base/game_events/BattleEvent.ts b/base/game_events/BattleEvent.ts index b855088212..fed23b5634 100644 --- a/base/game_events/BattleEvent.ts +++ b/base/game_events/BattleEvent.ts @@ -131,6 +131,8 @@ export class BattleEvent extends GameEvent { undefined, undefined, undefined, + undefined, + undefined, undefined ); let promise_resolve; diff --git a/base/game_events/ParticlesEvent.ts b/base/game_events/ParticlesEvent.ts index e143965c7f..48d5c74961 100644 --- a/base/game_events/ParticlesEvent.ts +++ b/base/game_events/ParticlesEvent.ts @@ -1,5 +1,5 @@ -import {ParticlesInfo} from "ParticlesWrapper"; -import {EventValue, GameEvent, event_types} from "./GameEvent"; +import {ParticlesInfo, ParticlesWrapper} from "../ParticlesWrapper"; +import {GameEvent, event_types} from "./GameEvent"; enum game_groups { LOWER = "lower", @@ -29,39 +29,13 @@ export class ParticlesEvent extends GameEvent { async _fire() { ++this.data.game_event_manager.events_running_count; - const xy_pos_getter = ( - x: number | EventValue, - y: number | EventValue, - shift_x: number | EventValue, - shift_y: number | EventValue - ) => { - let this_x = x as number; - let this_y = y as number; - let this_shift_x = shift_x as number; - let this_shift_y = shift_y as number; - if (x !== undefined && typeof x !== "number") { - this_x = this.data.game_event_manager.get_value(x); - } - if (y !== undefined && typeof y !== "number") { - this_y = this.data.game_event_manager.get_value(y); - } - if (shift_x !== undefined && typeof shift_x !== "number") { - this_shift_x = this.data.game_event_manager.get_value(shift_x); - } - if (shift_y !== undefined && typeof shift_y !== "number") { - this_shift_y = this.data.game_event_manager.get_value(shift_y); - } - this_x += this_shift_x ?? 0; - this_y += this_shift_y ?? 0; - return {x: this_x, y: this_y}; - }; const promises = this.data.particle_wrapper.start_particles( this.particles_info, this.group, undefined, undefined, - xy_pos_getter - ); + ParticlesWrapper.expanded_xy_pos_getter.bind(this, this.data) + ).promises; const udpate_callback = () => this.data.particle_wrapper.render(); this.data.game_event_manager.add_callback(udpate_callback); await Promise.all(promises); diff --git a/base/game_events/TeleportEvent.ts b/base/game_events/TeleportEvent.ts index 9c72c661fe..585be0df2b 100644 --- a/base/game_events/TeleportEvent.ts +++ b/base/game_events/TeleportEvent.ts @@ -62,6 +62,8 @@ export class TeleportEvent extends GameEvent { undefined, this.fade_color, undefined, + undefined, + undefined, undefined ); event.set_fadein_callback(() => { diff --git a/base/tile_events/SliderEvent.ts b/base/tile_events/SliderEvent.ts index 30f2bd39bb..aec57daa65 100644 --- a/base/tile_events/SliderEvent.ts +++ b/base/tile_events/SliderEvent.ts @@ -217,6 +217,8 @@ export class SliderEvent extends TileEvent { undefined, undefined, undefined, + undefined, + undefined, undefined ); event.set_fadein_callback(() => { diff --git a/base/tile_events/TileEventManager.ts b/base/tile_events/TileEventManager.ts index 19645e94e1..276880735d 100644 --- a/base/tile_events/TileEventManager.ts +++ b/base/tile_events/TileEventManager.ts @@ -208,7 +208,7 @@ export class TileEventManager { case event_types.ROPE: if ( this_event.type === event_types.TELEPORT && - !(this_event as TeleportEvent).open_door && + !(this_event as TeleportEvent).need_stop_before_start && !(this_event as TeleportEvent).start_climbing ) { this.event_queue.add( @@ -340,7 +340,9 @@ export class TileEventManager { info.on_event_toggle_layers, info.fade_color, info.dont_change_to_idle, - info.play_sfx + info.play_sfx, + info.custom_sfx, + info.particles_info ); } else if (info.type === event_types.SLIDER) { return new SliderEvent(