bool CSE_ALifeDynamicObject::synchronize_location () { if (!ai().level_graph().valid_vertex_position(o_Position) || ai().level_graph().inside(ai().level_graph().vertex(m_tNodeID),o_Position)) return (true); u32 const new_vertex_id = ai().level_graph().vertex(m_tNodeID,o_Position); if (!m_bOnline && !ai().level_graph().inside(new_vertex_id, o_Position)) return (true); m_tNodeID = new_vertex_id; GameGraph::_GRAPH_ID tGraphID = ai().cross_table().vertex(m_tNodeID).game_vertex_id(); if (tGraphID != m_tGraphID) { if (!m_bOnline) { Fvector position = o_Position; u32 level_vertex_id = m_tNodeID; alife().graph().change (this,m_tGraphID,tGraphID); if (ai().level_graph().inside(ai().level_graph().vertex(level_vertex_id),position)) { level_vertex_id = m_tNodeID; o_Position = position; } } else { VERIFY (ai().game_graph().vertex(tGraphID)->level_id() == alife().graph().level().level_id()); m_tGraphID = tGraphID; } } m_fDistance = ai().cross_table().vertex(m_tNodeID).distance(); return (true); }
void CSE_ALifeOnlineOfflineGroup::unregister_member (ALife::_OBJECT_ID member_id) { CALifeGraphRegistry &graph = alife().graph(); CALifeLevelRegistry &level = graph.level(); MEMBERS::iterator I = m_members.find(member_id); VERIFY (I != m_members.end()); VERIFY ((*I).second->m_group_id == ID); (*I).second->m_group_id = 0xffff; graph.update ((*I).second); alife().scheduled().add ((*I).second); m_members.erase (I); if (m_members.empty()) { if (!m_bOnline) { graph.remove (this,m_tGraphID); } else { if (ID_Parent == 0xffff) level.remove (this); } m_flags.set (flUsedAI_Locations,FALSE); } }
void CSE_ALifeOnlineOfflineGroup::try_switch_offline () { if (m_members.empty()) return; if (!can_switch_offline()) return; if (!can_switch_online()) { alife().switch_offline (this); return; } MEMBERS::iterator I = m_members.begin(); MEMBERS::iterator E = m_members.end(); for ( ; I != E; ++I) { VERIFY3 ((*I).second->g_Alive(),"Incorrect situation : some of the OnlineOffline group members is dead",(*I).second->name_replace()); VERIFY3 ((*I).second->can_switch_offline(),"Incorrect situation : some of the OnlineOffline group members cannot be switched online due to their personal properties",(*I).second->name_replace()); VERIFY3 ((*I).second->can_switch_online(),"Incorrect situation : some of the OnlineOffline group members cannot be switched online due to their personal properties",(*I).second->name_replace()); if (alife().graph().actor()->o_Position.distance_to((*I).second->o_Position) <= alife().offline_distance()) return; } alife().switch_offline (this); }
void CSE_ALifeOnlineOfflineGroup::register_member (ALife::_OBJECT_ID member_id) { VERIFY (m_members.find(member_id) == m_members.end()); CSE_ALifeDynamicObject *object = ai().alife().objects().object(member_id); CSE_ALifeHumanStalker *stalker = smart_cast<CSE_ALifeHumanStalker*>(object); VERIFY (stalker); VERIFY (stalker->g_Alive()); VERIFY ((stalker->m_group_id == 0xffff) || (stalker->m_group_id == ID)); stalker->m_group_id = ID; bool empty = m_members.empty(); m_members.insert (std::make_pair(member_id,stalker)); if (empty) { o_Position = stalker->o_Position; m_tNodeID = stalker->m_tNodeID; m_tGraphID = stalker->m_tGraphID; m_flags.set (flUsedAI_Locations,TRUE); alife().graph().update (this); } if (!object->m_bOnline) { alife().graph().remove (object,object->m_tGraphID); alife().scheduled().remove (object); } else { VERIFY (object->ID_Parent == 0xffff); alife().graph().level().remove (object); } }
void CSE_ALifeDynamicObject::add_offline (const xr_vector<ALife::_OBJECT_ID> &saved_children, const bool &update_registries) { if (!update_registries) return; alife().scheduled().add (this); alife().graph().add (this,m_tGraphID,false); }
void CSE_ALifeDynamicObject::add_online (const bool &update_registries) { if (!update_registries) return; alife().scheduled().remove (this); alife().graph().remove (this,m_tGraphID,false); }
void CSE_ALifeOnlineOfflineGroup::switch_online () { R_ASSERT (!m_bOnline); m_bOnline = true; MEMBERS::iterator I = m_members.begin(); MEMBERS::iterator E = m_members.end(); for ( ; I != E; ++I) alife().add_online ((*I).second, false); alife().scheduled().remove (this); alife().graph().remove (this,m_tGraphID,false); }
void CSE_ALifeDynamicObject::try_switch_online () { CSE_ALifeSchedulable *schedulable = smart_cast<CSE_ALifeSchedulable*>(this); // checking if the abstract monster has just died if (schedulable) { if (!schedulable->need_update(this)) { if (alife().scheduled().object(ID,true)) alife().scheduled().remove (this); } else if (!alife().scheduled().object(ID,true)) alife().scheduled().add (this); } if (!can_switch_online()) { on_failed_switch_online(); return; } if (!can_switch_offline()) { alife().switch_online (this); return; } if (alife().graph().actor()->o_Position.distance_to(o_Position) > alife().online_distance()) { on_failed_switch_online(); return; } alife().switch_online (this); }
void CSE_ALifeDynamicObject::try_switch_offline () { if (!can_switch_offline()) return; if (!can_switch_online()) { alife().switch_offline (this); return; } if (alife().graph().actor()->o_Position.distance_to(o_Position) <= alife().offline_distance()) return; alife().switch_offline (this); }
bool CSE_ALifeMonsterAbstract::redundant () const { if (g_Alive()) return (false); if (m_bOnline) return (false); if (m_story_id != INVALID_STORY_ID) return (false); if (!m_game_death_time) return (false); ALife::_TIME_ID current_time = alife().time_manager().game_time(); VERIFY2 ( m_game_death_time <= current_time, make_string( "incorrect death time for monster %s[death time = %I64d][current time = %I64d]", name_replace(), m_game_death_time, current_time ) ); if ((m_game_death_time + m_stay_after_death_time_interval) > current_time) return (false); return (true); }
void CSE_ALifeMonsterAbstract::vfCheckForPopulationChanges () { CSE_ALifeGroupAbstract *l_tpALifeGroupAbstract = smart_cast<CSE_ALifeGroupAbstract*>(this); if (!l_tpALifeGroupAbstract || !bfActive() || m_bOnline) return; ai().ef_storage().alife_evaluation(true); ALife::_TIME_ID l_tTimeID = ai().alife().time_manager().game_time(); if (l_tTimeID >= l_tpALifeGroupAbstract->m_tNextBirthTime) { ai().ef_storage().alife().member() = this; l_tpALifeGroupAbstract->m_tNextBirthTime = l_tTimeID + ALife::_TIME_ID(ai().ef_storage().m_pfBirthSpeed->ffGetValue()*24*60*60*1000); if (randF(100) < ai().ef_storage().m_pfBirthProbability->ffGetValue()) { u32 l_dwBornCount = iFloor(float(l_tpALifeGroupAbstract->m_wCount)*randF(.5f,1.5f)*ai().ef_storage().m_pfBirthPercentage->ffGetValue()/100.f + .5f); if (l_dwBornCount) { l_tpALifeGroupAbstract->m_tpMembers.resize(l_tpALifeGroupAbstract->m_wCount + l_dwBornCount); ALife::OBJECT_IT I = l_tpALifeGroupAbstract->m_tpMembers.begin() + l_tpALifeGroupAbstract->m_wCount; ALife::OBJECT_IT E = l_tpALifeGroupAbstract->m_tpMembers.end(); for ( ; I != E; ++I) { CSE_Abstract *l_tpAbstract = alife().create (l_tpALifeGroupAbstract,this); *I = l_tpAbstract->ID; } l_tpALifeGroupAbstract->m_wCount = l_tpALifeGroupAbstract->m_wCount + u16(l_dwBornCount); } } } }
void CSE_ALifeDynamicObject::switch_offline () { R_ASSERT (m_bOnline); m_bOnline = false; alife().remove_online (this); clear_client_data(); }
void CSE_ALifeDynamicObject::on_register () { CSE_ALifeObject *object = this; while (object->ID_Parent != ALife::_OBJECT_ID(-1)) { object = ai().alife().objects().object(object->ID_Parent); VERIFY (object); } if (!alife().graph().level().object(object->ID,true)) clear_client_data(); }
void CSE_ALifeOnlineOfflineGroup::switch_offline () { R_ASSERT (m_bOnline); m_bOnline = false; if (!m_members.empty()) { MEMBER *member = (*m_members.begin()).second; o_Position = member->o_Position; m_tNodeID = member->m_tNodeID; m_tGraphID = member->m_tGraphID; m_fDistance = member->m_fDistance; } MEMBERS::iterator I = m_members.begin(); MEMBERS::iterator E = m_members.end(); for ( ; I != E; ++I) alife().remove_online ((*I).second,false); alife().scheduled().add (this); alife().graph().add (this,m_tGraphID,false); }
void CSE_ALifeDynamicObject::switch_offline () { R_ASSERT (m_bOnline); m_bOnline = false; alife().remove_online (this); #ifdef DEBUG if (!client_data.empty()) Msg ("CSE_ALifeDynamicObject::switch_offline: client_data is cleared for [%d][%s]",ID,name_replace()); #endif // DEBUG if (!keep_saved_data_anyway()) client_data.clear (); }
void CSE_InventoryBox::add_offline (const xr_vector<ALife::_OBJECT_ID> &saved_children, const bool &update_registries) { CSE_ALifeDynamicObjectVisual *object = (this); for (u32 i=0, n=saved_children.size(); i<n; ++i) { CSE_ALifeDynamicObject *child = smart_cast<CSE_ALifeDynamicObject*>(ai().alife().objects().object(saved_children[i],true)); R_ASSERT (child); child->m_bOnline = false; CSE_ALifeInventoryItem *inventory_item = smart_cast<CSE_ALifeInventoryItem*>(child); VERIFY2 (inventory_item,"Non inventory item object has parent?!"); #ifdef DEBUG // if (psAI_Flags.test(aiALife)) // Msg ("[LSS] Destroying item [%s][%s][%d]",inventory_item->base()->name_replace(),*inventory_item->base()->s_name,inventory_item->base()->ID); Msg ( "[LSS][%d] Going offline [%d][%s][%d] with parent [%d][%s] on '%s'", Device.dwFrame, Device.dwTimeGlobal, inventory_item->base()->name_replace(), inventory_item->base()->ID, ID, name_replace(), "*SERVER*" ); #endif ALife::_OBJECT_ID item_id = inventory_item->base()->ID; inventory_item->base()->ID = object->alife().server().PerformIDgen(item_id); if (!child->can_save()) { object->alife().release (child); --i; --n; continue; } #ifdef DEBUG if (!client_data.empty()) Msg ("CSE_InventoryBox::add_offline: client_data is cleared for [%d][%s]",ID,name_replace()); #endif // DEBUG if (!child->keep_saved_data_anyway()) child->client_data.clear (); object->alife().graph().add (child,child->m_tGraphID,false); // object->alife().graph().attach (*object,inventory_item,child->m_tGraphID,true); alife().graph().remove (child,child->m_tGraphID); children.push_back (child->ID); child->ID_Parent = ID; } CSE_ALifeDynamicObjectVisual::add_offline(saved_children, update_registries); }
void CSE_ALifeDynamicObject::try_switch_online () { CSE_ALifeSchedulable *schedulable = smart_cast<CSE_ALifeSchedulable*>(this); // checking if the abstract monster has just died if (schedulable) { if (!schedulable->need_update(this)) { if (alife().scheduled().object(ID,true)) alife().scheduled().remove (this); } else if (!alife().scheduled().object(ID,true)) alife().scheduled().add (this); } if (!can_switch_online()) { #ifdef DEBUG if (!client_data.empty()) Msg ("CSE_ALifeDynamicObject::try_switch_online: client_data is cleared for [%d][%s]",ID,name_replace()); #endif // DEBUG if (!keep_saved_data_anyway()) client_data.clear (); return; } if (!can_switch_offline()) { alife().switch_online (this); return; } if (alife().graph().actor()->o_Position.distance_to(o_Position) > alife().online_distance()) { #ifdef DEBUG if (!client_data.empty()) Msg ("CSE_ALifeDynamicObject::try_switch_online2: client_data is cleared for [%d][%s]",ID,name_replace()); #endif // DEBUG if (!keep_saved_data_anyway()) client_data.clear (); return; } alife().switch_online (this); }
bool CSE_ALifeOnlineOfflineGroup::synchronize_location () { if (m_members.empty()) return (true); MEMBERS::iterator I = m_members.begin(); MEMBERS::iterator E = m_members.end(); for ( ; I != E; ++I) (*I).second->synchronize_location (); MEMBER &member = *(*m_members.begin()).second; o_Position = member.o_Position; m_tNodeID = member.m_tNodeID; if (m_tGraphID != member.m_tGraphID) { if (!m_bOnline) alife().graph().change (this,m_tGraphID,member.m_tGraphID); else m_tGraphID = member.m_tGraphID; } m_fDistance = member.m_fDistance; return (true); }
void CSE_ALifeAnomalousZone::spawn_artefacts () { VERIFY2 (!m_bOnline,"Cannot spawn artefacts in online!"); float m_min_start_power = pSettings->r_float(name(),"min_start_power"); float m_max_start_power = pSettings->r_float(name(),"max_start_power"); u32 m_min_artefact_count= pSettings->r_u32 (name(),"min_artefact_count");; u32 m_max_artefact_count= pSettings->r_u32 (name(),"max_artefact_count");; u32 m_artefact_count; if (m_min_artefact_count == m_max_artefact_count) m_artefact_count = m_min_artefact_count; else m_artefact_count = randI(m_min_artefact_count,m_max_artefact_count); if (m_min_start_power == m_max_start_power) m_maxPower = m_min_start_power; else m_maxPower = randF(m_min_start_power,m_max_start_power); LPCSTR artefacts = pSettings->r_string(name(),"artefacts"); u32 n = _GetItemCount(artefacts); VERIFY2 (!(n % 2),"Invalid parameters count in line artefacts for anomalous zone"); n >>= 1; typedef std::pair<shared_str,float> ARTEFACT_PAIR; string256 temp0, temp1; ARTEFACT_PAIR *m_weights = (ARTEFACT_PAIR*)_alloca(n*sizeof(ARTEFACT_PAIR)); ARTEFACT_PAIR *I = m_weights; ARTEFACT_PAIR *E = m_weights + n; for (u32 i = 0; I != E; ++I, ++i) { _GetItem (artefacts,2*i,temp0); _GetItem (artefacts,2*i + 1,temp1); new (I) ARTEFACT_PAIR(temp0,(float)atof(temp1)); } for (u32 ii=0; ii<m_artefact_count; ++ii) { float fProbability = randF(1.f); float fSum = 0.f; for (u16 p=0; p<n; ++p) { fSum += m_weights[p].second; if (fSum > fProbability) break; } if (p < n) { CSE_Abstract *l_tpSE_Abstract = alife().spawn_item(*m_weights[p].first,position(),m_tNodeID,m_tGraphID,0xffff); R_ASSERT3 (l_tpSE_Abstract,"Can't spawn artefact ",*m_weights[p].first); CSE_ALifeDynamicObject *i = smart_cast<CSE_ALifeDynamicObject*>(l_tpSE_Abstract); R_ASSERT2 (i,"Non-ALife object in the 'game.spawn'"); i->m_tSpawnID = m_tSpawnID; i->m_bALifeControl = true; ai().alife().spawns().assign_artefact_position(this,i); Fvector t = i->o_Position ; u32 p = i->m_tNodeID ; float q = i->m_fDistance ; alife().graph().change(i,m_tGraphID,i->m_tGraphID); i->o_Position = t; i->m_tNodeID = p; i->m_fDistance = q; CSE_ALifeItemArtefact *l_tpALifeItemArtefact = smart_cast<CSE_ALifeItemArtefact*>(i); R_ASSERT2 (l_tpALifeItemArtefact,"Anomalous zone can't generate non-artefact objects since they don't have an 'anomaly property'!"); l_tpALifeItemArtefact->m_fAnomalyValue = m_maxPower*(1.f - i->o_Position.distance_to(o_Position)/m_offline_interactive_radius); } } for (I = m_weights; I != E; ++I) I->~ARTEFACT_PAIR (); }
void CSE_ALifeDynamicObject::switch_online () { R_ASSERT (!m_bOnline); m_bOnline = true; alife().add_online (this); }