@@ -176,7 +176,27 @@ void CALifeGraphRegistry::add(CSE_ALifeDynamicObject* object, GameGraph::_GRAPH_
176176 if (!object->m_bOnline && object->used_ai_locations () /* *&& object->interactive()**/ )
177177 {
178178 VERIFY (ai ().game_graph ().valid_vertex_id (game_vertex_id));
179- m_objects[game_vertex_id].objects ().add (object->ID , object);
179+ OBJECT_REGISTRY& target = m_objects[game_vertex_id].objects ();
180+ const auto & target_map = target.objects ();
181+ const auto existing_at_target = target_map.find (object->ID );
182+ const bool already_registered_here =
183+ (existing_at_target != target_map.end () && existing_at_target->second == object);
184+
185+ if (!already_registered_here)
186+ {
187+ const GameGraph::_GRAPH_ID vertex_count = (GameGraph::_GRAPH_ID)m_objects.size ();
188+ for (GameGraph::_GRAPH_ID i = 0 ; i < vertex_count; ++i)
189+ {
190+ if (!ai ().game_graph ().valid_vertex_id (i))
191+ continue ;
192+ OBJECT_REGISTRY& reg = m_objects[i].objects ();
193+ const auto & om = reg.objects ();
194+ if (om.find (object->ID ) == om.end ())
195+ continue ;
196+ reg.remove (object->ID , true );
197+ }
198+ target.add (object->ID , object);
199+ }
180200 object->m_tGraphID = game_vertex_id;
181201 }
182202 else if (!m_level && update)
@@ -191,6 +211,7 @@ void CALifeGraphRegistry::add(CSE_ALifeDynamicObject* object, GameGraph::_GRAPH_
191211
192212void CALifeGraphRegistry::remove (CSE_ALifeDynamicObject* object, GameGraph::_GRAPH_ID game_vertex_id, bool update)
193213{
214+ bool removed_from_graph = false ;
194215 if (object->used_ai_locations () /* *&& object->interactive()**/ )
195216 {
196217#ifdef DEBUG
@@ -200,8 +221,51 @@ void CALifeGraphRegistry::remove(CSE_ALifeDynamicObject* object, GameGraph::_GRA
200221 game_vertex_id);
201222 }
202223#endif
203- m_objects[game_vertex_id].objects ().remove (object->ID );
224+ if (ai ().game_graph ().valid_vertex_id (game_vertex_id))
225+ {
226+ OBJECT_REGISTRY& primary = m_objects[game_vertex_id].objects ();
227+ const auto & primary_map = primary.objects ();
228+ if (primary_map.find (object->ID ) != primary_map.end ())
229+ {
230+ primary.remove (object->ID );
231+ removed_from_graph = true ;
232+ }
233+ }
234+ if (!removed_from_graph)
235+ {
236+ const GameGraph::_GRAPH_ID vertex_count = (GameGraph::_GRAPH_ID)m_objects.size ();
237+ for (GameGraph::_GRAPH_ID i = 0 ; i < vertex_count; ++i)
238+ {
239+ if (!ai ().game_graph ().valid_vertex_id (i))
240+ continue ;
241+ if (i == game_vertex_id)
242+ continue ;
243+ OBJECT_REGISTRY& reg = m_objects[i].objects ();
244+ const auto & om = reg.objects ();
245+ if (om.find (object->ID ) == om.end ())
246+ continue ;
247+ reg.remove (object->ID );
248+ removed_from_graph = true ;
249+ #ifndef MASTER_GOLD
250+ Msg (" ! [ALife] graph registry: object [%s][%d] was at vertex %u, not at m_tGraphID %u — removed from "
251+ " actual vertex" ,
252+ object->name_replace (), object->ID , i, game_vertex_id);
253+ #endif
254+ break ;
255+ }
256+ }
257+ #ifndef MASTER_GOLD
258+ if (!removed_from_graph)
259+ Msg (" ! [ALife] graph registry: remove [%s][%d] — not in any vertex map (expected %u), continuing" ,
260+ object->name_replace (), object->ID , game_vertex_id);
261+ #endif
204262 }
205263 if (update && m_level)
206- level ().remove (object, ai ().game_graph ().vertex (game_vertex_id)->level_id () != level ().level_id ());
264+ {
265+ bool level_no_assert =
266+ ai ().game_graph ().vertex (game_vertex_id)->level_id () != level ().level_id ();
267+ if (object->used_ai_locations () && !removed_from_graph)
268+ level_no_assert = true ;
269+ level ().remove (object, level_no_assert);
270+ }
207271}
0 commit comments