diff --git a/CONTEXT.md b/CONTEXT.md index fde3e17a3..9fa2bea16 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -517,6 +517,18 @@ the effective run speed. Never a second state machine. The one shared operation that removes the active Land Mount's aura rows and re-derives the Mount Projection. Idempotent, and a no-op for a rider who is not mounted. +### Death and resurrection + +**Self-Resurrection Option**: +The one spell a dead Character may cast on itself from the death dialog. Chosen at death from the +Character's Soulstone aura, kept through Release Spirit, and spent when the Character is resurrected +by any path or leaves the world. The client sees it as `PLAYER_SELF_RES_SPELL`. +_Avoid_: self-res offer, rez offer, resurrect offer (an offer is a resurrect request from another Character) + +**Soulstone**: +The item a Warlock creates, and the Aura its use puts on a Character. A Character that dies while the +Aura is on it gets a Self-Resurrection Option. The Aura itself does not survive death. + ### Procs **Proc**: diff --git a/docs/architecture.md b/docs/architecture.md index 29409318e..50e6e6da6 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -789,6 +789,7 @@ explains why two rungs of the ladder are written down instead of automated. | [`guild-client-check.md`](./guild-client-check.md) | Guilds between two real 5875 clients across a Shard Boundary: founding, invites, chat, ranks, Transfer, emblem, Charter and deletion. Status: outstanding, needs a human. | | [`mail-client-check.md`](./mail-client-check.md) | Mail against a real 5875 client. Status: outstanding, needs a human. | | [`meeting-stone-client-check.md`](./meeting-stone-client-check.md) | Meeting stones between two real 5875 clients across a Shard Boundary: the JOIN packet, tooltip, minimap button, every status line, Transfer, logout and a stone-formed Party. Status: outstanding, needs a human. | +| [`self-resurrection-client-check.md`](./self-resurrection-client-check.md) | The Soulstone Self-Resurrection Option against a real 5875 client: the death dialog button, the revived vitals, the buff duration and the Release Spirit edge. Status: outstanding, needs a human. | | [`duel-client-check.md`](./duel-client-check.md) | Duel visuals against a real 5875 client, which the automated tests cannot see. Status: outstanding. | | [`chat-client-check.md`](./chat-client-check.md) | Realm-wide chat between two real 5875 clients across a Shard Boundary: party, channels and moderation, AFK and DND, whisper, friends, `/who`, ignore, say range, proximity emotes, the language Gate and the flood mute. Status: outstanding, needs a human. | | [`raid-client-check.md`](./raid-client-check.md) | Raids, Group Broadcasts, raid chat, member stats across Shards and the Instance Removal countdown against real 5875 clients. Status: outstanding, needs a human. | diff --git a/docs/self-resurrection-client-check.md b/docs/self-resurrection-client-check.md new file mode 100644 index 000000000..49ad6a343 --- /dev/null +++ b/docs/self-resurrection-client-check.md @@ -0,0 +1,47 @@ +# Self-resurrection client check + +Execution status: outstanding. This checklist needs a human with an unmodified 1.12.1 build-5875 +client. The automated tests prove the Self-Resurrection Option at the reducer seam, the +`PLAYER_SELF_RES_SPELL` bytes, and the `CMSG_SELF_RES` dispatch. They cannot prove what the client +draws or when it sends the opcode. The field index and the 30 minute duration come from emulator +source and the ClassicDB dump, not from a client. + +Use only an isolated non-production LyraCore stack. Never point these steps at a production database, +and never use `spacetime publish -c`. Point the client's realmlist at the isolated stack first. Import +the operator-owned 1.12.1 client data with spells and items, so the five Soulstone Resurrection +ranks, their self-resurrect spells and the Soulstone item templates exist. Run the Gateway at debug +log level. + +Prepare one Warlock of level 18 or higher, and one Priest who knows Resurrection for the ally step. + +Data, before any client: + +- [ ] On the isolated stack, read `game_spell` and `game_spell_effect` for spells 20707 and 3026 with + `spacetime sql`. For 20707 confirm `duration_ms = 1800000`, `cast_time_ms = 3000`, and one + effect with kind `0xB5` (`A_SELF_RESURRECT`), `p0 = 3026`, `p0_kind = 15`. For 3026 confirm + one effect with kind `0x26` (`E_SELF_RESURRECT`), `base_points = -400`, `p0 = 700`. Record any + difference. + +Soulstone: + +- [ ] Grant the Warlock a Minor Soulstone (`debug_grant_item 5232 1`) and use it on itself. + Record whether the 3 second cast bar shows, and whether the buff shows a 30 minute timer. +- [ ] Kill the Warlock (`debug_set_health 0`). Confirm the death dialog shows a second button + beside Release Spirit. Record its exact text. +- [ ] Click it. Confirm the death screen closes, health shows 400, mana shows 700 (or the Warlock's + max mana if lower), no Resurrection Sickness, and no corpse. Record the numbers. +- [ ] Record whether the client plays any cast animation or sound on use. The server sends no cast + packet for it. +- [ ] Repeat, but click Release Spirit first. Record whether the ghost sees any self-resurrection + prompt or button. The server keeps the option for the ghost; if the client offers a way to use + it, confirm it works. +- [ ] Repeat, but die inside the Deadmines and release into Westfall. Record whether the option is + still offered. The server does not carry it across a Shard hop. +- [ ] Die with a Soulstone, let the Priest resurrect the Warlock, and accept. Then die without a + Soulstone. Confirm the dialog shows only Release Spirit. +- [ ] Die with a Soulstone, log out on the death screen, and log back in. Record the state. +- [ ] Use a Soulstone, then move during the 3 second cast. Record whether the item is lost. Every + timed consumable is consumed when its cast starts. + +Record the server commit, the client build on the login screen, Character names and levels, each +dialog text, each number read from the client, and any disconnect or error dialog. diff --git a/gateway/src/codec/tests.rs b/gateway/src/codec/tests.rs index db96ae6cb..cb3841e7e 100644 --- a/gateway/src/codec/tests.rs +++ b/gateway/src/codec/tests.rs @@ -2615,6 +2615,33 @@ fn player_ammo_id_values_is_player_only_no_object_type() { ); } +#[test] +fn self_res_spell_values_sets_only_field_1224() { + // PLAYER_SELF_RES_SPELL is vanilla update field 1224 (cmangos-classic UpdateFields.h: + // PLAYER_AMMO_ID + 1). 1224 = 38 * 32 + 8, so the mask spans 39 blocks: 38 empty ones (block 0 + // carries no OBJECT_FIELD_TYPE bit 2), then bit 8 of block 38, then the one value word. Minor + // Soulstone's self-resurrect spell is 3026 = 0x0BD2. + let msg = build_self_res_spell_values(1, 3026); + let mut buf = Vec::new(); + msg.write_unencrypted_server(&mut buf).unwrap(); + let mut tail = vec![39u8]; + tail.extend(std::iter::repeat_n(0u8, 38 * 4)); + tail.extend([0x00, 0x01, 0x00, 0x00]); + tail.extend([0xD2, 0x0B, 0x00, 0x00]); + assert!( + buf.ends_with(&tail), + "the VALUES mask must carry field 1224 alone; tail was {:02x?}", + &buf[buf.len().saturating_sub(tail.len())..] + ); + + let cleared = build_self_res_spell_values(1, 0); + let mut buf = Vec::new(); + cleared.write_unencrypted_server(&mut buf).unwrap(); + tail.truncate(tail.len() - 4); + tail.extend([0x00; 4]); + assert!(buf.ends_with(&tail), "spell 0 clears the field"); +} + #[test] fn player_xp_values_carries_xp_and_next_level_no_object_type() { let msg = build_player_xp_values(1, 450, 1000); diff --git a/gateway/src/codec/values.rs b/gateway/src/codec/values.rs index 9d36683ff..cce381c0a 100644 --- a/gateway/src/codec/values.rs +++ b/gateway/src/codec/values.rs @@ -436,6 +436,15 @@ pub fn build_player_ammo_id_values(guid: u64, ammo_entry: u32) -> SMSG_UPDATE_OB }) } +/// Build a VALUES partial-update carrying `PLAYER_SELF_RES_SPELL`, the Self-Resurrection Option the +/// 5875 death dialog offers as its second button. `spell_id` 0 clears it. Owner-only field; same +/// `dirty_reset` discipline as `build_coinage_values`, so `OBJECT_FIELD_TYPE` is never re-sent. +pub fn build_self_res_spell_values(guid: u64, spell_id: u32) -> SMSG_UPDATE_OBJECT { + player_values(guid, |player| { + player.set_player_self_res_spell(spell_id as i32); + }) +} + /// `PLAYER_CHARACTER_POINTS1` partial VALUES — the talent pane's unspent-points counter. Pushed /// LIVE after a talent pick (fires the client's CHARACTER_POINTS_CHANGED → TalentFrame refresh) /// and once after the login CREATE for a character with spent points (the CREATE's formula counts diff --git a/gateway/src/stdb/bindings/debug_self_resurrect_reducer.rs b/gateway/src/stdb/bindings/debug_self_resurrect_reducer.rs new file mode 100644 index 000000000..b36eac189 --- /dev/null +++ b/gateway/src/stdb/bindings/debug_self_resurrect_reducer.rs @@ -0,0 +1,68 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct DebugSelfResurrectArgs { + pub character_guid: u64, +} + +impl From for super::Reducer { + fn from(args: DebugSelfResurrectArgs) -> Self { + Self::DebugSelfResurrect { + character_guid: args.character_guid, + } + } +} + +impl __sdk::InModule for DebugSelfResurrectArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `debug_self_resurrect`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait debug_self_resurrect { + /// Request that the remote module invoke the reducer `debug_self_resurrect` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and this method provides no way to listen for its completion status. + /// /// Use [`debug_self_resurrect:debug_self_resurrect_then`] to run a callback after the reducer completes. + fn debug_self_resurrect(&self, character_guid: u64) -> __sdk::Result<()> { + self.debug_self_resurrect_then(character_guid, |_, _| {}) + } + + /// Request that the remote module invoke the reducer `debug_self_resurrect` to run as soon as possible, + /// registering `callback` to run when we are notified that the reducer completed. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed with the `callback`. + fn debug_self_resurrect_then( + &self, + character_guid: u64, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()>; +} + +impl debug_self_resurrect for super::RemoteReducers { + fn debug_self_resurrect_then( + &self, + character_guid: u64, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()> { + self.imp + .invoke_reducer_with_callback(DebugSelfResurrectArgs { character_guid }, callback) + } +} diff --git a/gateway/src/stdb/bindings/game_self_resurrect_option_table.rs b/gateway/src/stdb/bindings/game_self_resurrect_option_table.rs new file mode 100644 index 000000000..55aca3cee --- /dev/null +++ b/gateway/src/stdb/bindings/game_self_resurrect_option_table.rs @@ -0,0 +1,231 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use super::self_resurrect_option_type::SelfResurrectOption; +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +/// Table handle for the table `game_self_resurrect_option`. +/// +/// Obtain a handle from the [`GameSelfResurrectOptionTableAccess::game_self_resurrect_option`] method on [`super::RemoteTables`], +/// like `ctx.db.game_self_resurrect_option()`. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.game_self_resurrect_option().on_insert(...)`. +pub struct GameSelfResurrectOptionTableHandle<'ctx> { + imp: __sdk::TableHandle, + ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +/// Lifetime-aware accessor marker for the table `game_self_resurrect_option`. +pub struct GameSelfResurrectOptionTableAccessor; + +impl __sdk::TableAccessor for GameSelfResurrectOptionTableAccessor { + type Row = SelfResurrectOption; + type Handle<'db> = GameSelfResurrectOptionTableHandle<'db>; + + fn get<'db>(db: &'db super::RemoteTables) -> Self::Handle<'db> { + db.game_self_resurrect_option() + } +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the table `game_self_resurrect_option`. +/// +/// Implemented for [`super::RemoteTables`]. +pub trait GameSelfResurrectOptionTableAccess { + #[allow(non_snake_case)] + /// Obtain a [`GameSelfResurrectOptionTableHandle`], which mediates access to the table `game_self_resurrect_option`. + fn game_self_resurrect_option(&self) -> GameSelfResurrectOptionTableHandle<'_>; +} + +impl GameSelfResurrectOptionTableAccess for super::RemoteTables { + fn game_self_resurrect_option(&self) -> GameSelfResurrectOptionTableHandle<'_> { + GameSelfResurrectOptionTableHandle { + imp: self + .imp + .get_table::("game_self_resurrect_option"), + ctx: std::marker::PhantomData, + } + } +} + +pub struct GameSelfResurrectOptionInsertCallbackId(__sdk::CallbackId); +pub struct GameSelfResurrectOptionDeleteCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableLike for GameSelfResurrectOptionTableHandle<'ctx> { + type Row = SelfResurrectOption; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } +} + +impl<'ctx> __sdk::Table for GameSelfResurrectOptionTableHandle<'ctx> { + type Row = SelfResurrectOption; + type EventContext = super::EventContext; + + fn count(&self) -> u64 { + self.imp.count() + } + fn iter(&self) -> impl Iterator + '_ { + self.imp.iter() + } + + type InsertCallbackId = GameSelfResurrectOptionInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> GameSelfResurrectOptionInsertCallbackId { + GameSelfResurrectOptionInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: GameSelfResurrectOptionInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } + + type DeleteCallbackId = GameSelfResurrectOptionDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> GameSelfResurrectOptionDeleteCallbackId { + GameSelfResurrectOptionDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: GameSelfResurrectOptionDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +impl<'ctx> __sdk::WithInsert for GameSelfResurrectOptionTableHandle<'ctx> { + type InsertCallbackId = GameSelfResurrectOptionInsertCallbackId; + + fn on_insert( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> GameSelfResurrectOptionInsertCallbackId { + GameSelfResurrectOptionInsertCallbackId(self.imp.on_insert(Box::new(callback))) + } + + fn remove_on_insert(&self, callback: GameSelfResurrectOptionInsertCallbackId) { + self.imp.remove_on_insert(callback.0) + } +} + +impl<'ctx> __sdk::WithDelete for GameSelfResurrectOptionTableHandle<'ctx> { + type DeleteCallbackId = GameSelfResurrectOptionDeleteCallbackId; + + fn on_delete( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static, + ) -> GameSelfResurrectOptionDeleteCallbackId { + GameSelfResurrectOptionDeleteCallbackId(self.imp.on_delete(Box::new(callback))) + } + + fn remove_on_delete(&self, callback: GameSelfResurrectOptionDeleteCallbackId) { + self.imp.remove_on_delete(callback.0) + } +} + +pub struct GameSelfResurrectOptionUpdateCallbackId(__sdk::CallbackId); + +impl<'ctx> __sdk::TableWithPrimaryKey for GameSelfResurrectOptionTableHandle<'ctx> { + type UpdateCallbackId = GameSelfResurrectOptionUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> GameSelfResurrectOptionUpdateCallbackId { + GameSelfResurrectOptionUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: GameSelfResurrectOptionUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +impl<'ctx> __sdk::WithUpdate for GameSelfResurrectOptionTableHandle<'ctx> { + type UpdateCallbackId = GameSelfResurrectOptionUpdateCallbackId; + + fn on_update( + &self, + callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static, + ) -> GameSelfResurrectOptionUpdateCallbackId { + GameSelfResurrectOptionUpdateCallbackId(self.imp.on_update(Box::new(callback))) + } + + fn remove_on_update(&self, callback: GameSelfResurrectOptionUpdateCallbackId) { + self.imp.remove_on_update(callback.0) + } +} + +/// Access to the `character_guid` unique index on the table `game_self_resurrect_option`, +/// which allows point queries on the field of the same name +/// via the [`GameSelfResurrectOptionCharacterGuidUnique::find`] method. +/// +/// Users are encouraged not to explicitly reference this type, +/// but to directly chain method calls, +/// like `ctx.db.game_self_resurrect_option().character_guid().find(...)`. +pub struct GameSelfResurrectOptionCharacterGuidUnique<'ctx> { + imp: __sdk::UniqueConstraintHandle, + phantom: std::marker::PhantomData<&'ctx super::RemoteTables>, +} + +impl<'ctx> GameSelfResurrectOptionTableHandle<'ctx> { + /// Get a handle on the `character_guid` unique index on the table `game_self_resurrect_option`. + pub fn character_guid(&self) -> GameSelfResurrectOptionCharacterGuidUnique<'ctx> { + GameSelfResurrectOptionCharacterGuidUnique { + imp: self.imp.get_unique_constraint::("character_guid"), + phantom: std::marker::PhantomData, + } + } +} + +impl<'ctx> GameSelfResurrectOptionCharacterGuidUnique<'ctx> { + /// Find the subscribed row whose `character_guid` column value is equal to `col_val`, + /// if such a row is present in the client cache. + pub fn find(&self, col_val: &u64) -> Option { + self.imp.find(col_val) + } +} + +#[doc(hidden)] +pub(super) fn register_table(client_cache: &mut __sdk::ClientCache) { + let _table = + client_cache.get_or_make_table::("game_self_resurrect_option"); + _table.add_unique_constraint::("character_guid", |row| &row.character_guid); +} + +#[doc(hidden)] +pub(super) fn parse_table_update( + raw_updates: __ws::v2::TableUpdate, +) -> __sdk::Result<__sdk::TableUpdate> { + __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { + __sdk::InternalError::failed_parse("TableUpdate", "TableUpdate") + .with_cause(e) + .into() + }) +} + +#[allow(non_camel_case_types)] +/// Extension trait for query builder access to the table `SelfResurrectOption`. +/// +/// Implemented for [`__sdk::QueryTableAccessor`]. +pub trait game_self_resurrect_optionQueryTableAccess { + #[allow(non_snake_case)] + /// Get a query builder for the table `SelfResurrectOption`. + fn game_self_resurrect_option(&self) -> __sdk::__query_builder::Table; +} + +impl game_self_resurrect_optionQueryTableAccess for __sdk::QueryTableAccessor { + fn game_self_resurrect_option(&self) -> __sdk::__query_builder::Table { + __sdk::__query_builder::Table::new("game_self_resurrect_option") + } +} diff --git a/gateway/src/stdb/bindings/gw_self_resurrect_reducer.rs b/gateway/src/stdb/bindings/gw_self_resurrect_reducer.rs new file mode 100644 index 000000000..2bb0c79c8 --- /dev/null +++ b/gateway/src/stdb/bindings/gw_self_resurrect_reducer.rs @@ -0,0 +1,70 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +#![allow(unused, clippy::all)] +use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; + +use super::session_actor_type::SessionActor; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub(super) struct GwSelfResurrectArgs { + pub request_actor: SessionActor, +} + +impl From for super::Reducer { + fn from(args: GwSelfResurrectArgs) -> Self { + Self::GwSelfResurrect { + request_actor: args.request_actor, + } + } +} + +impl __sdk::InModule for GwSelfResurrectArgs { + type Module = super::RemoteModule; +} + +#[allow(non_camel_case_types)] +/// Extension trait for access to the reducer `gw_self_resurrect`. +/// +/// Implemented for [`super::RemoteReducers`]. +pub trait gw_self_resurrect { + /// Request that the remote module invoke the reducer `gw_self_resurrect` to run as soon as possible. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and this method provides no way to listen for its completion status. + /// /// Use [`gw_self_resurrect:gw_self_resurrect_then`] to run a callback after the reducer completes. + fn gw_self_resurrect(&self, request_actor: SessionActor) -> __sdk::Result<()> { + self.gw_self_resurrect_then(request_actor, |_, _| {}) + } + + /// Request that the remote module invoke the reducer `gw_self_resurrect` to run as soon as possible, + /// registering `callback` to run when we are notified that the reducer completed. + /// + /// This method returns immediately, and errors only if we are unable to send the request. + /// The reducer will run asynchronously in the future, + /// and its status can be observed with the `callback`. + fn gw_self_resurrect_then( + &self, + request_actor: SessionActor, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()>; +} + +impl gw_self_resurrect for super::RemoteReducers { + fn gw_self_resurrect_then( + &self, + request_actor: SessionActor, + + callback: impl FnOnce(&super::ReducerEventContext, Result, __sdk::InternalError>) + + Send + + 'static, + ) -> __sdk::Result<()> { + self.imp + .invoke_reducer_with_callback(GwSelfResurrectArgs { request_actor }, callback) + } +} diff --git a/gateway/src/stdb/bindings/mod.rs b/gateway/src/stdb/bindings/mod.rs index 1ba2aa7ee..e82bf4457 100644 --- a/gateway/src/stdb/bindings/mod.rs +++ b/gateway/src/stdb/bindings/mod.rs @@ -249,6 +249,7 @@ pub mod debug_seed_creature_ai_fixtures_reducer; pub mod debug_seed_mail_reducer; pub mod debug_seed_package_config_reducer; pub mod debug_seed_scenario_fixtures_reducer; +pub mod debug_self_resurrect_reducer; pub mod debug_sell_item_reducer; pub mod debug_set_health_reducer; pub mod debug_set_lethal_damage_floor_fixture_reducer; @@ -612,6 +613,7 @@ pub mod game_resurrect_request_table; pub mod game_roll_event_table; pub mod game_school_lockout_table; pub mod game_script_table; +pub mod game_self_resurrect_option_table; pub mod game_session_reaper_schedule_table; pub mod game_session_table; pub mod game_sessionless_action_consent_table; @@ -806,6 +808,7 @@ pub mod gw_repair_item_reducer; pub mod gw_repop_reducer; pub mod gw_reset_talents_reducer; pub mod gw_respond_resurrect_reducer; +pub mod gw_self_resurrect_reducer; pub mod gw_sell_item_reducer; pub mod gw_send_chat_reducer; pub mod gw_send_emote_reducer; @@ -1070,6 +1073,7 @@ pub mod scale_selected_threat_instruction_type; pub mod school_lockout_type; pub mod script_type; pub mod seeker_facts_type; +pub mod self_resurrect_option_type; pub mod server_config_type; pub mod session_actor_type; pub mod session_reaper_schedule_type; @@ -1415,6 +1419,7 @@ pub use debug_seed_creature_ai_fixtures_reducer::debug_seed_creature_ai_fixtures pub use debug_seed_mail_reducer::debug_seed_mail; pub use debug_seed_package_config_reducer::debug_seed_package_config; pub use debug_seed_scenario_fixtures_reducer::debug_seed_scenario_fixtures; +pub use debug_self_resurrect_reducer::debug_self_resurrect; pub use debug_sell_item_reducer::debug_sell_item; pub use debug_set_health_reducer::debug_set_health; pub use debug_set_lethal_damage_floor_fixture_reducer::debug_set_lethal_damage_floor_fixture; @@ -1778,6 +1783,7 @@ pub use game_resurrect_request_table::*; pub use game_roll_event_table::*; pub use game_school_lockout_table::*; pub use game_script_table::*; +pub use game_self_resurrect_option_table::*; pub use game_session_reaper_schedule_table::*; pub use game_session_table::*; pub use game_sessionless_action_consent_table::*; @@ -1972,6 +1978,7 @@ pub use gw_repair_item_reducer::gw_repair_item; pub use gw_repop_reducer::gw_repop; pub use gw_reset_talents_reducer::gw_reset_talents; pub use gw_respond_resurrect_reducer::gw_respond_resurrect; +pub use gw_self_resurrect_reducer::gw_self_resurrect; pub use gw_sell_item_reducer::gw_sell_item; pub use gw_send_chat_reducer::gw_send_chat; pub use gw_send_emote_reducer::gw_send_emote; @@ -2236,6 +2243,7 @@ pub use scale_selected_threat_instruction_type::ScaleSelectedThreatInstruction; pub use school_lockout_type::SchoolLockout; pub use script_type::Script; pub use seeker_facts_type::SeekerFacts; +pub use self_resurrect_option_type::SelfResurrectOption; pub use server_config_type::ServerConfig; pub use session_actor_type::SessionActor; pub use session_reaper_schedule_type::SessionReaperSchedule; @@ -2973,6 +2981,9 @@ pub enum Reducer { value: String, }, DebugSeedScenarioFixtures, + DebugSelfResurrect { + character_guid: u64, + }, DebugSellItem { character_guid: u64, vendor_guid: u64, @@ -3729,6 +3740,9 @@ pub enum Reducer { request_actor: SessionActor, accept: bool, }, + GwSelfResurrect { + request_actor: SessionActor, + }, GwSellItem { request_actor: SessionActor, vendor_guid: u64, @@ -4523,6 +4537,7 @@ impl __sdk::Reducer for Reducer { Reducer::DebugSeedMail { .. } => "debug_seed_mail", Reducer::DebugSeedPackageConfig { .. } => "debug_seed_package_config", Reducer::DebugSeedScenarioFixtures => "debug_seed_scenario_fixtures", + Reducer::DebugSelfResurrect { .. } => "debug_self_resurrect", Reducer::DebugSellItem { .. } => "debug_sell_item", Reducer::DebugSetHealth { .. } => "debug_set_health", Reducer::DebugSetLethalDamageFloorFixture { .. } => { @@ -4729,6 +4744,7 @@ impl __sdk::Reducer for Reducer { Reducer::GwRepop { .. } => "gw_repop", Reducer::GwResetTalents { .. } => "gw_reset_talents", Reducer::GwRespondResurrect { .. } => "gw_respond_resurrect", + Reducer::GwSelfResurrect { .. } => "gw_self_resurrect", Reducer::GwSellItem { .. } => "gw_sell_item", Reducer::GwSendChat { .. } => "gw_send_chat", Reducer::GwSendEmote { .. } => "gw_send_emote", @@ -6001,7 +6017,12 @@ Reducer::DebugSeedMail{ }), Reducer::DebugSeedScenarioFixtures => __sats::bsatn::to_vec(&debug_seed_scenario_fixtures_reducer::DebugSeedScenarioFixturesArgs { }), -Reducer::DebugSellItem{ +Reducer::DebugSelfResurrect{ + character_guid, +} => __sats::bsatn::to_vec(&debug_self_resurrect_reducer::DebugSelfResurrectArgs { + character_guid: character_guid.clone(), +}), + Reducer::DebugSellItem{ character_guid, vendor_guid, slot, @@ -7360,6 +7381,11 @@ Reducer::GwIgnoreTrade{ } => __sats::bsatn::to_vec(&gw_respond_resurrect_reducer::GwRespondResurrectArgs { request_actor: request_actor.clone(), accept: accept.clone(), +}), + Reducer::GwSelfResurrect{ + request_actor, +} => __sats::bsatn::to_vec(&gw_self_resurrect_reducer::GwSelfResurrectArgs { + request_actor: request_actor.clone(), }), Reducer::GwSellItem{ request_actor, @@ -8727,6 +8753,7 @@ pub struct DbUpdate { game_roll_event: __sdk::TableUpdate, game_school_lockout: __sdk::TableUpdate, game_script: __sdk::TableUpdate