View previous topic :: View next topic |
Author |
Message |
fgetce
Joined: 04 Jun 2006 Posts: 23
|
Posted: Wed Sep 06, 2006 0:08 Post subject: Query: DelayCommand? |
|
|
I am using a DelayCommand loop on a script to log individual player character locations in the PW, that fires every two minutes. Would anyone consider that time delay to be to long, to short or just about right? What would be the performance of the server if it was 1 minute intervals?
Also how many DelayCommand loops is exceptable on a player character before your robbing performance of a beefy machine?
I was thinking of adding a food and drink script through a DelayCommand loop after player login. Run it every 3 minutes to first select their current values see if they are above 0, than update each column and reduce it by two for that character and display the new value to the player with some text. If below 50 but greater than 25 inform them they are hungry/parched, if 25 or below they are starving/thirsty. If either on of them are at zero inform player they are suffering from starvation/dehydration and they take one hitpoint in damage for every 3 minutes they go without (a total of 2 hitpoints per 3 minutes for being both hungry and thirsty).
Finally must I specifically kill any DelayCommand loop scripts that may be running on a character when they logout, or are any such scripts auto terminated? |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Wed Sep 06, 2006 8:07 Post subject: |
|
|
Delaycommand loops, or psuedoheartbeats, are about 5 times as intensive as actual heartbeats that do the exact same thng. Instead of a looping delay, use a mod heartbeat with time checks. This has the added advantage of not adding extra delaycommands to the stack, as well. For instance:
Code: |
#include "aps_include"
object FindAddressee(string sPlayername)
{
string sCheck;
object oPC = GetFirstPC();
while (GetIsObjectValid(oPC))
{
sCheck = GetPCPlayerName(oPC);
if (sCheck == sPlayername) return oPC;
oPC = GetNextPC();
}
return OBJECT_INVALID;
}
void main()
{
int nTime = GetLocalInt(OBJECT_SELF,"uptime");
nTime = nTime + 5;//changed from 6 because server firing hb every 5.012 seconds
SetLocalInt(OBJECT_SELF,"uptime", nTime);
if (!(nTime%60))
{
string sServer = GetLocalString(OBJECT_SELF, "ServerNumber");
string sSQL = "SELECT name, sender, message FROM messages WHERE server = '" + sServer + "'";
string sMessage, sName, sLocalString;
object oAddressee, oPC;
string sSender;
int nCount = 1;
int nX;
object oMod = GetModule();
SQLExecDirect(sSQL);
while(SQLFetch() != SQL_ERROR)
{
sMessage = SQLDecodeSpecialChars(SQLGetData(3));
sName = SQLDecodeSpecialChars(SQLGetData(1));
sSender = SQLDecodeSpecialChars(SQLGetData(2));
PrintString(sMessage+sName+sSender);
if (sName == "None") AssignCommand(oMod, SpeakString(sMessage, TALKVOLUME_SHOUT));
else
{
oAddressee = FindAddressee(sName);
if (GetIsObjectValid(oAddressee))
{
FloatingTextStringOnCreature("<c þ >Interserver message received from " + sSender + "!</c>", oAddressee, FALSE);
SendMessageToPC(oAddressee, "<c þ >" + sMessage + "</c>");
}
}
}
sSQL = "DELETE FROM messages WHERE server = '" + sServer + "'";
SQLExecDirect(sSQL);
}
}
|
That does a check once a minute. You could easily stagger it, with other commands, if you wanted, with any number of variations.
Funky |
|
Back to top |
|
|
fgetce
Joined: 04 Jun 2006 Posts: 23
|
Posted: Wed Sep 06, 2006 17:50 Post subject: Please validate logic |
|
|
Alright than, something like this?
Code: |
#include "aps_include"
#include "survival"
#include "pclocation"
void main()
{
int nTime = GetLocalInt(OBJECT_SELF,"uptime");
nTime = nTime + 5
SetLocalInt(OBJECT_SELF,"uptime", nTime); //This will store it under the identity of the module correct?
if (!(nTime%60)) //This checks to see if value is evenly divisable by 60?
{
//If divisable by 60, loop through players logged in and call survial function and pclocation function for each PC in the loop
}
}
|
Plus onModuleLoad should I start the local integer?
Put somewhere in my module start script something like...
Code: |
SetLocalInt(OBJECT_SELF,"uptime", 0);
|
Or will the call to and set function in the heartbeat start with 0 for the value if there isn't anything to begin with? |
|
Back to top |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Thu Sep 07, 2006 6:35 Post subject: |
|
|
Ints are always auto-initialized at 0 by nwscript. Strings starts as "".
the % is the remainder function. If there is any remainder it returns it. 70%60 = 10. If there is any remainder, then nTime%60 will not be zero, it will be TRUE. Then !(nTime%60) will be FALSE. Any nonzero number is true, zero is FALSE.
So if a number is divisible by 60, that if statement returns TRUE and runs the code. Otherwise, nothing happens. If you need to stagger firinings for whatever reason, add a second clause, something like:
else if (!((nTime+30)%60))
That'd fire every minute as well, but 30 seconds after the first. The math in the checks is simple, and none of the code in the if statements is evaluated if they don't return TRUE, making the heartbeat very low profile.
HTH, and feel free to ask any other questions you may have.
Funky |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|