////////////////////////////////////////////////////////////////////////////// // // File : aura_spellbook.skrit // Author(s): Witness // Purpose : Checks the spellbook active slot contents and delegates the // (de)activation of auras in either of those slots. // // Versions : v2.1 [November 18, 2004] // - fixes buff spell deletion bug, apparently sending // WE_REQ_DEACTIVATE (which aura_spellbook accidentally does // due to a little aura-check omission snaffu) causes these // spells to delete themselves, even though there is no skrit // in those respective spells that is supposed to react thusly // - in case death removes all generic states, the Tracking$ // state will now check for the existence of the check_state$, // and add itself as the manager if it isn't present when // entering that state (prevents potential duplicate aura // checkers, which can slow down the game if there are too // many duplicates active) // // v2.0 [November 13, 2004] // - aura_spellbook is a component for a standalone omni manager // (not a spellbook component anymore, for increased mod // compatibility and stability) // - sends WE_REQ_(DE)ACTIVATE instead of WE_TRIGGER_(DE)ACTIVATE // // v1.0 [June 18, 2004] // - auras notify their parent spellbook when they are placed in // either the spellbook's first or second active slot (because // the spellbook might not otherwise gets any notification) // //---------------------------------------------------------------------------- // Version: 2.1 Date: November 18, 2004 //---------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////////// property string check_state$ = "aura_check"; owner = GoSkritComponent; ////////////////////////////////////////////////////////////////////////////// // GLOBALS ////////////////////////////////////////////////////////////////////////////// Go caster$; Goid spell1$, spell2$; Goid aura$; eInventoryLocation selected_loc$; ////////////////////////////////////////////////////////////////////////////// // STATES ////////////////////////////////////////////////////////////////////////////// startup State Init$ { event OnEnterState$ { spell1$ = Goid.InvalidGoid; spell2$ = Goid.InvalidGoid; aura$ = Goid.InvalidGoid; selected_loc$ = IL_INVALID; } event OnGoHandleMessage$( eWorldEvent e$, WorldMessage msg$ ) { if ( e$ == WE_REQ_ACTIVATE ) { Goid sender$ = msg$.SendFrom; if ( sender$.IsValid ) { caster$ = sender$.Go; GoDb.StartWatching( owner.Goid, caster$.Goid ); SetState Tracking$; } else { SetState Exiting$; } } } } State Tracking$ { Goid selected$; Goid GetSpellUpdate$( Goid current_spell$, eInventoryLocation il$, bool force_select$ ) { Go spell$ = caster$.Inventory.GetItem( il$ ); if ( spell$ != NULL ) { Goid spell_goid$ = spell$.Goid; if ( !selected$.IsValid ) { if ( current_spell$.IsValid ) { if ( spell_goid$ != current_spell$ ) { if ( spell$.HasComponent( "aura" ) ) { selected$ = spell_goid$; //report.screenf("selecting aura: %s (%d)", selected$.Go.TemplateName, MakeInt(selected$)); } } else if ( !aura$.IsValid ) { if ( spell$.HasComponent( "aura" ) ) { selected$ = spell_goid$; } } else if ( spell_goid$ == aura$ ) { if ( spell$.HasComponent( "aura" ) ) { selected$ = spell_goid$; } //report.screenf("selecting aura: %s (%d)", selected$.Go.TemplateName, MakeInt(selected$)); } else if ( force_select$ ) { if ( spell$.HasComponent( "aura" ) ) { selected$ = spell_goid$; //report.screenf("selecting aura: %s (%d)", selected$.Go.TemplateName, MakeInt(selected$)); } } } else if ( spell$.HasComponent( "aura" ) ) { selected$ = spell_goid$; //report.screenf("selecting aura: %s (%d)", selected$.Go.TemplateName, MakeInt(selected$)); } } //report.screenf("GetSpellUpdate$ il:%d, name:%s, id:%d", il$, spell$.TemplateName, MakeInt(spell_goid$)); return spell_goid$; } //report.screenf("GetSpellUpdate$ il:%d", il$); return Goid.InvalidGoid; } event OnEnterState$ { if ( !caster$.Actor.HasGenericState( check_state$ ) ) { //add the check state caster$.Actor.SAddGenericState( check_state$, "", 0.0, caster$.Goid, owner.Goid, 1.0 ); } } event OnGoUpdate$( float ) { if ( !IsConscious( caster$.LifeState ) ) { SetState Waiting$; return; } selected$ = Goid.InvalidGoid; Go spell$ = caster$.Inventory.SelectedSpell; if ( spell$ != NULL ) { eInventoryLocation loc$ = spell$.Parent.Inventory.GetLocation( spell$ ); bool force_select$; if ( selected_loc$ != loc$ ) { //report.screenf("!!!!!!selected location has changed!!!!!!"); selected_loc$ = loc$; force_select$ = true; } else { force_select$ = false; } if ( loc$ == IL_SPELL_1 ) { //report.screenf("forward loc GetSpellUpdate$"); spell1$ = GetSpellUpdate$( spell1$, IL_ACTIVE_PRIMARY_SPELL, force_select$ ); spell2$ = GetSpellUpdate$( spell2$, IL_ACTIVE_SECONDARY_SPELL, false ); } else { //report.screenf("backwards loc GetSpellUpdate$"); spell2$ = GetSpellUpdate$( spell2$, IL_ACTIVE_SECONDARY_SPELL, force_select$ ); spell1$ = GetSpellUpdate$( spell1$, IL_ACTIVE_PRIMARY_SPELL, false ); } } else { //report.screenf("regular loc GetSpellUpdate$"); spell1$ = GetSpellUpdate$( spell1$, IL_ACTIVE_PRIMARY_SPELL, false ); spell2$ = GetSpellUpdate$( spell2$, IL_ACTIVE_SECONDARY_SPELL, false ); } //check active aura selection if ( selected$ != aura$ ) { //report.screenf("selected$ != aura$"); if ( aura$.IsValid ) { PostWorldMessage( WE_REQ_DEACTIVATE, owner.Goid, aura$, 0 ); } if ( selected$.IsValid ) { //report.screenf("selected$ (%s - %d)", selected$.Go.TemplateName, MakeInt(selected$) ); PostWorldMessage( WE_REQ_ACTIVATE, owner.Goid, selected$, 0 ); } //report.screenf("selected$ (%s - %d)", selected$.Go.TemplateName, MakeInt(selected$) ); aura$ = selected$; } else { if ( aura$.IsValid ) { //report.screenf("aura$ (%s - %d)", aura$.Go.TemplateName, MakeInt(aura$) ); } } } transition -> Exiting$ : OnGoHandleCCMessage( WE_DESTRUCTED ); } State Waiting$ { event OnEnterState$ { if ( aura$.IsValid ) { PostWorldMessage( WE_REQ_DEACTIVATE, owner.Goid, aura$, 0 ); } this.CreateTimer( 1, 1.0 ); this.SetTimerRepeatCount( 1, -1 ); } trigger OnTimer$( 1 ) { if ( IsConscious( caster$.LifeState ) ) { if ( aura$.IsValid ) { PostWorldMessage( WE_REQ_ACTIVATE, owner.Goid, aura$, 0 ); } SetState Tracking$; } } transition -> Exiting$ : OnGoHandleCCMessage( WE_DESTRUCTED ); } State Exiting$ { event OnEnterState$ { if ( caster$ != NULL ) { GoDb.StopWatching( owner.Goid, caster$.Goid ); } GoDb.SMarkForDeletion( owner.Go ); //PostWorldMessage( WE_REQ_DELETE, owner.Goid, owner.Goid, 0 ); } }