Merge pull request #57033 from lawnjelly/gameplay_monitor_unload
Portals - fix gameplay monitor unloading
This commit is contained in:
commit
c6480e2166
5 changed files with 107 additions and 0 deletions
|
@ -74,6 +74,95 @@ bool PortalGameplayMonitor::_source_rooms_changed(const int *p_source_room_ids,
|
||||||
return source_rooms_changed;
|
return source_rooms_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PortalGameplayMonitor::unload(PortalRenderer &p_portal_renderer) {
|
||||||
|
// First : send gameplay exit signals for any objects still in gameplay
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// lock output
|
||||||
|
VisualServerCallbacks *callbacks = VSG::scene->get_callbacks();
|
||||||
|
callbacks->lock();
|
||||||
|
|
||||||
|
// Remove any movings
|
||||||
|
for (int n = 0; n < _active_moving_pool_ids_prev->size(); n++) {
|
||||||
|
int pool_id = (*_active_moving_pool_ids_prev)[n];
|
||||||
|
PortalRenderer::Moving &moving = p_portal_renderer.get_pool_moving(pool_id);
|
||||||
|
moving.last_gameplay_tick_hit = 0;
|
||||||
|
|
||||||
|
VisualServerCallbacks::Message msg;
|
||||||
|
msg.object_id = VSG::scene->_instance_get_object_ID(moving.instance);
|
||||||
|
msg.type = _exit_callback_type;
|
||||||
|
callbacks->push_message(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any roaming ghosts
|
||||||
|
for (int n = 0; n < _active_rghost_pool_ids_prev->size(); n++) {
|
||||||
|
int pool_id = (*_active_rghost_pool_ids_prev)[n];
|
||||||
|
PortalRenderer::RGhost &moving = p_portal_renderer.get_pool_rghost(pool_id);
|
||||||
|
moving.last_gameplay_tick_hit = 0;
|
||||||
|
|
||||||
|
VisualServerCallbacks::Message msg;
|
||||||
|
msg.object_id = moving.object_id;
|
||||||
|
msg.type = VisualServerCallbacks::CALLBACK_NOTIFICATION_EXIT_GAMEPLAY;
|
||||||
|
callbacks->push_message(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rooms
|
||||||
|
for (int n = 0; n < _active_room_ids_prev->size(); n++) {
|
||||||
|
int room_id = (*_active_room_ids_prev)[n];
|
||||||
|
VSRoom &room = p_portal_renderer.get_room(room_id);
|
||||||
|
room.last_gameplay_tick_hit = 0;
|
||||||
|
|
||||||
|
VisualServerCallbacks::Message msg;
|
||||||
|
msg.object_id = room._godot_instance_ID;
|
||||||
|
msg.type = _exit_callback_type;
|
||||||
|
callbacks->push_message(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoomGroups
|
||||||
|
for (int n = 0; n < _active_roomgroup_ids_prev->size(); n++) {
|
||||||
|
int roomgroup_id = (*_active_roomgroup_ids_prev)[n];
|
||||||
|
VSRoomGroup &roomgroup = p_portal_renderer.get_roomgroup(roomgroup_id);
|
||||||
|
roomgroup.last_gameplay_tick_hit = 0;
|
||||||
|
|
||||||
|
VisualServerCallbacks::Message msg;
|
||||||
|
msg.object_id = roomgroup._godot_instance_ID;
|
||||||
|
msg.type = _exit_callback_type;
|
||||||
|
callbacks->push_message(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static Ghosts
|
||||||
|
for (int n = 0; n < _active_sghost_ids_prev->size(); n++) {
|
||||||
|
int id = (*_active_sghost_ids_prev)[n];
|
||||||
|
VSStaticGhost &ghost = p_portal_renderer.get_static_ghost(id);
|
||||||
|
ghost.last_gameplay_tick_hit = 0;
|
||||||
|
|
||||||
|
VisualServerCallbacks::Message msg;
|
||||||
|
msg.object_id = ghost.object_id;
|
||||||
|
msg.type = VisualServerCallbacks::CALLBACK_NOTIFICATION_EXIT_GAMEPLAY;
|
||||||
|
callbacks->push_message(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// unlock
|
||||||
|
callbacks->unlock();
|
||||||
|
|
||||||
|
// Clear all remaining data
|
||||||
|
for (int n = 0; n < 2; n++) {
|
||||||
|
_active_moving_pool_ids[n].clear();
|
||||||
|
_active_rghost_pool_ids[n].clear();
|
||||||
|
_active_room_ids[n].clear();
|
||||||
|
_active_roomgroup_ids[n].clear();
|
||||||
|
_active_sghost_ids[n].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
_source_rooms_prev.clear();
|
||||||
|
|
||||||
|
// Lets not reset this just in case because it may be possible to have a moving outside the room system
|
||||||
|
// which is preserved between levels, and has a stored gameplay tick. And with uint32_t this should take
|
||||||
|
// a *long* time to rollover... (828 days?). And I don't think a rollover would actually cause a problem in practice.
|
||||||
|
// But can revisit this in the case of e.g. servers running continuously.
|
||||||
|
// We could alternatively go through all movings (not just active) etc and reset the last_gameplay_tick_hit to 0.
|
||||||
|
// _gameplay_tick = 1;
|
||||||
|
}
|
||||||
|
|
||||||
void PortalGameplayMonitor::set_params(bool p_use_secondary_pvs, bool p_use_signals) {
|
void PortalGameplayMonitor::set_params(bool p_use_secondary_pvs, bool p_use_signals) {
|
||||||
_use_secondary_pvs = p_use_secondary_pvs;
|
_use_secondary_pvs = p_use_secondary_pvs;
|
||||||
_use_signals = p_use_signals;
|
_use_signals = p_use_signals;
|
||||||
|
|
|
@ -43,6 +43,8 @@ class PortalGameplayMonitor {
|
||||||
public:
|
public:
|
||||||
PortalGameplayMonitor();
|
PortalGameplayMonitor();
|
||||||
|
|
||||||
|
void unload(PortalRenderer &p_portal_renderer);
|
||||||
|
|
||||||
// entering and exiting gameplay notifications (requires PVS)
|
// entering and exiting gameplay notifications (requires PVS)
|
||||||
void update_gameplay(PortalRenderer &p_portal_renderer, const int *p_source_room_ids, int p_num_source_rooms);
|
void update_gameplay(PortalRenderer &p_portal_renderer, const int *p_source_room_ids, int p_num_source_rooms);
|
||||||
void set_params(bool p_use_secondary_pvs, bool p_use_signals);
|
void set_params(bool p_use_secondary_pvs, bool p_use_signals);
|
||||||
|
|
|
@ -996,6 +996,7 @@ void PortalRenderer::sprawl_roaming(uint32_t p_mover_pool_id, MovingBase &r_movi
|
||||||
void PortalRenderer::_ensure_unloaded(String p_reason) {
|
void PortalRenderer::_ensure_unloaded(String p_reason) {
|
||||||
if (_loaded) {
|
if (_loaded) {
|
||||||
_loaded = false;
|
_loaded = false;
|
||||||
|
_gameplay_monitor.unload(*this);
|
||||||
|
|
||||||
String str;
|
String str;
|
||||||
if (p_reason != String()) {
|
if (p_reason != String()) {
|
||||||
|
@ -1014,6 +1015,17 @@ void PortalRenderer::_ensure_unloaded(String p_reason) {
|
||||||
|
|
||||||
void PortalRenderer::rooms_and_portals_clear() {
|
void PortalRenderer::rooms_and_portals_clear() {
|
||||||
_loaded = false;
|
_loaded = false;
|
||||||
|
|
||||||
|
// N.B. We want to make sure all the tick counters on movings rooms etc to zero,
|
||||||
|
// so that on loading the next level gameplay entered signals etc will be
|
||||||
|
// correctly sent and everything is fresh.
|
||||||
|
// This is mostly done by the gameplay_monitor, but rooms_and_portals_clear()
|
||||||
|
// will also clear tick counters where possible
|
||||||
|
// (there is no TrackedList for the RoomGroup pool for example).
|
||||||
|
// This could be made neater by moving everything to TrackedPooledLists, but this
|
||||||
|
// may be overkill.
|
||||||
|
_gameplay_monitor.unload(*this);
|
||||||
|
|
||||||
_statics.clear();
|
_statics.clear();
|
||||||
_static_ghosts.clear();
|
_static_ghosts.clear();
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,9 @@ public:
|
||||||
void destroy() {
|
void destroy() {
|
||||||
_rooms.clear();
|
_rooms.clear();
|
||||||
room_id = -1;
|
room_id = -1;
|
||||||
|
|
||||||
|
last_tick_hit = 0;
|
||||||
|
last_gameplay_tick_hit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the expanded aabb allows objects to move on most frames
|
// the expanded aabb allows objects to move on most frames
|
||||||
|
|
|
@ -257,6 +257,7 @@ struct VSRoom {
|
||||||
_secondary_pvs_size = 0;
|
_secondary_pvs_size = 0;
|
||||||
_priority = 0;
|
_priority = 0;
|
||||||
_contains_internal_rooms = false;
|
_contains_internal_rooms = false;
|
||||||
|
last_gameplay_tick_hit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_after_conversion() {
|
void cleanup_after_conversion() {
|
||||||
|
|
Loading…
Reference in a new issue