Page 1 of 1

its me again: script a countdown

PostPosted: Wed Apr 12, 2006 10:59 am
Author: girlysprite
Well, Im building a dungeon now, and i need some scripts...and I dont know how to set it up exactly...

In the dungeon, when the player steps over a certain trigger, a count down starts. Making a countdown isnt so hard...its an onenter script, run only once per game, and has a lot of delayaction in it to show some lines for the countdown.

The problem is that I want to make a device to make the countdown stop. As soon the player uses the device, the counting should stop.
I dont even know if I can stop a script in the middle of its workings, so maybe I should do something else.

How can I set up a countdown that can be canceled?

PostPosted: Wed Apr 12, 2006 11:11 am
Author: Alphonse
create a stop variable.

set the variable using the usable item

have the countdown check the variable each time it counts down, and break out of the loop if it is set.

PostPosted: Wed Apr 12, 2006 11:14 am
Author: girlysprite
hm, loops it is then.
No idea how to make a loop in nwscript yet, though I know how such a loop should be structured.... Ill dive in the lexicon.

PostPosted: Wed Apr 12, 2006 12:37 pm
Author: Jonezie
There's a couple of approaches you could try.

The first is to use the heartbeat event on a particular object to increment the timer, unless the 'stop' variable is set.

The second is to have the trigger execute a repeating script, that breaks when the variable is set. Something like this cheap and nasty snippet:

Code: Select all
    object oArea = GetArea(OBJECT_SELF);
    int iCounter = GetLocalInt(oArea, "Counter");

    if (!GetLocalInt(oArea, "Count_Stop"))
    {
        SetLocalInt(oArea, "Counter", iCounter + 1);
        DelayCommand(1.0, ExectuteScript("ThisScript", OBJECT_SELF));
    }

That says, basically, if the stop variable isn't set, increment the counter and execute this script again in one second.

Note: This sort of stuff is fine for running in a single-player mod, but I have it on good authority that having a bunch of delaycommands active in a big multiplayer mod is not a good thing. I hope that gives you some clues.

PostPosted: Wed Apr 12, 2006 1:04 pm
Author: girlysprite
Thanks all.

It's a single player module. So thats one less problem.
With help from Al and some other boards I managed to get some code together...

here is the basics:

// ** OnEnter handle of the appropriate area/trigger.

// ** FUNCTION DECLARATIONS ** //
void Countdown( int nTimeLimit, object oObject = OBJECT_INVALID);

void main()
{
// Declare variables:
object oPC = GetEnteringObject();
// Check that the entering object is a player character and
// that the LocalInt, "bDoOnce", has not been set:
if( !GetIsPC( oPC) || GetLocalInt( OBJECT_SELF, "bDoOnce")) { return;}
// Initiate the countdown:
// Note: The number determines the length of the
// countdown in seconds; you can change it to
// whatever you want. Moreover, delete oPC if you
// don't want to display a countdown for the last
// X seconds.
Countdown( 15, oPC);
// Flag the LocalInt, "bDoOnce", as TRUE so the countdown
// won't start if the player re-enters the area/trigger:
SetLocalInt( OBJECT_SELF, "bDoOnce", TRUE);
}

// ** FUNCTION DEFINITIONS ** //
void Countdown( int nTimeLimit, object oObject = OBJECT_INVALID)
{
// Declare variables:
// Note: Insert the tag of the object you want the player
// to use where indicted.
int bUsed = GetLocalInt( GetObjectByTag( "TAG_OF_OBJECT_HERE"), "bUsed");
// Return if the LocalInt, "bUsed", has been set:
if( bUsed) { return;}
// If the time limit has been exhausted...
if( nTimeLimit == 0) {
// ** WHATEVER YOU WANT TO HAPPEN WHEN THE TIMER ENDS ** //
// Delete the LocalInt, "bDoOnce", so the player can repeat
// the timed task by re-entering the area/trigger:
// Note: Comment out this line if you don't want the
// player to be able to repeat the task in the event
// they fail.
DeleteLocalInt( OBJECT_SELF, "bDoOnce");
// Otherwise...
} else {
// ...inform the player if they have less than or equal to
// 10 seconds remaining...
// Note: This number can be changed.
if( GetIsObjectValid( oObject) && nTimeLimit <= 10) {
FloatingTextStringOnCreature( IntToString( nTimeLimit), oObject);
}
// ...and continue with the countdown:
DelayCommand( 1.0, Countdown( --nTimeLimit, oObject));
}
}


and the great thing is...it works! :D

It isnt on heartbeat, because I dont trust heartbeat too much ;) and besides, its a loop that needs to be done every second, not every 6 seconds.

PostPosted: Wed Apr 12, 2006 1:43 pm
Author: PlasmaJohn
Code: Select all
if( nTimeLimit == 0 ) { ....

I prefer to be a bit more defensive:
Code: Select all
if( nTimeLimit <= 0 ) { ...

On the off chance that something else is mucking with your variables, this at least makes sure it will terminate :D