void CLevel::g_cl_Spawn		(LPCSTR name, u8 rp, u16 flags, Fvector pos)
{
	// Create
	CSE_Abstract*		E	= F_entity_Create(name);
	VERIFY				(E);

	// Fill
	E->s_name			= name;
	E->set_name_replace	("");
//.	E->s_gameid			=	u8(GameID());
	E->s_RP				=	rp;
	E->ID				=	0xffff;
	E->ID_Parent		=	0xffff;
	E->ID_Phantom		=	0xffff;
	E->s_flags.assign	(flags);
	E->RespawnTime		=	0;
	E->o_Position		= pos;

	// Send
	NET_Packet			P;
	E->Spawn_Write		(P,TRUE);
	Send				(P,net_flags(TRUE));

	// Destroy
	F_entity_Destroy	(E);
}
void xrServer::Process_save(NET_Packet& P, ClientID sender)
{
    xrClientData* CL		= ID_to_client(sender);
    if (CL)	CL->net_Ready	= TRUE;

    R_ASSERT(CL->flags.bLocal);
    // while has information
    while (!P.r_eof())
    {
        // find entity
        u16				ID;
        u16				size;

        P.r_u16			(ID);
        P.r_u16			(size);
        s32				_pos_start	= P.r_tell	();
        CSE_Abstract	*E	= ID_to_entity(ID);

        if (E) {
            E->net_Ready = TRUE;
            E->load		(P);
        }
        else
            P.r_advance	(size);
        s32				_pos_end	= P.r_tell	();
        s32				_size		= size;
        if				(_size != (_pos_end-_pos_start))	{
            Msg			("! load/save mismatch, object: '%s'",E?E->name_replace():"unknown");
            s32			_rollback	= _pos_start+_size;
            P.r_seek	(_rollback);
        }
    }
}
Beispiel #3
0
/////////spawn object representing destroyed item//////////////////////////////////////////////////////////////////////////////////
void CPHDestroyable::GenSpawnReplace(u16 ref_id,LPCSTR section,shared_str visual_name)
{

	CSE_Abstract				*D	= F_entity_Create(section);//*cNameSect()
	VERIFY						(D);
	CSE_Visual					*V  =smart_cast<CSE_Visual*>(D);
	V->set_visual				(*visual_name);
	CSE_PHSkeleton				*l_tpPHSkeleton = smart_cast<CSE_PHSkeleton*>(D);
	VERIFY						(l_tpPHSkeleton);
	l_tpPHSkeleton->source_id	= ref_id;
	//init

	// Send
	D->s_name			= section;//*cNameSect()
	D->ID_Parent		= u16(-1);
	InitServerObject	(D);
	if (OnServer())
	{
		NET_Packet			P;
		D->Spawn_Write		(P,TRUE);
		Level().Send		(P,net_flags(TRUE));
		// Destroy
		F_entity_Destroy	(D);
		m_depended_objects++;
	};
};
Beispiel #4
0
//call this after CGameObject::net_Spawn
BOOL CInventoryOwner::net_Spawn		(CSE_Abstract* DC)
{
	if (!m_pTrade)
		m_pTrade				= xr_new<CTrade>(this);

	if (m_trade_parameters)
		xr_delete				(m_trade_parameters);

	m_trade_parameters			= xr_new<CTradeParameters>(trade_section());

	//получить указатель на объект, InventoryOwner
	//m_inventory->setSlotsBlocked(false);
	CGameObject			*pThis = smart_cast<CGameObject*>(this);
	if(!pThis) return FALSE;
	CSE_Abstract* E	= (CSE_Abstract*)(DC);

	if ( IsGameTypeSingle() )
	{
		CSE_ALifeTraderAbstract* pTrader = NULL;
		if(E) pTrader = smart_cast<CSE_ALifeTraderAbstract*>(E);
		if(!pTrader) return FALSE;

		R_ASSERT( pTrader->character_profile().size() );

		//синхронизируем параметры персонажа с серверным объектом
		CharacterInfo().Init(pTrader);

		//-------------------------------------
		m_known_info_registry->registry().init(E->ID);
		//-------------------------------------


		CAI_PhraseDialogManager* dialog_manager = smart_cast<CAI_PhraseDialogManager*>(this);
		if( dialog_manager && !dialog_manager->GetStartDialog().size() )
		{
			dialog_manager->SetStartDialog(CharacterInfo().StartDialog());
			dialog_manager->SetDefaultStartDialog(CharacterInfo().StartDialog());
		}
		m_game_name			= pTrader->m_character_name;
	}
	else
	{
		CharacterInfo().m_SpecificCharacter.Load					("mp_actor");
		CharacterInfo().InitSpecificCharacter						("mp_actor");
		CharacterInfo().m_SpecificCharacter.data()->m_sGameName = (E->name_replace()[0]) ? E->name_replace() : *pThis->cName();
		m_game_name												= (E->name_replace()[0]) ? E->name_replace() : *pThis->cName();
	}
	

	if(!pThis->Local())  return TRUE;


	return TRUE;
}
Beispiel #5
0
void CWeapon::SpawnAmmo(u32 boxCurr, LPCSTR ammoSect, u32 ParentID) 
{
	if(!m_ammoTypes.size())			return;
	if (OnClient())					return;
	m_bAmmoWasSpawned				= true;
	
	int l_type						= 0;
	l_type							%= m_ammoTypes.size();

	if(!ammoSect) ammoSect			= m_ammoTypes[l_type].c_str(); 
	
	++l_type; 
	l_type							%= m_ammoTypes.size();

	CSE_Abstract *D					= F_entity_Create(ammoSect);

	{	
		CSE_ALifeItemAmmo *l_pA		= smart_cast<CSE_ALifeItemAmmo*>(D);
		R_ASSERT					(l_pA);
		l_pA->m_boxSize				= (u16)pSettings->r_s32(ammoSect, "box_size");
		D->s_name					= ammoSect;
		D->set_name_replace			("");
//.		D->s_gameid					= u8(GameID());
		D->s_RP						= 0xff;
		D->ID						= 0xffff;
		if (ParentID == 0xffffffff)	
			D->ID_Parent			= (u16)H_Parent()->ID();
		else
			D->ID_Parent			= (u16)ParentID;

		D->ID_Phantom				= 0xffff;
		D->s_flags.assign			(M_SPAWN_OBJECT_LOCAL);
		D->RespawnTime				= 0;
		l_pA->m_tNodeID				= g_dedicated_server ? u32(-1) : ai_location().level_vertex_id();

		if(boxCurr == 0xffffffff) 	
			boxCurr					= l_pA->m_boxSize;

		while(boxCurr) 
		{
			l_pA->a_elapsed			= (u16)(boxCurr > l_pA->m_boxSize ? l_pA->m_boxSize : boxCurr);
			NET_Packet				P;
			D->Spawn_Write			(P, TRUE);
			Level().Send			(P,net_flags(TRUE));

			if(boxCurr > l_pA->m_boxSize) 
				boxCurr				-= l_pA->m_boxSize;
			else 
				boxCurr				= 0;
		}
	}
	F_entity_Destroy				(D);
}
void xrServer::Process_update(NET_Packet& P, ClientID sender)
{
    xrClientData* CL		= ID_to_client(sender);
    if (!CL)
    {
        return;
    }
//	if (CL)	CL->net_Ready	= TRUE;

#ifdef DEBUG
    if (g_Dump_Update_Read) Msg("---- UPDATE_Read --- ");
#endif						// Entities

    R_ASSERT(CL->flags.bLocal);
    // while has information
    while (!P.r_eof())
    {
        // find entity
        u16				ID;
        u8				size;

        P.r_u16			(ID);
        P.r_u8			(size);
        u32	_pos		= P.r_tell();
        CSE_Abstract	*E	= ID_to_entity(ID);

        if (E) {
            //Msg				("sv_import: %d '%s'",E->ID,E->name_replace());
            E->net_Ready	= TRUE;
            E->UPDATE_Read	(P);
#ifdef DEBUG
            if (g_Dump_Update_Read) Msg("* %s : %d - %d", E->name(), size, P.r_tell() - _pos);
#endif

            if ((P.r_tell()-_pos) != size)	{
                string16	tmp;
                CLSID2TEXT	(E->m_tClassID,tmp);
                Debug.fatal	(DEBUG_INFO,"Beer from the creator of '%s'",tmp);
            }
        }
        else
            P.r_advance	(size);
    }
#ifdef DEBUG
    if (g_Dump_Update_Read) Msg("-------------------- ");
#endif						// Entities

}
Beispiel #7
0
u16	GetSpawnInfo(NET_Packet &P, u16 &parent_id)
{
	u16 dummy16, id;
	P.r_begin(dummy16);
	shared_str	s_name;
	P.r_stringZ(s_name);
	CSE_Abstract*	E = F_entity_Create(*s_name);
	E->Spawn_Read(P);
	if (E->s_flags.is(M_SPAWN_UPDATE))
		E->UPDATE_Read(P);
	id = E->ID;
	parent_id = E->ID_Parent;
	F_entity_Destroy(E);
	P.r_pos = 0;
	return id;
}
void CALifeGraphRegistry::detach	(CSE_Abstract &object, CSE_ALifeInventoryItem *item, GameGraph::_GRAPH_ID game_vertex_id, bool alife_query, bool remove_children)
{
#ifdef DEBUG
	if (psAI_Flags.test(aiALife)) {
		Msg						("[LSS] Detaching item [%s][%d] from [%s][%d]",item->base()->name_replace(),item->base()->ID,object.name_replace(),object.ID);
	}
#endif
	if (alife_query)
		add						(smart_cast<CSE_ALifeDynamicObject*>(item),game_vertex_id);
	else {
		CSE_ALifeDynamicObject	*object = smart_cast<CSE_ALifeDynamicObject*>(item);
		VERIFY					(object);
		object->m_tGraphID		= game_vertex_id;
		level().add 			(object);
	}

	CSE_ALifeDynamicObject		*dynamic_object = smart_cast<CSE_ALifeDynamicObject*>(&object);
	R_ASSERT2					(!alife_query || dynamic_object,"Cannot detach an item from non-alife object");
	
	VERIFY						(alife_query || !smart_cast<CSE_ALifeDynamicObject*>(&object) || (ai().game_graph().vertex(smart_cast<CSE_ALifeDynamicObject*>(&object)->m_tGraphID)->level_id() == level().level_id()));

	if (dynamic_object)
		dynamic_object->detach	(item,0,alife_query,remove_children);
	else {
#ifdef DEBUG
		bool					value = std::find(object.children.begin(),object.children.end(),item->base()->ID) != object.children.end();
		if (!value) {
			Msg					("! ERROR: can't detach independant object. entity[%s:%d], parent[%s:%d], section[%s]",
				item->base()->name_replace(),item->base()->ID,object.name_replace(),object.ID, *item->base()->s_name);
		}
#endif // DEBUG
//		R_ASSERT2				(value,"Can't detach an item which is not on my own");
	}
}
Beispiel #9
0
CSE_Abstract *CALifeSimulatorBase::spawn_item	(LPCSTR section, const Fvector &position, u32 level_vertex_id, GameGraph::_GRAPH_ID game_vertex_id, u16 parent_id, bool registration)
{
	CSE_Abstract				*abstract = F_entity_Create(section);
	R_ASSERT3					(abstract,"Cannot find item with section",section);

	abstract->s_name			= section;
//.	abstract->s_gameid			= u8(GAME_SINGLE);
	abstract->s_RP				= 0xff;
	abstract->ID				= server().PerformIDgen(0xffff);
	abstract->ID_Parent			= parent_id;
	abstract->ID_Phantom		= 0xffff;
	abstract->o_Position		= position;
	abstract->m_wVersion		= SPAWN_VERSION;
	
	string256					s_name_replace;
	strcpy_s						(s_name_replace,*abstract->s_name);
	if (abstract->ID < 1000)
		strcat					(s_name_replace,"0");
	if (abstract->ID < 100)
		strcat					(s_name_replace,"0");
	if (abstract->ID < 10)
		strcat					(s_name_replace,"0");
	string16					S1;
	strcat						(s_name_replace,itoa(abstract->ID,S1,10));
	abstract->set_name_replace	(s_name_replace);

	CSE_ALifeDynamicObject		*dynamic_object = smart_cast<CSE_ALifeDynamicObject*>(abstract);
	VERIFY						(dynamic_object);

	//оружие спавним с полным магазинои
	CSE_ALifeItemWeapon* weapon = smart_cast<CSE_ALifeItemWeapon*>(dynamic_object);
	if(weapon)
		weapon->a_elapsed		= weapon->get_ammo_magsize();

	dynamic_object->m_tNodeID	= level_vertex_id;
	dynamic_object->m_tGraphID	= game_vertex_id;
	dynamic_object->m_tSpawnID	= u16(-1);

	if (registration)
		register_object				(dynamic_object,true);

	dynamic_object->spawn_supplies	();
	dynamic_object->on_spawn		();

//	Msg							("LSS : SPAWN : [%s],[%s], level %s",*dynamic_object->s_name,dynamic_object->name_replace(),*ai().game_graph().header().level(ai().game_graph().vertex(dynamic_object->m_tGraphID)->level_id()).name());
	return						(dynamic_object);
}
Beispiel #10
0
//процесс отсоединения вещи заключается в спауне новой вещи 
//в инвентаре и установке соответствующих флагов в родительском
//объекте, поэтому функция должна быть переопределена
bool CInventoryItem::Detach(const char* item_section_name, bool b_spawn_item) 
{
	if (OnClient()) return true;
	if(b_spawn_item)
	{
		CSE_Abstract*		D	= F_entity_Create(item_section_name);
		R_ASSERT		   (D);
		CSE_ALifeDynamicObject	*l_tpALifeDynamicObject = 
								smart_cast<CSE_ALifeDynamicObject*>(D);
		R_ASSERT			(l_tpALifeDynamicObject);
		
		l_tpALifeDynamicObject->m_tNodeID = object().ai_location().level_vertex_id();
			
		// Fill
		D->s_name			=	item_section_name;
		D->set_name_replace	("");
		D->s_gameid			=	u8(GameID());
		D->s_RP				=	0xff;
		D->ID				=	0xffff;
		if (GameID() == GAME_SINGLE)
		{
			D->ID_Parent		=	u16(object().H_Parent()->ID());
		}
		else	// i'm not sure this is right
		{		// but it is simpliest way to avoid exception in MP BuyWnd... [Satan]
			if (object().H_Parent())
				D->ID_Parent	=	u16(object().H_Parent()->ID());
			else
				D->ID_Parent	= NULL;
		}
		D->ID_Phantom		=	0xffff;
		D->o_Position		=	object().Position();
		D->s_flags.assign	(M_SPAWN_OBJECT_LOCAL);
		D->RespawnTime		=	0;
		// Send
		NET_Packet			P;
		D->Spawn_Write		(P,TRUE);
		Level().Send		(P,net_flags(TRUE));
		// Destroy
		F_entity_Destroy	(D);
	}
	return true;
}
Beispiel #11
0
void CPHSkeleton::SpawnCopy()
{
	if(PPhysicsShellHolder()->Local()) {
		CSE_Abstract*				D	= F_entity_Create("ph_skeleton_object");//*cNameSect()
		R_ASSERT					(D);
		/////////////////////////////////////////////////////////////////////////////////////////////
		CSE_ALifePHSkeletonObject	*l_tpALifePhysicObject = smart_cast<CSE_ALifePHSkeletonObject*>(D);
		R_ASSERT					(l_tpALifePhysicObject);
		l_tpALifePhysicObject->_flags.set	(CSE_PHSkeleton::flSpawnCopy,1);
		//SetNotNeedSave()
		/////////////////////////////////////////////////////////////////////////////////////////////
		InitServerObject			(D);
		// Send
		NET_Packet			P;
		D->Spawn_Write		(P,TRUE);
		Level().Send		(P,net_flags(TRUE));
		// Destroy
		F_entity_Destroy	(D);
	}
}
void xrServer::Process_update(NET_Packet& P, ClientID sender)
{
	xrClientData* CL		= ID_to_client(sender);
	R_ASSERT2				(CL,"Process_update client not found");

	if (g_Dump_Update_Read) Msg("---- UPDATE_Read --- ");

	R_ASSERT(CL->flags.bLocal);
	// while has information
	while (!P.r_eof())
	{
		// find entity
		u16				ID;
		u8				size;

		P.r_u16			(ID);
		P.r_u8			(size);
		u32	_pos		= P.r_tell();
		CSE_Abstract	*E	= ID_to_entity(ID);
		
		if (E) {
			//Msg				("sv_import: %d '%s'",E->ID,E->name_replace());
			E->net_Ready	= TRUE;
			E->UPDATE_Read	(P);

			u32 cp = P.r_tell();
			if (g_Dump_Update_Read) Msg("* %s : %d - %d", E->name(), size, cp - _pos);

			if ((cp - _pos) != size)	{
				string16	tmp;
				CLSID2TEXT	(E->m_tClassID,tmp);
				Msg("* size = %d, start read = %d, end read = %d", size, _pos, cp);
				Debug.fatal	(DEBUG_INFO,"Beer from the creator of '%s', version of object = %d", tmp, E->m_wVersion);				
			}
		}
		else
			P.r_advance	(size);
	}
	if (g_Dump_Update_Read) Msg("-------------------- ");

}
Beispiel #13
0
CSE_Abstract *CLevelSpawnConstructor::create_object						(IReader *chunk)
{
	NET_Packet				net_packet;
	net_packet.B.count		= chunk->length();
	chunk->r				(net_packet.B.data,net_packet.B.count);
//	we do not need to close chunk since we iterate on them
//	chunk->close			();
	u16						ID;
	net_packet.r_begin		(ID);
	R_ASSERT2				(M_SPAWN==ID,"ID doesn't match to the spawn-point ID!");
	string64				section_name;
	net_packet.r_stringZ	(section_name);
	CSE_Abstract			*abstract = F_entity_Create(section_name);
	if (!abstract) {
		string256			temp;
		sprintf				(temp,"Can't create entity '%s' !\n",section_name);
		R_ASSERT2			(abstract,temp);
	}
	abstract->Spawn_Read	(net_packet);
	return					(abstract);
}
Beispiel #14
0
void CInventoryOwner::spawn_supplies		()
{
	CGameObject								*game_object = smart_cast<CGameObject*>(this);
	VERIFY									(game_object);
	if (smart_cast<CBaseMonster*>(this))	return;


	if (use_bolts())
		Level().spawn_item					("bolt",game_object->Position(),game_object->ai_location().level_vertex_id(),game_object->ID());

	if (!ai().get_alife() && GameID()==GAME_SINGLE) {
		CSE_Abstract						*abstract = Level().spawn_item("device_pda",game_object->Position(),game_object->ai_location().level_vertex_id(),game_object->ID(),true);
		CSE_ALifeItemPDA					*pda = smart_cast<CSE_ALifeItemPDA*>(abstract);
		R_ASSERT							(pda);
		pda->m_original_owner				= (u16)game_object->ID();
		NET_Packet							P;
		abstract->Spawn_Write				(P,TRUE);
		Level().Send						(P,net_flags(TRUE));
		F_entity_Destroy					(abstract);
	}
}
CSE_Abstract *CLevel::spawn_item		(LPCSTR section, const Fvector &position, u32 level_vertex_id, u16 parent_id, bool return_item)
{
	CSE_Abstract			*abstract = F_entity_Create(section);
	R_ASSERT3				(abstract,"Cannot find item with section",section);
	CSE_ALifeDynamicObject	*dynamic_object = smart_cast<CSE_ALifeDynamicObject*>(abstract);
	if (dynamic_object && ai().get_level_graph()) {
		dynamic_object->m_tNodeID	= level_vertex_id;
		if (ai().level_graph().valid_vertex_id(level_vertex_id) && ai().get_game_graph() && ai().get_cross_table())
			dynamic_object->m_tGraphID	= ai().cross_table().vertex(level_vertex_id).game_vertex_id();
	}

	//оружие спавним с полным магазинои
	CSE_ALifeItemWeapon* weapon = smart_cast<CSE_ALifeItemWeapon*>(abstract);
	if(weapon)
		weapon->a_elapsed	= weapon->get_ammo_magsize();
	
	// Fill
	abstract->s_name		= section;
	abstract->set_name_replace	(section);
//.	abstract->s_gameid		= u8(GameID());
	abstract->o_Position	= position;
	abstract->s_RP			= 0xff;
	abstract->ID			= 0xffff;
	abstract->ID_Parent		= parent_id;
	abstract->ID_Phantom	= 0xffff;
	abstract->s_flags.assign(M_SPAWN_OBJECT_LOCAL);
	abstract->RespawnTime	= 0;

	if (!return_item) {
		NET_Packet				P;
		abstract->Spawn_Write	(P,TRUE);
		Send					(P,net_flags(TRUE));
		F_entity_Destroy		(abstract);
		return					(0);
	}
	else
		return				(abstract);
}
Beispiel #16
0
void SArtefactActivation::SpawnAnomaly()
{
	VERIFY(!ph_world->Processing());
	string128 tmp;
	LPCSTR str			= pSettings->r_string("artefact_spawn_zones",*m_af->cNameSect());
	VERIFY3(3==_GetItemCount(str),"Bad record format in artefact_spawn_zones",str);
	float zone_radius	= (float)atof(_GetItem(str,1,tmp));
	float zone_power	= (float)atof(_GetItem(str,2,tmp));
	LPCSTR zone_sect	= _GetItem(str,0,tmp); //must be last call of _GetItem... (LPCSTR !!!)

		Fvector pos;
		m_af->Center(pos);
		CSE_Abstract		*object = Level().spawn_item(	zone_sect,
															pos,
															m_af->ai_location().level_vertex_id(),
															0xffff,
															true
		);
		CSE_ALifeAnomalousZone*		AlifeZone = smart_cast<CSE_ALifeAnomalousZone*>(object);
		VERIFY(AlifeZone);
		CShapeData::shape_def		_shape;
		_shape.data.sphere.P.set	(0.0f,0.0f,0.0f);
		_shape.data.sphere.R		= zone_radius;
		_shape.type					= CShapeData::cfSphere;
		AlifeZone->assign_shapes	(&_shape,1);
		AlifeZone->m_maxPower		= zone_power;
		AlifeZone->m_owner_id		= m_owner_id;
		AlifeZone->m_space_restrictor_type	= RestrictionSpace::eRestrictorTypeNone;

		NET_Packet					P;
		object->Spawn_Write			(P,TRUE);
		Level().Send				(P,net_flags(TRUE));
		F_entity_Destroy			(object);
#ifdef DEBUG
		Msg("artefact [%s] spawned a zone [%s] at [%f]", *m_af->cName(), zone_sect, Device.fTimeGlobal);
#endif
}
void CLevel::cl_Process_Spawn(NET_Packet& P)
{
	// Begin analysis
	shared_str			s_name;
	P.r_stringZ			(s_name);

	// Create DC (xrSE)
	CSE_Abstract*	E	= F_entity_Create	(*s_name);
	R_ASSERT2(E, *s_name);


	E->Spawn_Read		(P);
	if (E->s_flags.is(M_SPAWN_UPDATE))
		E->UPDATE_Read	(P);

	if (!E->match_configuration())
	{
		F_entity_Destroy(E);
		return;
	}
//-------------------------------------------------
//.	Msg ("M_SPAWN - %s[%d][%x] - %d %d", *s_name,  E->ID, E,E->ID_Parent, Device.dwFrame);
//-------------------------------------------------
	//force object to be local for server client
	if (OnServer())		{
		E->s_flags.set(M_SPAWN_OBJECT_LOCAL, TRUE);
	};

	/*
	game_spawn_queue.push_back(E);
	if (g_bDebugEvents)		ProcessGameSpawns();
	/*/
	g_sv_Spawn					(E);

	F_entity_Destroy			(E);
	//*/
};
void CALifeGraphRegistry::attach	(CSE_Abstract &object, CSE_ALifeInventoryItem *item, GameGraph::_GRAPH_ID game_vertex_id, bool alife_query, bool add_children)
{
#ifdef DEBUG
	if (psAI_Flags.test(aiALife)) {
		Msg						("[LSS] Attaching item [%s][%d] to [%s][%d]",item->base()->name_replace(),item->base()->ID,object.name_replace(),object.ID);
	}
#endif
	if (alife_query)
		remove					(smart_cast<CSE_ALifeDynamicObject*>(item),game_vertex_id);
	else
		level().remove			(smart_cast<CSE_ALifeDynamicObject*>(item));

	CSE_ALifeDynamicObject		*dynamic_object = smart_cast<CSE_ALifeDynamicObject*>(&object);
	R_ASSERT2					(!alife_query || dynamic_object,"Cannot attach an item to a non-alife object object");

	dynamic_object->attach		(item,alife_query,add_children);
}
Beispiel #19
0
void xrServer::Update	()
{
	NET_Packet		Packet;
	u32				position;

	csPlayers.Enter	();

	VERIFY						(verify_entities());

	// game update
	game->ProcessDelayedEvent();
	game->Update	();

	// spawn queue
	u32 svT				= Device.TimerAsync();
	while (!(q_respawn.empty() || (svT<q_respawn.begin()->timestamp)))
	{
		// get
		svs_respawn	R		= *q_respawn.begin();
		q_respawn.erase		(q_respawn.begin());

		// 
		CSE_Abstract* E	= ID_to_entity(R.phantom);
		E->Spawn_Write		(Packet,FALSE);
		u16					ID;
		Packet.r_begin		(ID);	R_ASSERT(M_SPAWN==ID);
		ClientID clientID; clientID.set(0xffff);
		Process_spawn		(Packet,clientID);
	}

	// 
	for (u32 client=0; client<net_Players.size(); ++client)
	{
		// Initialize process and check for available bandwidth
		xrClientData*	Client		= (xrClientData*) net_Players	[client];
		if (!Client->net_Ready)		continue;		
		if (!HasBandwidth(Client) 
#ifdef DEBUG
			&& !g_sv_SendUpdate
#endif
			)	continue;		

		// Send relevant entities to client
		// CSE_Abstract*	Base	= Client->owner;
		u16 PacketType = M_UPDATE;
		Packet.w_begin	(PacketType);

		// GameUpdate
		++(Client->game_replicate_id);
		u32		g_it				= (Client->game_replicate_id % client_Count());
//		u32		g_id				= net_Players[g_it]->ID;
		ClientID g_id 				= net_Players[g_it]->ID;
		game->net_Export_Update		(Packet,Client->ID,g_id);

//		if (!Client->flags.bLocal)	
			game->net_Export_GameTime(Packet);

		if (!Client->flags.bLocal || client_Count() == 1)
		{
#ifdef DEBUG
			if (g_Dump_Update_Write) Msg("---- UPDATE_Write to %s --- ", *(Client->Name));
#endif					// Entities
			
			NET_Packet tmpPacket;
			xrS_entities::iterator	I=entities.begin(),E=entities.end();
			for (; I!=E; ++I)
			{
				CSE_Abstract&	Test = *(I->second);

				if (0==Test.owner)							continue;	// Phantom(?)
				if (!Test.net_Ready)						continue;
				if (Test.owner == Client && Client->flags.bLocal)					continue;	// Can't be relevant

				if (Test.s_flags.is(M_SPAWN_OBJECT_PHANTOM))	continue;	// Surely: phantom
				
				tmpPacket.B.count = 0;
				// write specific data
				{
					tmpPacket.w_u16			(Test.ID		);
					tmpPacket.w_chunk_open8	(position		);
					Test.UPDATE_Write		(tmpPacket			);
#ifdef DEBUG
					if (g_Dump_Update_Write) Msg("* %s : %d", Test.name(), u32(tmpPacket.w_tell()-position)-sizeof(u8));
#endif
					tmpPacket.w_chunk_close8	(position		);
					if (Packet.B.count + tmpPacket.B.count < NET_PacketSizeLimit)
					{
						Packet.w(tmpPacket.B.data, tmpPacket.B.count);
					}
					else
					{
						if (Packet.B.count > 2)	
						{
//							if (!Client->flags.bLocal)
//								Msg ("- Server Update[%d] to Client  : %d", PacketType, Packet.B.count);
							SendTo			(Client->ID,Packet,net_flags(FALSE,TRUE));
						}
						PacketType = M_UPDATE_OBJECTS;
						Packet.w_begin(PacketType);
					}
				}
			}
#ifdef DEBUG
			if (g_Dump_Update_Write) Msg("----------------------- ");
#endif			
		};

		if (Packet.B.count > 2)	
		{
//			if (!Client->flags.bLocal)
//				Msg ("- Server Update[%d] to Client  : %d", PacketType, Packet.B.count);
			SendTo			(Client->ID,Packet,net_flags(FALSE,TRUE));
		}
	}
#ifdef DEBUG
	g_sv_SendUpdate = 0;
#endif			

	if (game->sv_force_sync)	Perform_game_export();

	VERIFY						(verify_entities());
	//-----------------------------------------------------
	//Remove any of long time disconnected players
	for (u32 DI = 0; DI<net_Players_disconnected.size(); DI++)
	{
		IClient* CL = net_Players_disconnected[DI];
		if (CL->dwTime_LastUpdate+g_sv_Client_Reconnect_Time*60000<Device.dwTimeGlobal)
			client_Destroy(CL);
	}
	//-----------------------------------------------------
	csPlayers.Leave	();
}
Beispiel #20
0
BOOL CGameObject::net_Spawn		(CSE_Abstract*	DC)
{
	VERIFY							(!m_spawned);
	m_spawned						= true;
	m_spawn_time					= Device.dwFrame;
	m_ai_obstacle					= xr_new<ai_obstacle>(this);

	CSE_Abstract					*E = (CSE_Abstract*)DC;
	VERIFY							(E);

	const CSE_Visual				*visual	= smart_cast<const CSE_Visual*>(E);
	if (visual) {
		cNameVisual_set				(visual_name(E));
		if (visual->flags.test(CSE_Visual::flObstacle)) {
			ISpatial				*self = smart_cast<ISpatial*>(this);
			self->spatial.type		|=	STYPE_OBSTACLE;
		}
	}

	// Naming
	cName_set						(E->s_name);
	cNameSect_set					(E->s_name);
	if (E->name_replace()[0])
		cName_set					(E->name_replace());
	bool demo_spectator = false;
	
	if (Level().IsDemoPlayStarted() && E->ID == u16(-1))
	{
		Msg("* Spawning demo spectator ...");
		demo_spectator = true;
	} else {
		R_ASSERT(Level().Objects.net_Find(E->ID) == NULL);
	}


	setID							(E->ID);
//	if (GameID() != eGameIDSingle)
//		Msg ("CGameObject::net_Spawn -- object %s[%x] setID [%d]", *(E->s_name), this, E->ID);
	
	// XForm
	XFORM().setXYZ					(E->o_Angle);
	Position().set					(E->o_Position);
#ifdef DEBUG
	if(ph_dbg_draw_mask1.test(ph_m1_DbgTrackObject)&&stricmp(PH_DBG_ObjectTrackName(),*cName())==0)
	{
		Msg("CGameObject::net_Spawn obj %s Position set from CSE_Abstract %f,%f,%f",PH_DBG_ObjectTrackName(),Position().x,Position().y,Position().z);
	}
#endif
	VERIFY							(_valid(renderable.xform));
	VERIFY							(!fis_zero(DET(renderable.xform)));
	CSE_ALifeObject					*O = smart_cast<CSE_ALifeObject*>(E);
	if (O && xr_strlen(O->m_ini_string)) {
#pragma warning(push)
#pragma warning(disable:4238)
		m_ini_file					= xr_new<CInifile>(
			&IReader				(
				(void*)(*(O->m_ini_string)),
				O->m_ini_string.size()
			),
			FS.get_path("$game_config$")->m_Path
		);
#pragma warning(pop)
	}

	m_story_id						= ALife::_STORY_ID(-1);
	if (O)
		m_story_id					= O->m_story_id;

	// Net params
	setLocal						(E->s_flags.is(M_SPAWN_OBJECT_LOCAL));
	if (Level().IsDemoPlay()) //&& OnClient())
	{
		if (!demo_spectator)
		{
			setLocal(FALSE);
		}
	};

	setReady						(TRUE);
	if (!demo_spectator)
		g_pGameLevel->Objects.net_Register	(this);

	m_server_flags.one				();
	if (O) {
		m_server_flags					= O->m_flags;
		if (O->m_flags.is(CSE_ALifeObject::flVisibleForAI))
			spatial.type				|= STYPE_VISIBLEFORAI;
		else
			spatial.type				= (spatial.type | STYPE_VISIBLEFORAI) ^ STYPE_VISIBLEFORAI;
	}

	reload						(*cNameSect());
	if(!g_dedicated_server)
		CScriptBinder::reload	(*cNameSect());
	
	reinit						();
	if(!g_dedicated_server)
		CScriptBinder::reinit	();
#ifdef DEBUG
	if(ph_dbg_draw_mask1.test(ph_m1_DbgTrackObject)&&stricmp(PH_DBG_ObjectTrackName(),*cName())==0)
	{
		Msg("CGameObject::net_Spawn obj %s After Script Binder reinit %f,%f,%f",PH_DBG_ObjectTrackName(),Position().x,Position().y,Position().z);
	}
#endif
	//load custom user data from server
	if(!E->client_data.empty())
	{	
//		Msg				("client data is present for object [%d][%s], load is processed",ID(),*cName());
		IReader			ireader = IReader(&*E->client_data.begin(), E->client_data.size());
		net_Load		(ireader);
	}
	else {
//		Msg				("no client data for object [%d][%s], load is skipped",ID(),*cName());
	}

	// if we have a parent
	if ( ai().get_level_graph() ) {
		if ( E->ID_Parent == 0xffff ) {
			CSE_ALifeObject* l_tpALifeObject	= smart_cast<CSE_ALifeObject*>(E);
			if (l_tpALifeObject && ai().level_graph().valid_vertex_id(l_tpALifeObject->m_tNodeID))
				ai_location().level_vertex		(l_tpALifeObject->m_tNodeID);
			else {
				CSE_Temporary* l_tpTemporary	= smart_cast<CSE_Temporary*>	(E);
				if (l_tpTemporary && ai().level_graph().valid_vertex_id(l_tpTemporary->m_tNodeID))
					ai_location().level_vertex	(l_tpTemporary->m_tNodeID);
			}

			if (l_tpALifeObject && ai().game_graph().valid_vertex_id(l_tpALifeObject->m_tGraphID))
				ai_location().game_vertex		(l_tpALifeObject->m_tGraphID);

			validate_ai_locations				(false);

			// validating position
			if	(
					UsedAI_Locations() && 
					ai().level_graph().inside(
						ai_location().level_vertex_id(),
						Position()
					) &&
					can_validate_position_on_spawn()
				)
				Position().y					= EPS_L + ai().level_graph().vertex_plane_y(*ai_location().level_vertex(),Position().x,Position().z);
		}
		else {
			CSE_ALifeObject* const alife_object	= smart_cast<CSE_ALifeObject*>(E);
			if ( alife_object && ai().level_graph().valid_vertex_id(alife_object->m_tNodeID) ) {
				ai_location().level_vertex		(alife_object->m_tNodeID);
				ai_location().game_vertex		(alife_object->m_tGraphID);
			}
		}
	}
	inherited::net_Spawn		(DC);

	m_bObjectRemoved			= false;

	spawn_supplies				();
#ifdef DEBUG
	if(ph_dbg_draw_mask1.test(ph_m1_DbgTrackObject)&&stricmp(PH_DBG_ObjectTrackName(),*cName())==0)
	{
		Msg("CGameObject::net_Spawn obj %s Before CScriptBinder::net_Spawn %f,%f,%f",PH_DBG_ObjectTrackName(),Position().x,Position().y,Position().z);
	}
	BOOL ret =CScriptBinder::net_Spawn(DC);
#else
	return						(CScriptBinder::net_Spawn(DC));
#endif

#ifdef DEBUG
	if(ph_dbg_draw_mask1.test(ph_m1_DbgTrackObject)&&stricmp(PH_DBG_ObjectTrackName(),*cName())==0)
	{
		Msg("CGameObject::net_Spawn obj %s Before CScriptBinder::net_Spawn %f,%f,%f",PH_DBG_ObjectTrackName(),Position().x,Position().y,Position().z);
	}
	return ret;
#endif
}
Beispiel #21
0
void CGameGraphBuilder::load_graph_point	(NET_Packet &net_packet)
{
	string256				section_id;
	u16						id;
	net_packet.r_begin		(id);
	R_ASSERT				(M_SPAWN == id);
	net_packet.r_stringZ	(section_id);

//	if (xr_strcmp("graph_point",section_id))
//		return;

	CSE_Abstract			*entity = F_entity_Create(section_id);
	if (!entity) {
		Msg					("Cannot create entity from section %s, skipping",section_id);
		return;
	}

	CSE_ALifeGraphPoint		*graph_point = smart_cast<CSE_ALifeGraphPoint*>(entity);
	if (!graph_point) {
		F_entity_Destroy	(entity);
		return;
	}

	entity->Spawn_Read		(net_packet);

	vertex_type				vertex;
	vertex.tLocalPoint		= graph_point->o_Position;
	// check for duplicate graph point positions
	{
		graph_type::const_vertex_iterator	I = graph().vertices().begin();
		graph_type::const_vertex_iterator	E = graph().vertices().end();
		for ( ; I != E; ++I) {
			if ((*I).second->data().tLocalPoint.distance_to_sqr(vertex.tLocalPoint) < EPS_L) {
				Msg			("! removing graph point [%s][%f][%f][%f] because it is too close to the another graph point",entity->name_replace(),VPUSH(entity->o_Position));
				return;
			}
		}
	}

	vertex.tGlobalPoint		= graph_point->o_Position;
	vertex.tNodeID			= level_graph().valid_vertex_position(vertex.tLocalPoint) ? level_graph().vertex_id(vertex.tLocalPoint) : u32(-1);
	if (!level_graph().valid_vertex_id(vertex.tNodeID)) {
		Msg					("! removing graph point [%s][%f][%f][%f] because it is outside of the AI map",entity->name_replace(),VPUSH(entity->o_Position));
		return;
	}

	{
		graph_type::const_vertex_iterator	I = graph().vertices().begin();
		graph_type::const_vertex_iterator	E = graph().vertices().end();
		for ( ; I != E; ++I) {
			if ((*I).second->data().tNodeID == vertex.tNodeID) {
				Msg			("! removing graph point [%s][%f][%f][%f] because it has the same AI node as another graph point",entity->name_replace(),VPUSH(entity->o_Position));
				return;
			}
		}
	}

	vertex.tNeighbourCount	= 0;
	Memory.mem_copy			(vertex.tVertexTypes,graph_point->m_tLocations,GameGraph::LOCATION_TYPE_COUNT*sizeof(GameGraph::_LOCATION_ID));
	vertex.tLevelID			= 0;
	vertex.tDeathPointCount = 0;
	vertex.dwPointOffset	= 0;

	graph().add_vertex		(vertex,graph().vertices().size());

	F_entity_Destroy		(entity);
}
Beispiel #22
0
								CLevelGameGraph	(
									LPCSTR graph_file_name,
									LPCSTR raw_cross_table_file_name,
									CGameGraph::SLevel *tLevel,
									LPCSTR S,
									u32 dwOffset,
									u32 dwLevelID,
									CInifile *Ini
								)
	{
		m_tLevel				= *tLevel;
		m_dwOffset				= dwOffset;
		m_tpLevelPoints.clear	();
		
		FILE_NAME				caFileName;
		
		// loading graph
		strcpy_s				(caFileName,graph_file_name);
		m_tpGraph				= new CGameGraph(caFileName);

		strcpy_s				(caFileName,raw_cross_table_file_name);
		CGameLevelCrossTable	*l_tpCrossTable = new CGameLevelCrossTable(caFileName);

		CLevelGraph				*l_tpAI_Map = new CLevelGraph(S);

		VERIFY2					(l_tpCrossTable->header().level_guid() == l_tpAI_Map->header().guid(), "cross table doesn't correspond to the AI-map, rebuild graph!");
		VERIFY2					(l_tpCrossTable->header().game_guid() == m_tpGraph->header().guid(), "cross table doesn't correspond to the graph, rebuild graph!");
		VERIFY2					(m_tpGraph->header().level(GameGraph::_LEVEL_ID(0)).guid() == l_tpAI_Map->header().guid(), "cross table doesn't correspond to the AI-map, rebuild graph!");

		VERIFY					(l_tpAI_Map->header().vertex_count() == l_tpCrossTable->header().level_vertex_count());
		VERIFY					(m_tpGraph->header().vertex_count() == l_tpCrossTable->header().game_vertex_count());

		tLevel->m_guid			= l_tpAI_Map->header().guid();

		{
			for (GameGraph::_GRAPH_ID i=0, n = m_tpGraph->header().vertex_count(); i<n; ++i)
				if ((!l_tpAI_Map->valid_vertex_id(m_tpGraph->vertex(i)->level_vertex_id()) ||
					(l_tpCrossTable->vertex(m_tpGraph->vertex(i)->level_vertex_id()).game_vertex_id() != i) ||
					!l_tpAI_Map->inside(m_tpGraph->vertex(i)->level_vertex_id(),m_tpGraph->vertex(i)->level_point()))) {
						Msg				("! Graph doesn't correspond to the cross table");
						R_ASSERT2		(false,"Graph doesn't correspond to the cross table");
				}
		}

		m_tpVertices.resize		(m_tpGraph->header().vertex_count());
		GRAPH_VERTEX_IT			B = m_tpVertices.begin();
		GRAPH_VERTEX_IT			I = B;
		GRAPH_VERTEX_IT			E = m_tpVertices.end();
		for ( ; I != E; I++) {
			(*I).tLocalPoint		= m_tpGraph->vertex(int(I - B))->level_point();
			(*I).tGlobalPoint.add	(m_tpGraph->vertex(int(I - B))->game_point(),m_tLevel.offset());
			(*I).tLevelID			= dwLevelID;
			(*I).tNodeID			= m_tpGraph->vertex(int(I - B))->level_vertex_id();
			Memory.mem_copy			((*I).tVertexTypes,m_tpGraph->vertex(int(I - B))->vertex_type(),GameGraph::LOCATION_TYPE_COUNT*sizeof(GameGraph::_LOCATION_ID));
			(*I).tNeighbourCount	= m_tpGraph->vertex(int(I - B))->edge_count();
			CGameGraph::const_iterator	b,i,e;
			m_tpGraph->begin		(int(I - B),i,e);
			(*I).tpaEdges			= (CGameGraph::CEdge*)xr_malloc((*I).tNeighbourCount*sizeof(CGameGraph::CEdge));
			b						= i;
			for ( ; i != e; ++i) {
				GameGraph::CEdge	&edge = (*I).tpaEdges[i - b];
				edge				= *i;
				VERIFY				((edge.vertex_id() + dwOffset) < (u32(1) << (8*sizeof(GameGraph::_GRAPH_ID))));
				edge.m_vertex_id	= (GameGraph::_GRAPH_ID)(edge.m_vertex_id + dwOffset);
			}
			(*I).dwPointOffset		= 0;
			vfGenerateDeathPoints	(int(I - B),l_tpCrossTable,l_tpAI_Map,(*I).tDeathPointCount);
		}

		xr_delete					(l_tpCrossTable);
		xr_delete					(l_tpAI_Map);
		
		// updating cross-table
		{
			strcpy_s				(caFileName,raw_cross_table_file_name);
			CGameLevelCrossTable	*tpCrossTable = new CGameLevelCrossTable(caFileName);
			xr_vector<CGameLevelCrossTable::CCell> tCrossTableUpdate;
			tCrossTableUpdate.resize(tpCrossTable->header().level_vertex_count());
			for (int i=0; i<(int)tpCrossTable->header().level_vertex_count(); i++) {
				tCrossTableUpdate[i] = tpCrossTable->vertex(i);
				VERIFY				(u32(tCrossTableUpdate[i].tGraphIndex) < tpCrossTable->header().game_vertex_count());
				tCrossTableUpdate[i].tGraphIndex = tCrossTableUpdate[i].tGraphIndex + (GameGraph::_GRAPH_ID)dwOffset;
			}

			CGameLevelCrossTable::CHeader	tCrossTableHeader;

			tCrossTableHeader.dwVersion			= XRAI_CURRENT_VERSION;
			tCrossTableHeader.dwNodeCount		= tpCrossTable->m_tCrossTableHeader.dwNodeCount;
			tCrossTableHeader.dwGraphPointCount = tpCrossTable->m_tCrossTableHeader.dwGraphPointCount;
			tCrossTableHeader.m_level_guid		= tpCrossTable->m_tCrossTableHeader.m_level_guid;
			tCrossTableHeader.m_game_guid		= tGraphHeader.m_guid;

			xr_delete			(tpCrossTable);

			m_cross_table.w(&tCrossTableHeader,sizeof(tCrossTableHeader));
			for (int i=0; i<(int)tCrossTableHeader.dwNodeCount; i++)
				m_cross_table.w(&(tCrossTableUpdate[i]),sizeof(tCrossTableUpdate[i]));
		}

		// fill vertex map
		{
			string_path								fName;
			strconcat								(sizeof(fName),fName,S,"level.spawn");
			IReader									*F = FS.r_open(fName);
			u32										id;
			IReader									*O = F->open_chunk_iterator(id);
			for (int i=0; O; O = F->open_chunk_iterator(id,O))	{
				NET_Packet							P;
				P.B.count							= O->length();
				O->r								(P.B.data,P.B.count);
				u16									ID;
				P.r_begin							(ID);
				R_ASSERT							(M_SPAWN==ID);
				P.r_stringZ							(fName);
				CSE_Abstract						*E = F_entity_Create(fName);
				R_ASSERT3							(E,"Can't create entity.",fName);
//				E->Spawn_Read						(P);
				CSE_ALifeGraphPoint					*tpGraphPoint = smart_cast<CSE_ALifeGraphPoint*>(E);
				if (tpGraphPoint) {
					E->Spawn_Read					(P);

					Fvector							tVector;
					tVector							= tpGraphPoint->o_Position;
					GameGraph::_GRAPH_ID			tGraphID = GameGraph::_GRAPH_ID(-1);
					float							fMinDistance = 1000000.f;
					{
						GRAPH_VERTEX_IT					B = m_tpVertices.begin();
						GRAPH_VERTEX_IT					I = B;
						GRAPH_VERTEX_IT					E = m_tpVertices.end();
						for ( ; I != E; I++) {
							float fDistance = (*I).tLocalPoint.distance_to(tVector);
							if (fDistance < fMinDistance) {
								fMinDistance	= fDistance;
								tGraphID		= GameGraph::_GRAPH_ID(I - B);
								if (fMinDistance < EPS_L)
									break;
							}
						}
					}
					if (fMinDistance < EPS_L) {
						SConnectionVertex				T;
						LPSTR							S;
						S								= xr_strdup(tpGraphPoint->name_replace());
						T.caConnectName					= xr_strdup(*tpGraphPoint->m_caConnectionPointName);
						T.dwLevelID						= dwfGetIDByLevelName(Ini,*tpGraphPoint->m_caConnectionLevelName);
//						T.tGraphID						= (GameGraph::_GRAPH_ID)i;
//						T.tOldGraphID					= tGraphID;
						T.tOldGraphID					= (GameGraph::_GRAPH_ID)i;
						T.tGraphID						= tGraphID;

						bool							ok = true;
						VERTEX_MAP::const_iterator		II = m_tVertexMap.begin();
						VERTEX_MAP::const_iterator		EE = m_tVertexMap.end();
						for ( ; II != EE; ++II)
							if (T.tOldGraphID == (*II).second.tOldGraphID) {
								ok						= false;
								Msg						("Graph point %s is removed,because it has the same position as some another graph point",E->name_replace());
								break;
							}

						if (ok) {
							m_tVertexMap.insert			(mk_pair(S,T));
							i++;
						}
					}
				}
				F_entity_Destroy					(E);
			}
			if (i != m_tpGraph->header().vertex_count())
				Msg									("Graph for the level %s doesn't correspond to the graph points from Level Editor! (%d : %d)",*m_tLevel.name(),i,m_tpGraph->header().vertex_count());
			
			VERTEX_MAP::const_iterator				I = m_tVertexMap.begin();
			VERTEX_MAP::const_iterator				E = m_tVertexMap.end();
			for ( ; I != E; ++I) {
				R_ASSERT3	(!xr_strlen((*I).second.caConnectName) || ((*I).second.tGraphID < m_tpVertices.size()),"Rebuild graph for the level",*m_tLevel.name());
			}

//			VERIFY3									(i == m_tpGraph->header().vertex_count(), "Rebuild graph for the level ",m_tLevel.name());
			O->close								();
			FS.r_close								(F);
		}
	};
Beispiel #23
0
void xrServer::Process_event	(NET_Packet& P, ClientID sender)
{
#	ifdef SLOW_VERIFY_ENTITIES
			VERIFY					(verify_entities());
#	endif

	u32			timestamp;
	u16			type;
	u16			destination;
	u32			MODE			= net_flags(TRUE,TRUE);

	// correct timestamp with server-unique-time (note: direct message correction)
	P.r_u32		(timestamp	);

	// read generic info
	P.r_u16		(type		);
	P.r_u16		(destination);

	CSE_Abstract*	receiver	= game->get_entity_from_eid	(destination);
	if (receiver)	
	{
		R_ASSERT(receiver->owner);
		receiver->OnEvent						(P,type,timestamp,sender);

	};

	switch		(type)
	{
	case GE_GAME_EVENT:
		{
			u16		game_event_type;
			P.r_u16(game_event_type);
			game->AddDelayedEvent(P,game_event_type,timestamp,sender);
		}break;
	case GE_INFO_TRANSFER:
	case GE_WPN_STATE_CHANGE:
	case GE_ZONE_STATE_CHANGE:
	case GE_ACTOR_JUMPING:
	case GEG_PLAYER_PLAY_HEADSHOT_PARTICLE:
	case GEG_PLAYER_ATTACH_HOLDER:
	case GEG_PLAYER_DETACH_HOLDER:
	case GEG_PLAYER_ITEM2SLOT:
	case GEG_PLAYER_ITEM2BELT:
	case GEG_PLAYER_ITEM2RUCK:
	case GE_GRENADE_EXPLODE:
		{
		SendBroadcast			(BroadcastCID,P,MODE);
		}break;
	case GEG_PLAYER_ACTIVATEARTEFACT:
		{
			Process_event_activate	(P,sender,timestamp,destination,P.r_u16(), true);
			break;
		};
	case GE_INV_ACTION:
		{
			xrClientData* CL		= ID_to_client(sender);
			if (CL)	CL->net_Ready	= TRUE;
			if (SV_Client) SendTo(SV_Client->ID, P, net_flags(TRUE, TRUE));
		}break;
	case GE_RESPAWN:
		{
			CSE_Abstract*		E	= receiver;
			if (E) 
			{
				R_ASSERT			(E->s_flags.is(M_SPAWN_OBJECT_PHANTOM));

				svs_respawn			R;
				R.timestamp			= timestamp	+ E->RespawnTime*1000;
				R.phantom			= destination;
				q_respawn.insert	(R);
			}
		}
		break;
	case GE_TRADE_BUY:
	case GE_OWNERSHIP_TAKE:
		{
			Process_event_ownership	(P,sender,timestamp,destination);
			VERIFY					(verify_entities());
		}break;
	case GE_OWNERSHIP_TAKE_MP_FORCED:
		{
			Process_event_ownership	(P,sender,timestamp,destination,TRUE);
			VERIFY					(verify_entities());
		}break;
	case GE_TRADE_SELL:
	case GE_OWNERSHIP_REJECT:
	case GE_LAUNCH_ROCKET:
		{
			Process_event_reject	(P,sender,timestamp,destination,P.r_u16());
			VERIFY					(verify_entities());
		}break;
	case GE_DESTROY:
		{
			Process_event_destroy	(P,sender,timestamp,destination, NULL);
			VERIFY					(verify_entities());
		}
		break;
	case GE_TRANSFER_AMMO:
		{
			u16					id_entity;
			P.r_u16				(id_entity);
			CSE_Abstract*		e_parent	= receiver;	// кто забирает (для своих нужд)
			CSE_Abstract*		e_entity	= game->get_entity_from_eid	(id_entity);	// кто отдает
			if (!e_entity)		break;
			if (0xffff != e_entity->ID_Parent)	break;						// this item already taken
			xrClientData*		c_parent	= e_parent->owner;
			xrClientData*		c_from		= ID_to_client	(sender);
			R_ASSERT			(c_from == c_parent);						// assure client ownership of event

			// Signal to everyone (including sender)
			SendBroadcast		(BroadcastCID,P,MODE);

			// Perfrom real destroy
			entity_Destroy		(e_entity	);
			VERIFY				(verify_entities());
		}
		break;
	case GE_HIT:
	case GE_HIT_STATISTIC:
		{
			P.r_pos -=2;
			if (type == GE_HIT_STATISTIC) 
			{
				P.B.count -= 4;
				P.w_u32(sender.value());
			};
			game->AddDelayedEvent(P,GAME_EVENT_ON_HIT, 0, ClientID() );
		} break;
	case GE_ASSIGN_KILLER: {
		u16							id_src;
		P.r_u16						(id_src);
		
		CSE_Abstract				*e_dest = receiver;	// кто умер
		// this is possible when hit event is sent before destroy event
		if (!e_dest)
			break;

		CSE_ALifeCreatureAbstract	*creature = smart_cast<CSE_ALifeCreatureAbstract*>(e_dest);
		if (creature)
			creature->set_killer_id( id_src );

//		Msg							("[%d][%s] killed [%d][%s]",id_src,id_src==u16(-1) ? "UNKNOWN" : game->get_entity_from_eid(id_src)->name_replace(),id_dest,e_dest->name_replace());

		break;
	}
	case GE_CHANGE_VISUAL:
		{
			CSE_Visual* visual		= smart_cast<CSE_Visual*>(receiver); VERIFY(visual);
			string256 tmp;
			P.r_stringZ				(tmp);
			visual->set_visual		(tmp);
		}break;
	case GE_DIE:
		{
			// Parse message
			u16					id_dest		=	destination, id_src;
			P.r_u16				(id_src);


			xrClientData *l_pC	= ID_to_client(sender);
			VERIFY				(game && l_pC);
#ifndef MASTER_GOLD
			if ((game->Type() != eGameIDSingle) && l_pC && l_pC->owner)
			{
				Msg					("* [%2d] killed by [%2d] - sended by [%s:%2d]", id_dest, id_src, game->get_option_s(*l_pC->name,"name","Player"), l_pC->owner->ID);
			}
#endif // #ifndef MASTER_GOLD

			CSE_Abstract*		e_dest		= receiver;	// кто умер
			// this is possible when hit event is sent before destroy event
			if (!e_dest)
				break;

#ifndef MASTER_GOLD
			if (game->Type() != eGameIDSingle)
				Msg				("* [%2d] is [%s:%s]", id_dest, *e_dest->s_name, e_dest->name_replace());
#endif // #ifndef MASTER_GOLD

			CSE_Abstract*		e_src		= game->get_entity_from_eid	(id_src	);	// кто убил
			if (!e_src) {
				xrClientData*	C = (xrClientData*)	game->get_client(id_src);
				if (C) e_src = C->owner;
			};
			VERIFY				(e_src);
			if (!e_src)
			{
				Msg("! ERROR: SV: src killer not exist.");
				return;
			}
//			R_ASSERT2			(e_dest && e_src, "Killer or/and being killed are offline or not exist at all :(");
#ifndef MASTER_GOLD
			if (game->Type() != eGameIDSingle)
				Msg				("* [%2d] is [%s:%s]", id_src, *e_src->s_name, e_src->name_replace());
#endif // #ifndef MASTER_GOLD

			game->on_death		(e_dest,e_src);

			xrClientData*		c_src		= e_src->owner;				// клиент, чей юнит убил

			if (c_src->owner->ID == id_src) {
				// Main unit
				P.w_begin			(M_EVENT);
				P.w_u32				(timestamp);
				P.w_u16				(type);
				P.w_u16				(destination);
				P.w_u16				(id_src);
				P.w_clientID		(c_src->ID);
			}

			SendBroadcast			(BroadcastCID,P,MODE);

			//////////////////////////////////////////////////////////////////////////
			// 
			if (game->Type() == eGameIDSingle) {
				P.w_begin			(M_EVENT);
				P.w_u32				(timestamp);
				P.w_u16				(GE_KILL_SOMEONE);
				P.w_u16				(id_src);
				P.w_u16				(destination);
				SendTo				(c_src->ID, P, net_flags(TRUE, TRUE));
			}
			//////////////////////////////////////////////////////////////////////////

			VERIFY					(verify_entities());
		}
		break;
	case GE_ADDON_ATTACH:
	case GE_ADDON_DETACH:
	case GE_CHANGE_POS:
		{			
			SendTo(SV_Client->ID, P, net_flags(TRUE, TRUE));
		}break;
	case GE_INSTALL_UPGRADE:
		{
			shared_str				upgrade_id;
			P.r_stringZ				( upgrade_id );
			CSE_ALifeInventoryItem* iitem = smart_cast<CSE_ALifeInventoryItem*>( receiver );
			if ( !iitem )
			{
				break;
			}
			iitem->add_upgrade		( upgrade_id );
		}break;

	case GEG_PLAYER_DISABLE_SPRINT:
	case GEG_PLAYER_WEAPON_HIDE_STATE:
		{
			SendTo		(SV_Client->ID, P, net_flags(TRUE, TRUE));

#	ifdef SLOW_VERIFY_ENTITIES
			VERIFY					(verify_entities());
#	endif
		}break;
	case GEG_PLAYER_ACTIVATE_SLOT:
	case GEG_PLAYER_ITEM_EAT:
		{
			SendTo(SV_Client->ID, P, net_flags(TRUE, TRUE));
#	ifdef SLOW_VERIFY_ENTITIES
			VERIFY					(verify_entities());
#	endif
		}break;	
	case GEG_PLAYER_ITEM_SELL:
		{
			game->OnPlayer_Sell_Item(sender, P);
		}break;
	case GE_TELEPORT_OBJECT:
		{
			game->teleport_object	(P,destination);
		}break;
	case GE_ADD_RESTRICTION:
		{
			game->add_restriction	(P,destination);
		}break;
	case GE_REMOVE_RESTRICTION:
		{
			game->remove_restriction(P,destination);
		}break;
	case GE_REMOVE_ALL_RESTRICTIONS:
		{
			game->remove_all_restrictions(P,destination);
		}break;
	case GE_MONEY:
		{
			CSE_Abstract				*e_dest = receiver;
			CSE_ALifeTraderAbstract*	pTa = smart_cast<CSE_ALifeTraderAbstract*>(e_dest);
			pTa->m_dwMoney				= P.r_u32();
						
		}break;
	case GE_FREEZE_OBJECT:
		break;
	default:
		R_ASSERT2	(0,"Game Event not implemented!!!");
		break;
	}
}