PDA

View Full Version : Make time available to quests


Knightly
01-14-2008, 07:51 PM
In the world building thread for the PEQ database (http://www.eqemulator.net/forums/showthread.php?t=23534) Angelox said:

Something like a new variable called $time would be nice. (if $time >=800 and <=1900, then it would be day time, or you could say , if $time==1936 , you could spawn some mob and start something )- $time would just return the current EqEmu time.

Which I thought was a good idea. I also don't like running shifts.pl outside of the emulator to take care of the day/night shift. Therefore I added two variables to my quests: $zonehour and $zonemin which return the hour and minute respectively. Similarly, I created $zonetime to return the time in military time as above. However, I'm not sure if the $zonetime calculation would be better off in the .pl script where you need it vs the .cpp (since it's really a calculation using the two variables I've already given quests access to). I'm not good at benchmarking so if putting it in the .pl each time it is better than putting it in the .cpp, let me know.

To make this change you'll need to open zone\embparser.cpp and find the following:
if (zone) {
// SCORPIOUS2K- added variable zoneid
ExportVar(packagename.c_str(), "zoneid", zone->GetZoneID());
ExportVar(packagename.c_str(), "zoneln", zone->GetLongName());
ExportVar(packagename.c_str(), "zonesn", zone->GetShortName());
}

Changing it to the following will give you the three variables I mentioned above:
if (zone) {
// SCORPIOUS2K- added variable zoneid
ExportVar(packagename.c_str(), "zoneid", zone->GetZoneID());
ExportVar(packagename.c_str(), "zoneln", zone->GetLongName());
ExportVar(packagename.c_str(), "zonesn", zone->GetShortName());
TimeOfDay_Struct eqTime;
zone->zone_time.getEQTimeOfDay( time(0), &eqTime);
ExportVar(packagename.c_str(), "zonehour", eqTime.hour - 1);
ExportVar(packagename.c_str(), "zonemin", eqTime.minute);
ExportVar(packagename.c_str(), "zonetime", (eqTime.hour - 1) * 100 + eqTime.minute);
}

To test this, I used templates\Priest_of_Discord.pl and added the following to sub EVENT_SAY:
if($text=~/time/i){
quest::say("The hour is currently $zonehour , the minute is currently $zonemin and the time is currently $zonetime .");
}

I then created a macro with:
#time
/say time
/time

And went and talked to the POD. Here's what happened:
You say, '#time'
To set the Time: #time HH [MM]
It is now 01:03pm (Timzeone: 0h 0m).
You say, 'time'
Priest of Discord says 'The hour is currently 13 , the minute is currently 3 and the time is currently 1303 .'
Game Time: Sunday, January 01, 3100 - 1PM

Keep in mind that I have already applied my other fix for #time to make it match for /time so if you haven't used the code from http://www.eqemulator.net/forums/showthread.php?t=24108 then #time will be one hour off of /time.

At any rate, since this lets us use $zonetime in quests, we can replace the (PEQ & AX Quests) kithicor\20250.pl:
if ($shifter==20) { #start night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(20,0);
}
elsif ($shifter==21){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(21,0);
}
elsif ($shifter==22){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(22,0);
}
elsif ($shifter==23){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(23,0);
}
elsif ($shifter==24){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(24,0);
}
elsif ($shifter==1){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(1,0);
}
elsif ($shifter==2){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(2,0);
}
elsif ($shifter==3){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(3,0);
}
elsif ($shifter==4){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(4,0);
}
elsif ($shifter==5){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(5,0);
}
elsif ($shifter==6){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(6,0);
}
elsif ($shifter==7){ #night spawn
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
quest::settime(7,0);
}
elsif ($shifter==8){ #start day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(8,0);
}
elsif ($shifter==9){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(9,0);
}
elsif ($shifter==10){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(10,0);
}
elsif ($shifter==11){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(11,0);
}
elsif ($shifter==12){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(12,0);
}
elsif ($shifter==13){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(13,0);
}
elsif ($shifter==14){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(14,0);
}
elsif ($shifter==15){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(15,0);
}
elsif ($shifter==16){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(16,0);
}
elsif ($shifter==17){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(17,0);
}
elsif ($shifter==18){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(18,0);
}
elsif ($shifter==19){ #day spawn
quest::spawn_condition(kithicor,2,1);
quest::spawn_condition(kithicor,1,0);
quest::settime(19,0);
}

With (this assumes 8pm is night and 8am is day):
if ($zonetime < 800 || $zonetime > 1999) {
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
}
else {
quest::spawn_condition(kithicor,2,1); #live are 2
quest::spawn_condition(kithicor,1,0); #undead are 1
}

There's two places in that file where this occurs: EVENT_SPAWN and EVENT_ENTER.

Now, just so you're aware, there's one thing that Angelox's shifter does that this won't do and that's synchronize the time for dynamic zones.

Knightly
01-14-2008, 08:42 PM
Now, just so you're aware, there's one thing that Angelox's shifter does that this won't do and that's synchronize the time for dynamic zones.

I could have sworn that while I was testing, I went into a dynamic zone and the clock had reset itself to 8:00am. However, now I can't seem to make it do it again...maybe I was dreaming.

So_1337
01-15-2008, 02:27 AM
You know, this is exactly the sort of thing I've been stuck with in regards to the Greenmist quest line. I knocked out all but two of the quests, and was trying to figure out a good way to work Tracker Azeal for the fifth quest. He goes patrolling (depops, a new version pops instantly, and starts pathing) at 9 PM game time, but I couldn't find a way to tie Angelox's time code in to him.

This would be incredibly helpful stuff, because I've been hesitant to implement a work-around of any kind, and then have it become completely obsolete once someone figured out how to get time and quests working together... And it seems you have! :)

You and Angelox have really put together some great work on time recently, and I hope this all gets implemented soon. Keep it up!

Angelox
01-15-2008, 11:26 AM
That script you are looking at does two things: spawns night or day creatures and sets the zone time. The full 20250.pl script is broken in three parts;EVENT_SPAWN- set time on zone boot/spawn, and spawn the proper NPCs . Next, I had set invisible "Watcher" NPC's in key areas around the zone that check $shifter when there's PC movement (EVENT_ENTER and EVENT_EXIT), they update what NPCs should be up.

What you have is very good and needed, my shifter scripts are sort of a hack to satisfy what I want. They work fine, but should be merged into the code.
I think for this, we need two things to work;

1st and most important> Time always be synchronized across the zones, even dynamic: when a dynamic zone loads and a static zone says it 1:00pm, then the dynamic zone needs to catch that and set the same time - there should be some sort of "main time" that starts at EQ8:00am on EqEmu boot up, regardless if we have statics or not. Another words, when a static loads, it looks at this "central time" and synchronizes with it. This way, if a zone reboots (static or not), it finds the proper time again. The shifter scripts already do this, but in a rather awkward way - so awkward to me (and I made them), I thought was too stupid to mention, so I kept it to myself tell Cavedude saw and liked.

2nd > "Central time" will always have a variable available for time checks via Perl scripts ($zonetime).

If you all could create a Central time that applies on zone boot up to any zone (dynamic or not), then all we would need for day and night creatures is something like you said;
if ($zonetime < 800 || $zonetime > 1999) {
quest::spawn_condition(kithicor, 2,0); #live are 2
quest::spawn_condition(kithicor, 1,1); #undead are 1
}
else {
quest::spawn_condition(kithicor,2,1); #live are 2
quest::spawn_condition(kithicor,1,0); #undead are 1
}

And even the above code could be debatable if needed; you could create a general setting in spawn2 table, that would define night or day npcs, and you know the rest.

Also, there's many more watchers across the zones - look in "server/quests/templates" there are the PoD and Nexus_Scion scripts which end in this;
# Night and Day checker
#Angelox's
#This script will re-sync zone time
sub EVENT_SPAWN {
if ($shifter==20) {quest::settime(20,0);}
elsif ($shifter==21){quest::settime(21,0);}
elsif ($shifter==22){quest::settime(22,0);}
elsif ($shifter==23){quest::settime(23,0);}
elsif ($shifter==24){quest::settime(24,0);}
elsif ($shifter==1){quest::settime(1,0);}
elsif ($shifter==2){quest::settime(2,0);}
elsif ($shifter==3){quest::settime(3,0);}
elsif ($shifter==4){quest::settime(4,0);}
elsif ($shifter==5){quest::settime(5,0);}
elsif ($shifter==6){quest::settime(6,0);}
elsif ($shifter==7){quest::settime(7,0);}
elsif ($shifter==8){quest::settime(8,0);}
elsif ($shifter==9){quest::settime(9,0);}
elsif ($shifter==10){quest::settime(10,0);}
elsif ($shifter==11){quest::settime(11,0);}
elsif ($shifter==12){quest::settime(12,0);}
elsif ($shifter==13){quest::settime(13,0);}
elsif ($shifter==14){quest::settime(14,0);}
elsif ($shifter==15){quest::settime(15,0);}
elsif ($shifter==16){quest::settime(16,0);}
elsif ($shifter==17){quest::settime(17,0);}
elsif ($shifter==18){quest::settime(18,0);}
elsif ($shifter==19){quest::settime(19,0); }
}

This applies to any zone with a Nexus Scion or PoD.

Knightly
01-15-2008, 11:31 AM
I listed all of the "watchers" in my other thread about time, so I didn't repeat them here. I was using the kith one as an example.

Can you give me the conditions that a zone comes up with the wrong time? I was trying to reproduce it, but on my server the dynamic zones keep coming up with the same time as my static zones. I mentioned it above because I could have sworn this wasn't the case, that my Kith was coming up at 8:00am regardless of my static zones...but that didn't happen last night while testing.

Angelox
01-15-2008, 11:37 AM
It's a freak thing, I've seen it happen too - I think it might be the client not updating properly , usually I can zone into a "watcher" zone and back, and it sets. if you use AX_PEQ database there are a few POD scripts in the zone that shouldn't be there, in NK, there was a Nexus Scion script that was voiding or confusing the one in templates. I've also seen zones sync time with no scripts running in there (zone to Harbingers spire after zoning to a scripted zone, I saw that there)

Knightly
01-17-2008, 06:16 AM
I did some testing on the "time sync" issue and modified the code for testing. My initial thoughts were that it was due to "gottime" still being true when a zone booted up. However, I had an error in my logic on my first test and ended up adding a bunch of other tests to check the server packets. Turns out, I was right originally.

The reason that the sync doesn't update properly for dynamic zones is because sometimes a dynamic zone comes up in a place where gottime is actually "true" even though it shouldn't be for that zone. (gottime gets set to false when a zone shuts down).

For testing I changed zone.cpp to:
void Zone::GetTimeSync()
{
LogFile->write(EQEMuLog::Status, "KNIGHTLY -- The value of gottime is %s", gottime ? "true" : "false");
if (worldserver.Connected() && !gottime) {
LogFile->write(EQEMuLog::Status, "KNIGHTLY -- Building Time Sync Packet");
ServerPacket* pack = new ServerPacket(ServerOP_GetWorldTime, 0);
LogFile->write(EQEMuLog::Status, "KNIGHTLY -- Sending Time Sync Packet");
worldserver.SendPacket(pack);
LogFile->write(EQEMuLog::Status, "KNIGHTLY -- Deleting Time Sync Packet");
safe_delete(pack);
LogFile->write(EQEMuLog::Status, "KNIGHTLY -- All done with Time Sync Packet");
}
}

Now all of the information we need regarding what's going on is stored in the log files. NOTE: If I planned on keeping this code in, there would need to be debug logic rather than just writing it to the normal log. However, since I was just trying to track this one issue down, there's no reason to put in all the debug logic.

I then zoned from neriakc to neriakb to neriaka to nektulos (all dynamic for my testing). NeriakC was the first zone to come up:
---------------------------------------------
[01.17. - 07:38:27] Starting Log: logs/eqemu_zone_17164.log
[01.17. - 07:38:27] Using database 'ProjectEQ' at localhost:3306
[01.17. - 07:38:27] EMuShareMem loaded
[01.17. - 07:39:49] Booting neriakc
[01.17. - 07:39:49] Loading spawn conditions...
[01.17. - 07:39:49] Loading static zone points...
[01.17. - 07:39:49] Loading spawn groups...
[01.17. - 07:39:49] Loading spawn2 points...
[01.17. - 07:39:49] Loading player corpses...
[01.17. - 07:39:49] Loading traps...
[01.17. - 07:39:49] Loading ground spawns...
[01.17. - 07:39:49] Loading Ground Spawns from DB...
[01.17. - 07:39:49] Loading World Objects from DB...
[01.17. - 07:39:49] Loading Objects from DB...
[01.17. - 07:39:49] Loading doors for neriakc ...
[01.17. - 07:39:49] Loading Doors from database...
[01.17. - 07:39:49] Loading AA information...
[01.17. - 07:39:49] Loading Merchant Lists...
[01.17. - 07:39:49] Loading Temporary Merchant Lists...
[01.17. - 07:39:49] Successfully loaded Zone Config.
[01.17. - 07:39:49] Loading timezone data...
[01.17. - 07:39:49] Init Finished: ZoneID = 42, Time Offset = 0
---------------------------------------------
[01.17. - 07:39:49] Starting Log: logs/eqemu_zone_17164.log
[01.17. - 07:39:49] ---- Zone server neriakc, listening on port:7004 ----
[01.17. - 07:39:49] Zone Bootup: neriakc (42)
[01.17. - 07:39:49] KNIGHTLY -- The value of gottime is true
[01.17. - 07:40:31] Zoning 'Testers' to: neriakb (41) x=-499.910004, y=2.970000, z=-10.250000
[01.17. - 07:40:49] Zone Shutdown: neriakc (42)
[01.17. - 07:40:49] Zone shutdown: going to sleep

Next neriakb came up (and the time did not get set):
---------------------------------------------
[01.17. - 07:38:23] Starting Log: logs/eqemu_zone_17528.log
[01.17. - 07:38:23] Using database 'ProjectEQ' at localhost:3306
[01.17. - 07:38:23] EMuShareMem loaded
[01.17. - 07:40:31] Booting neriakb
[01.17. - 07:40:31] Loading spawn conditions...
[01.17. - 07:40:31] Loading static zone points...
[01.17. - 07:40:31] Loading spawn groups...
[01.17. - 07:40:31] Loading spawn2 points...
[01.17. - 07:40:31] Loading player corpses...
[01.17. - 07:40:31] Loading traps...
[01.17. - 07:40:31] Loading ground spawns...
[01.17. - 07:40:31] Loading Ground Spawns from DB...
[01.17. - 07:40:31] Loading World Objects from DB...
[01.17. - 07:40:31] Loading Objects from DB...
[01.17. - 07:40:31] Loading doors for neriakb ...
[01.17. - 07:40:31] Loading Doors from database...
[01.17. - 07:40:31] Loading AA information...
[01.17. - 07:40:31] Loading Merchant Lists...
[01.17. - 07:40:31] Loading Temporary Merchant Lists...
[01.17. - 07:40:31] Successfully loaded Zone Config.
[01.17. - 07:40:31] Loading timezone data...
[01.17. - 07:40:31] Init Finished: ZoneID = 41, Time Offset = 0
---------------------------------------------
[01.17. - 07:40:31] Starting Log: logs/eqemu_zone_17528.log
[01.17. - 07:40:31] ---- Zone server neriakb, listening on port:7003 ----
[01.17. - 07:40:31] Zone Bootup: neriakb (41)
[01.17. - 07:40:31] KNIGHTLY -- The value of gottime is true
[01.17. - 07:41:08] Zoning 'Testers' to: neriaka (40) x=156.919998, y=-2.940000, z=31.750000
[01.17. - 07:41:34] Zone Shutdown: neriakb (41)
[01.17. - 07:41:34] Zone shutdown: going to sleep

Then I went to neriaka (which was in the same logfile as neriakc) and the time did not get set:
[01.17. - 07:41:08] Booting neriaka
[01.17. - 07:41:08] Loading spawn conditions...
[01.17. - 07:41:08] Loading static zone points...
[01.17. - 07:41:08] Loading spawn groups...
[01.17. - 07:41:08] Loading spawn2 points...
[01.17. - 07:41:08] Loading player corpses...
[01.17. - 07:41:08] Loading traps...
[01.17. - 07:41:08] Loading ground spawns...
[01.17. - 07:41:08] Loading Ground Spawns from DB...
[01.17. - 07:41:08] Loading World Objects from DB...
[01.17. - 07:41:08] Loading Objects from DB...
[01.17. - 07:41:08] Loading doors for neriaka ...
[01.17. - 07:41:08] Loading Doors from database...
[01.17. - 07:41:08] Loading AA information...
[01.17. - 07:41:08] Loading Merchant Lists...
[01.17. - 07:41:08] Loading Temporary Merchant Lists...
[01.17. - 07:41:08] Successfully loaded Zone Config.
[01.17. - 07:41:08] Loading timezone data...
[01.17. - 07:41:08] Init Finished: ZoneID = 40, Time Offset = 0
[01.17. - 07:41:08] ---- Zone server neriaka, listening on port:7004 ----
[01.17. - 07:41:08] Zone Bootup: neriaka (40)
[01.17. - 07:41:08] KNIGHTLY -- The value of gottime is true
[01.17. - 07:43:42] Zoning 'Testers' to: nektulos (25) x=-259.000000, y=-1201.000000, z=-5.000000
[01.17. - 07:43:47] Zone Shutdown: neriaka (40)
[01.17. - 07:43:47] Zone shutdown: going to sleep

And finally, I went to nektulos (which was in the same log file that neriakb was in originally) and the time did get set:
[01.17. - 07:43:42] Booting nektulos
[01.17. - 07:43:42] Loading spawn conditions...
[01.17. - 07:43:42] Loading static zone points...
[01.17. - 07:43:42] Loading spawn groups...
[01.17. - 07:43:42] Loading spawn2 points...
[01.17. - 07:43:42] Loading player corpses...
[01.17. - 07:43:42] Loading traps...
[01.17. - 07:43:42] Loading ground spawns...
[01.17. - 07:43:42] Loading Ground Spawns from DB...
[01.17. - 07:43:42] Loading World Objects from DB...
[01.17. - 07:43:42] Loading Objects from DB...
[01.17. - 07:43:42] Loading doors for nektulos ...
[01.17. - 07:43:42] Loading Doors from database...
[01.17. - 07:43:42] Loading AA information...
[01.17. - 07:43:42] Loading Merchant Lists...
[01.17. - 07:43:42] Loading Temporary Merchant Lists...
[01.17. - 07:43:42] Successfully loaded Zone Config.
[01.17. - 07:43:42] Loading timezone data...
[01.17. - 07:43:42] Init Finished: ZoneID = 25, Time Offset = 0
[01.17. - 07:43:42] ---- Zone server nektulos, listening on port:7003 ----
[01.17. - 07:43:42] Zone Bootup: nektulos (25)
[01.17. - 07:43:42] KNIGHTLY -- The value of gottime is false
[01.17. - 07:43:42] KNIGHTLY -- Building Time Sync Packet
[01.17. - 07:43:42] KNIGHTLY -- Sending Time Sync Packet
[01.17. - 07:43:42] KNIGHTLY -- Deleting Time Sync Packet
[01.17. - 07:43:42] KNIGHTLY -- All done with Time Sync Packet
[01.17. - 07:45:05] Zone Shutdown: nektulos (25)
[01.17. - 07:45:05] Zone shutdown: going to sleep

Note the value of gottime when the zone syncs properly is "false" as it should be. However, on the other zones, the value was true and as such, the server does not attempt to synchronize the time.

There are two ways to go about fixing this. There's the real way, and the Knight way (tm). The real way would be to find out why gottime is true and fix those conditions such that gottime is false when it should be false and true when it should be true.

The Knight way (tm) was to find out how often gottime is being used (appears to be only in the TimeSync stuff); find out how often GetTimeSync is used (appears to be only when the zone is booting up); and just remove the conditional so that the time sync is done whether we have time or not.

Now, after a brief look at the code, this should only cause us to try to sync time when the zone comes up and it should force a sync every time. HOWEVER, I did not run a debug to trace all of the instances of this to make sure that it's not being done too often. I can't help but think the reason that gottime was there was because someone had a problem with the zones repeatedly synchronizing even though they already had synchronized the time.

I won't have any more time to spend on this until next week, so I thought I'd post my findings here in case anyone else wanted to pick up the testing or try to fix the real problem.

Knightly
01-17-2008, 06:17 AM
To remove the conditional for gottime, just change the code in zone.cpp from:
void Zone::GetTimeSync()
{
if (worldserver.Connected() && !gottime) {
ServerPacket* pack = new ServerPacket(ServerOP_GetWorldTime, 0);
worldserver.SendPacket(pack);
safe_delete(pack);
}
}

To:
void Zone::GetTimeSync()
{
if (worldserver.Connected()) {
ServerPacket* pack = new ServerPacket(ServerOP_GetWorldTime, 0);
worldserver.SendPacket(pack);
safe_delete(pack);
}
}

But again, I don't have time to test to see if that causes an egregious amount of time sync'ing or other issues.

Knightly
02-02-2008, 07:09 AM
I've been running the above change (removing the !gottime conditional) since this was posted, except with the addition that I wrote an entry to the log every time that it was used. So, I can now verify that this doesn't cause an inordinate amount of time synchronization and, indeed, keeps all of my dynamic zones in sync with time.

cavedude
02-02-2008, 07:32 AM
I didn't even see that snippet, I'll have to try it out on TGC next time I patch. I know the rest of your submissions are in the official code, but I have yet to find time to play. :(

Angelox
06-27-2008, 08:53 AM
To remove the conditional for gottime, just change the code in zone.cpp from:
void Zone::GetTimeSync()
{
if (worldserver.Connected() && !gottime) {
ServerPacket* pack = new ServerPacket(ServerOP_GetWorldTime, 0);
worldserver.SendPacket(pack);
safe_delete(pack);
}
}

To:
void Zone::GetTimeSync()
{
if (worldserver.Connected()) {
ServerPacket* pack = new ServerPacket(ServerOP_GetWorldTime, 0);
worldserver.SendPacket(pack);
safe_delete(pack);
}
}

But again, I don't have time to test to see if that causes an egregious amount of time sync'ing or other issues.

This change never went into the source, did I miss something - or it just got forgotten?

Derision
06-27-2008, 09:16 AM
It may be the case that the problem described by Knightly is due to the
fact that 'gottime' is not initialised in the zone constructor and therefore
has a random value each time a zone is booted up.

In zone/zone.cpp, Zone::Zone(int32 in_zoneid, const char* in_short_name)

Around line 700:

After:


aas = NULL;
totalAAs = 0;

Add:


gottime = false;

I can't test this, but I'm bored at work and just had a quick look at the code :)

Angelox
06-27-2008, 01:15 PM
I just got back, saw your post. Before i tested , i pulled all "settime" scripts ;
Here's a summary of what happened:
With Knightlys gottime-removal fix, all dynamic zones start at 8pm, then continue to count normally ; all static zones start at 8am.
With Derisions gottime = false; fix, all dynamic zones start at 2:00pm, and continue normally.
so with one they stay 12 hours apart (dynamic vs static) and the other 6.
I stood around a while checked a lot of zones, and times remain stable, but with the mentioned time difference.

ChaosSlayer
06-27-2008, 01:58 PM
can't some sort of GLOBAL server side timer be build INTO server code istelf?

which will start when server itself is started (regardless if any zones have been booted or not) and then ALL zone will read time from that timer

in other words, tie timer to SERVER itself not to any zone in specific

OR as a cheap solution- make zones read time of current PC time and convert into EQ

since eq day is what 2 hours? then 11.30 am will be 6pm game time

Derision
06-27-2008, 02:38 PM
I've been looking at this some more. It appears that when a static zone
loads, it makes the call to GetTimeSync before it is actually connected
to the world server, hence the check for worldserver.connected fails.

Angelox, try this. In zone/worldserver.cpp void WorldServer::OnConnected():

Around line 124, After:


if (ZoneLoaded) {
this->SetZone(zone->GetZoneID());
entity_list.UpdateWho(true);
this->SendEmoteMessage(0, 0, 15, "Zone connect: %s", zone->GetLongName());

Add:


zone->GetTimeSync();

So the whole section of code reads:


if (ZoneLoaded) {
this->SetZone(zone->GetZoneID());
entity_list.UpdateWho(true);
this->SendEmoteMessage(0, 0, 15, "Zone connect: %s", zone->GetLongName());
zone->GetTimeSync();
} else {
this->SetZone(0);
}


I started and stopped my server a couple of times and the time in my 5 dynamic and 1 static were now in sync.

This is purely experimental code :)

Angelox
06-27-2008, 02:56 PM
what about gottime? should I leave as original, Knightly, or your change?

Derision
06-27-2008, 03:04 PM
what about gottime? should I leave as original, Knightly, or your change?

I don't understand why you get different results with Knightly's change or mine, on the face of it they should have the same effect.

I was more interested in why the statics had a different time than dynamics. My 'gottime fix' seems the more 'correct' one to me, but you can try with either.

Angelox
06-27-2008, 03:17 PM
I don't understand why you get different results with Knightly's change or mine, on the face of it they should have the same effect.

I was more interested in why the statics had a different time than dynamics. My 'gottime fix' seems the more 'correct' one to me, but you can try with either.

O well, I already compiled with your "zone->GetTimeSync();" fix and knightlys - I was just wanting to have it the way you wanted it.
BtW, it's working fine, all zones Sync together, static and dynamic. I'll watch it for a while and see i f it stays.
If so, what is "gottime" needed for? seems your insert will render gottime useless?

Derision
06-27-2008, 03:24 PM
If so, what is "gottime" needed for? seems your insert will render gottime useless?

It appears that whoever wrote the code meant the 'gottime' flag to mean that the zone had already synced it's time and didn't need to go to the trouble of sending another TimeSync request packet to world to sync again.

Since GetTimeSync is only called once during zone bootup, it doesn't seem to serve any purpose at present.

Angelox
06-27-2008, 03:50 PM
Well, this fix you made is working - best fix I've seen yet, MUCH better now.
I was just looking at a few old things I did - believe it or not, I hadn't looked at this time thing since I first came out with my "day and night" logic (from a dummies' point of view), sort of got burnt out on it. And now I'm out of work again and at home, so I'm back to learning all this.
Maybe you can find time to make a diff (probably quote out, the "gottime" entries ), see if the Devs can put it in.

Angelox
06-30-2008, 03:02 PM
Here's what I was able to come up with using Knightly's '$zonetime' and Derision's 'zone->GetTimeSync();' fix.
This is the most effective and less intrusive way to spawn the day/night NPCs. This originally was Qadar's idea (use EVENT_WAYPOINT), while we were working on the boat system, I just ported it over to the day/night spawns.
You need one npc, preferably invisible , untrackable, etc. and you need to assign him two waypoints at the same spawnpoint. Example: Lets say I spawned my LakeRathe NPC at 0,0,0 (X,Y,Z); I then make two more grid/waypoints at the same 0,0,0 ( no need to make it move around, it will still move from WP to WP), and give each WP a pausetime of 45. Then comes the script, which I see is different from Knightlys, but probably arrives at the same conclusion , if you just change EVENT_ENTER or EXIT to EVENT_WAYPOINT.
#lakerathe night and day spawns
#Angelox

sub EVENT_WAYPOINT{
if (($zonetime >= 0)&&($zonetime <= 800)){ #nighttime
quest::spawn_condition(lakerathe, 2,0); #live are 2
quest::spawn_condition(lakerathe, 1,1);} #undead are 1
elsif (($zonetime >= 2000)&&($zonetime <= 2359)){ #nighttime
quest::spawn_condition(lakerathe, 2,0); #live are 2
quest::spawn_condition(lakerathe, 1,1);} #undead are 1
else{ #daytime
quest::spawn_condition(lakerathe,2,1);
quest::spawn_condition(lakerathe,1,0);}}
## End spawn Script
Now, the only way this truly works is if you follow Derisions simple instructions for the 'zone->GetTimeSync();' fix, and add the insert - once the insert is in, there will be no need for time syncs, timers, or anything else. All zones will have the same time exactly: static or dynamic. The only thing I saw was, my server will start up at 4:00am instead of the original 8:00am (EQ Time), which is no big deal because it continues on to cycle the 24 hours in all zones.
Here's a pointer on using EVENT_WAYPOINT (Something we figured out while doing the boat work); Although the zone may be static, Perl scripts will not work, unless a PC is there (in the zone) too - This was a big problem with the boats, but solved.
Now that I think of it, I see where I can throw in an EVENT_SPAWN to the above script and that will easily fix any waypoint delays when you first zone in.
This will be the next script to try out;

#lakerathe night and day spawns
#Angelox
sub EVENT_SPAWN{
if (($zonetime >= 0)&&($zonetime <= 800)){ #nighttime
quest::spawn_condition(lakerathe, 2,0); #live are 2
quest::spawn_condition(lakerathe, 1,1);} #undead are 1
elsif (($zonetime >= 2000)&&($zonetime <= 2359)){ #nighttime
quest::spawn_condition(lakerathe, 2,0); #live are 2
quest::spawn_condition(lakerathe, 1,1);} #undead are 1
else{ #daytime
quest::spawn_condition(lakerathe,2,1);
quest::spawn_condition(lakerathe,1,0);}}

sub EVENT_WAYPOINT{
if (($zonetime >= 0)&&($zonetime <= 800)){ #nighttime
quest::spawn_condition(lakerathe, 2,0); #live are 2
quest::spawn_condition(lakerathe, 1,1);} #undead are 1
elsif (($zonetime >= 2000)&&($zonetime <= 2359)){ #nighttime
quest::spawn_condition(lakerathe, 2,0); #live are 2
quest::spawn_condition(lakerathe, 1,1);} #undead are 1
else{ #daytime
quest::spawn_condition(lakerathe,2,1);
quest::spawn_condition(lakerathe,1,0);}}
## End spawn Script
EVENT_SPAWN will instantly set the right spawn when you Zone in, and EVENT_WAYPOINT will keep checks on what mob should be up.

If you use the same NPC i placed for day/night, you only need but one of these spawns attached to the above PL per zone, so you can delete all the other ones, where I used proximity - this should be easy, as I always 'hand spawn' my NPCs under the same spawngroup. In places like Kithicor and Commons, I had put in numerous spawns.