////////////////////////////////////////////////////////////////////////////// // // File : charges.skrit // Author(s): Witness (Lisa Hui) // Purpose : A generic charge manager for all sorts of items // // Versions : v2.1 [November 3, 2004] // - changes screen name caching in Init$ to include prefix,suffix // // v2.0 [August 14, 2004] // - added optional regeneration // - added optional delete event // - tested successfully with potions // // v1.0 [August 9, 2004] // - first release // // All changes in charge count in the Begin$ state results in reentering // the state, which will then sync all the shared values - screen name and // gold value across all clients. // //---------------------------------------------------------------------------- // Version: 2.1 Date: November 3, 2004 //---------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////////// property bool _server_only$ = true; property int charges_max$ = 100 doc = "if less than or equal to 0, then generate a random value (auto-set)"; property int charges_curr$ = -1 doc = "if less than 0, start with a random value, otherwise, start with specified value, up to max (auto-set)"; property int charges_curr_ceil$ = 100 doc = "random generator: maximum number of charges"; property int charges_curr_floor$ = 0 doc = "random generator: minimum number of charges"; property int charges_value$ = 35 doc = "how much is each charge worth in gold? (must be non-negative)"; property float charges_regen$ = 0.0 doc = "interval before regenerating to regenerate charges"; property bool charges_buyable$ = false doc = "can the item be recharged by selling to a merchant and then buying it back?"; property eWorldEvent event_use$ = WE_REQ_USE doc = "Subtract one from charges_curr when this message is heard, if charges_curr > 0."; property eWorldEvent event_recharge$ = WE_UNKNOWN doc = "Reset charges to full when this message is heard"; property eWorldEvent event_delete$ = WE_UNKNOWN doc = "Delete this item when this message is heard and charges_curr equals zero"; property bool notify_self$ = false doc = ""; property eWorldEvent notify_one$ = WE_UNKNOWN doc = ""; property eWorldEvent notify_none$ = WE_UNKNOWN doc = ""; property eWorldEvent notify_full$ = WE_UNKNOWN doc = ""; property eWorldEvent notify_filling$ = WE_UNKNOWN doc = ""; property string screen_name$ = "" doc = "The original screen name without the charge state appended."; owner = GoSkritComponent; ////////////////////////////////////////////////////////////////////////////// // GLOBALS ////////////////////////////////////////////////////////////////////////////// //void debug$(string msg$) { // report.screenf("%s (%d)> %s", owner.Go.TemplateName, MakeInt(owner.Goid), msg$); //} void notify$( eWorldEvent e$ ) { if ( e$ != WE_UNKNOWN ) { PostWorldMessage( e$, owner.Goid, owner.Goid, 0 ); } } ////////////////////////////////////////////////////////////////////////////// // STATES ////////////////////////////////////////////////////////////////////////////// startup State Init$ { #only(game) [[ event OnEnterState$ { //initialize charges_curr$ int current_value$ = owner.Go.Aspect.GoldValue; if ( current_value$ < charges_value$ ) { //treat this as a new item, initialize current charge value //int rand$ = GoMath.RandomInt( charges_curr_floor$, charges_curr_ceil$ ); charges_curr$ = GoMath.RandomInt( charges_curr_floor$, charges_curr_ceil$ ); /*charges_curr$ = ( charges_curr$ < 0 ? rand$ : ( charges_max$ < charges_curr$ ? charges_max$ : charges_curr$ ) );*/ //debug$(MakeStringF("charges - init random charge count - %d",rand$)); //debug$(MakeStringF("charges - init random charge count - %d",charges_curr$)); } else { //figure out how many charges there are supposed to be from the current gold value charges_curr$ = current_value$ / charges_value$; if ( charges_curr$ > charges_max$ ) { charges_curr$ = charges_max$; } //debug$(MakeStringF("charges - init previous charge count - %d",charges_curr$)); } } trigger OnGoHandleMessage$( WE_ENTERED_WORLD ) { //save the original screen name owner.Go.Common.GetScreenName( screen_name$ ); //screen_name$ = ContentDb.GetTemplateString( MakeStringF( "%s:common:screen_name", owner.Go.TemplateName ), "" ); //debug$(MakeStringF("charges - init screen name - %s",screen_name$)); SetState Begin$; } //transition -> Begin$ : OnGoHandleMessage( WE_ENTERED_WORLD ); ]] } State Begin$ { event OnEnterState$ { //debug$(MakeStringF("charges - check charge count - %d",charges_curr$)); //owner.Go.Common.GetScreenName( screen_name$ ); //debug$(MakeStringF("charges - init screen name - %s",screen_name$)); //alter gold value to reflect the current number of charges owner.Go.Aspect.SSetGoldValue( charges_curr$ * charges_value$, true ); //alter screen name to reflect the current number of charges owner.Go.Common.SSetScreenName( MakeStringF( "%s (%d/%d)", screen_name$, charges_curr$, charges_max$ ) ); //send a notification, event message to itself if ( notify_self$ ) { if ( charges_curr$ == 0 ) { notify$( notify_none$ ); } else if ( charges_curr$ == 1 ) { notify$( notify_one$ ); } else if ( charges_curr$ == charges_max$ ) { notify$( notify_full$ ); } } //set up regen timer only applicable and there are is "space" for additional charges if ( charges_curr$ < charges_max$ ) { if ( charges_regen$ > 0.0 ) { this.CreateTimer( 1, charges_regen$ ); } } } event OnGoHandleMessage$( eWorldEvent e$, WorldMessage ) { if ( e$ == WE_PICKED_UP && charges_buyable$ ) { //sanity check if ( owner.Go.Parent == NULL ) { return; } //detect shopkeeper if ( owner.Go.Parent.HasStore() ) { charges_curr$ = charges_max$; SetState Begin$; } } else if ( e$ == event_use$ ) { if ( charges_curr$ > 0 ) { //debug$("charges heard the USE event"); charges_curr$ -= 1; SetState Begin$; } } else if ( e$ == event_recharge$ ) { charges_curr$ = charges_max$; SetState Begin$; } else if ( e$ == event_delete$ ) { if ( charges_curr$ == 0 ) { SetState Exiting$; } } else { //debug$(MakeStringF("charges heard %s", ToString(e$))); } } trigger OnTimer$( 1 ) { charges_curr$ += 1; SetState Begin$; } } State Invalid$ { event OnEnterState$ { report.screen("charges - item had invalid initialization values"); } } State Exiting$ { event OnEnterState$ { //report.screen("charges - item delete"); GoDb.SMarkForDeletion( owner.Goid ); } }