public void HeartBeat() { if (IsActive) { // tick decayable objects // tick items sold to vendors } // TODO: handle perma-loaded landblocks if (!Permaload && LastActiveTime + UnloadInterval < Timer.CurrentTime) { LandblockManager.AddToDestructionQueue(this); } else { QueueNextHeartBeat(); } }
public void Tick(double currentUnixTime) { actionQueue.RunActions(); var wos = worldObjects.Values.ToList(); // When a WorldObject Ticks, it can end up adding additional WorldObjects to this landblock foreach (var wo in wos) { wo.Tick(currentUnixTime); } // Heartbeat if (lastHeartBeat + heartbeatInterval <= DateTime.UtcNow) { var thisHeartBeat = DateTime.UtcNow; // Decay world objects foreach (var wo in wos) { if (wo.IsDecayable()) { wo.Decay(thisHeartBeat - lastHeartBeat); } } if (!Permaload && lastActiveTime + unloadInterval < thisHeartBeat) { LandblockManager.AddToDestructionQueue(this); } lastHeartBeat = thisHeartBeat; } // Database Save if (lastDatabaseSave + databaseSaveInterval <= DateTime.UtcNow) { SaveDB(); lastDatabaseSave = DateTime.UtcNow; } }
public void Tick(double lastTickDuration, long currentTimeTick) { // Here we'd move server objects in motion (subject to landscape) and do physics collision detection var allworldobj = worldObjects.Values; var allplayers = allworldobj.OfType <Player>().ToList(); UpdateStatus(allplayers.Count); if (IsActive) { var wos = worldObjects.Values.ToList(); foreach (var wo in wos) { wo.Tick(lastTickDuration, currentTimeTick); } } // Heartbeat if (lastHeartBeat + heartbeatInterval <= DateTime.UtcNow) { if (IsActive) { // tick decayable objects ?? Is this still needed now that we've migrated to the new Tick architecture? // tick items sold to vendors ?? Is this still needed now that we've migrated to the new Tick architecture? } // TODO: handle perma-loaded landblocks if (!Permaload && lastActiveTime + unloadInterval < DateTime.UtcNow) { LandblockManager.AddToDestructionQueue(this); } lastHeartBeat = DateTime.UtcNow; } }
public void Tick(double currentUnixTime) { if (monitorsRequireEventStart) { Monitor5m.RegisterEventStart(); Monitor1h.RegisterEventStart(); } else { Monitor5m.ResumeEvent(); Monitor1h.ResumeEvent(); } ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_RunActions); actionQueue.RunActions(); ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_RunActions); ProcessPendingWorldObjectAdditionsAndRemovals(); ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Player_Tick); foreach (var player in players) { player.Player_Tick(currentUnixTime); } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Player_Tick); // When a WorldObject Ticks, it can end up adding additional WorldObjects to this landblock if (!IsDormant) { ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Monster_Tick); while (sortedCreaturesByNextTick.Count > 0) // Monster_Tick() { var first = sortedCreaturesByNextTick.First.Value; // If they wanted to run before or at now if (first.NextMonsterTickTime <= currentUnixTime) { sortedCreaturesByNextTick.RemoveFirst(); first.Monster_Tick(currentUnixTime); sortedCreaturesByNextTick.AddLast(first); // All creatures tick at a fixed interval } else { break; } } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Monster_Tick); } ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_WorldObject_Heartbeat); while (sortedWorldObjectsByNextHeartbeat.Count > 0) // Heartbeat() { var first = sortedWorldObjectsByNextHeartbeat.First.Value; // If they wanted to run before or at now if (first.NextHeartbeatTime <= currentUnixTime) { sortedWorldObjectsByNextHeartbeat.RemoveFirst(); first.Heartbeat(currentUnixTime); InsertWorldObjectIntoSortedHeartbeatList(first); // WorldObjects can have heartbeats at different intervals } else { break; } } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_WorldObject_Heartbeat); ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_GeneratorUpdate); while (sortedGeneratorsByNextGeneratorUpdate.Count > 0) { var first = sortedGeneratorsByNextGeneratorUpdate.First.Value; // If they wanted to run before or at now if (first.NextGeneratorUpdateTime <= currentUnixTime) { sortedGeneratorsByNextGeneratorUpdate.RemoveFirst(); first.GeneratorUpdate(currentUnixTime); //InsertWorldObjectIntoSortedGeneratorUpdateList(first); sortedGeneratorsByNextGeneratorUpdate.AddLast(first); } else { break; } } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_GeneratorUpdate); ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_GeneratorRegeneration); while (sortedGeneratorsByNextRegeneration.Count > 0) // GeneratorRegeneration() { var first = sortedGeneratorsByNextRegeneration.First.Value; //Console.WriteLine($"{first.Name}.Landblock_Tick_GeneratorRegeneration({currentUnixTime})"); // If they wanted to run before or at now if (first.NextGeneratorRegenerationTime <= currentUnixTime) { sortedGeneratorsByNextRegeneration.RemoveFirst(); first.GeneratorRegeneration(currentUnixTime); InsertWorldObjectIntoSortedGeneratorRegenerationList(first); // Generators can have regnerations at different intervals } else { break; } } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_GeneratorRegeneration); // Heartbeat ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Heartbeat); if (lastHeartBeat + heartbeatInterval <= DateTime.UtcNow) { var thisHeartBeat = DateTime.UtcNow; ProcessPendingWorldObjectAdditionsAndRemovals(); // Decay world objects if (lastHeartBeat != DateTime.MinValue) { foreach (var wo in worldObjects.Values) { if (wo.IsDecayable()) { wo.Decay(thisHeartBeat - lastHeartBeat); } } } if (!Permaload) { if (lastActiveTime + dormantInterval < thisHeartBeat) { IsDormant = true; } if (lastActiveTime + unloadInterval < thisHeartBeat) { LandblockManager.AddToDestructionQueue(this); } } //log.Info($"Landblock {Id.ToString()}.Tick({currentUnixTime}).Landblock_Tick_Heartbeat: thisHeartBeat: {thisHeartBeat.ToString()} | lastHeartBeat: {lastHeartBeat.ToString()} | worldObjects.Count: {worldObjects.Count()}"); lastHeartBeat = thisHeartBeat; } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Heartbeat); // Database Save ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Database_Save); if (lastDatabaseSave + databaseSaveInterval <= DateTime.UtcNow) { ProcessPendingWorldObjectAdditionsAndRemovals(); SaveDB(); lastDatabaseSave = DateTime.UtcNow; } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Database_Save); Monitor5m.RegisterEventEnd(); Monitor1h.RegisterEventEnd(); monitorsRequireEventStart = true; if (DateTime.UtcNow - last5mClear >= last5mClearInteval) { Monitor5m.ClearEventHistory(); last5mClear = DateTime.UtcNow; } if (DateTime.UtcNow - last1hClear >= last1hClearInteval) { Monitor1h.ClearEventHistory(); last1hClear = DateTime.UtcNow; } }
public void Tick(double currentUnixTime) { ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_RunActions); actionQueue.RunActions(); ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_RunActions); ProcessPendingWorldObjectAdditionsAndRemovals(); // When a WorldObject Ticks, it can end up adding additional WorldObjects to this landblock ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Player_Tick); foreach (var player in players) { player.Player_Tick(currentUnixTime); } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Player_Tick); ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Monster_Tick); while (sortedCreaturesByNextTick.Count > 0) // Monster_Tick() { var first = sortedCreaturesByNextTick.First.Value; // If they wanted to run before or at now if (first.NextMonsterTickTime <= currentUnixTime) { sortedCreaturesByNextTick.RemoveFirst(); first.Monster_Tick(currentUnixTime); sortedCreaturesByNextTick.AddLast(first); // All creatures tick at a fixed interval } else { break; } } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Monster_Tick); ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_WorldObject_Heartbeat); while (sortedWorldObjectsByNextHeartbeat.Count > 0) // Heartbeat() { var first = sortedWorldObjectsByNextHeartbeat.First.Value; // If they wanted to run before or at now if (first.NextHeartbeatTime <= currentUnixTime) { sortedWorldObjectsByNextHeartbeat.RemoveFirst(); first.Heartbeat(currentUnixTime); InsertWorldObjectIntoSortedHeartbeatList(first); // WorldObjects can have heartbeats at different intervals } else { break; } } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_WorldObject_Heartbeat); ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_GeneratorHeartbeat); while (sortedGeneratorsByNextGeneratorHeartbeat.Count > 0) // GeneratorHeartbeat() { var first = sortedGeneratorsByNextGeneratorHeartbeat.First.Value; // If they wanted to run before or at now if (first.NextGeneratorHeartbeatTime <= currentUnixTime) { sortedGeneratorsByNextGeneratorHeartbeat.RemoveFirst(); first.GeneratorHeartbeat(currentUnixTime); InsertWorldObjectIntoSortedGeneratorHeartbeatList(first); // Generators can have heartbeats at different intervals } else { break; } } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_GeneratorHeartbeat); // Heartbeat ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Heartbeat); if (lastHeartBeat + heartbeatInterval <= DateTime.UtcNow) { var thisHeartBeat = DateTime.UtcNow; ProcessPendingWorldObjectAdditionsAndRemovals(); // Decay world objects foreach (var wo in worldObjects.Values) { if (wo.IsDecayable()) { wo.Decay(thisHeartBeat - lastHeartBeat); } } if (!Permaload && lastActiveTime + unloadInterval < thisHeartBeat) { LandblockManager.AddToDestructionQueue(this); } lastHeartBeat = thisHeartBeat; } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Heartbeat); // Database Save ServerPerformanceMonitor.ResumeEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Database_Save); if (lastDatabaseSave + databaseSaveInterval <= DateTime.UtcNow) { ProcessPendingWorldObjectAdditionsAndRemovals(); SaveDB(); lastDatabaseSave = DateTime.UtcNow; } ServerPerformanceMonitor.PauseEvent(ServerPerformanceMonitor.MonitorType.Landblock_Tick_Database_Save); }