Пример #1
0
void CAI_Space::validate			(const u32 level_id) const
{
	VERIFY					(level_graph().header().vertex_count() == cross_table().header().level_vertex_count());
	for (GameGraph::_GRAPH_ID i=0, n = game_graph().header().vertex_count(); i<n; ++i)
		if ((level_id == game_graph().vertex(i)->level_id()) && 
			(!level_graph().valid_vertex_id(game_graph().vertex(i)->level_vertex_id()) ||
			(cross_table().vertex(game_graph().vertex(i)->level_vertex_id()).game_vertex_id() != i) ||
			!level_graph().inside(game_graph().vertex(i)->level_vertex_id(),game_graph().vertex(i)->level_point()))) {
			Msg				("! Graph doesn't correspond to the cross table");
			R_ASSERT2		(false,"Graph doesn't correspond to the cross table");
		}

//	Msg						("death graph point id : %d",cross_table().vertex(455236).game_vertex_id());

	for (u32 i=0, n=game_graph().header().vertex_count(); i<n; ++i) {
		if (level_id != game_graph().vertex(i)->level_id())
			continue;

		CGameGraph::const_spawn_iterator	I, E;
		game_graph().begin_spawn			(i,I,E);
//		Msg									("vertex [%d] has %d death points",i,game_graph().vertex(i)->death_point_count());
		for ( ; I != E; ++I) {
			VERIFY							(cross_table().vertex((*I).level_vertex_id()).game_vertex_id() == i);
		}
	}
	

//	Msg						("* Graph corresponds to the cross table");
}
IC	shared_str CGameSpawnConstructor::actor_level_name()
{
	string256						temp;
	return							(
		strconcat(
			sizeof(temp),
			temp,
			*game_graph().header().level(
				game_graph().vertex(
					m_actor->m_tGraphID
				)->level_id()).name(),
			".spawn"
		)
	);
}
Пример #3
0
void CAI_Space::unload				(bool reload)
{
	script_engine().unload	();
	xr_delete				(m_graph_engine);
	xr_delete				(m_level_graph);
	xr_delete				(m_cross_table);
	if (!reload)
		m_graph_engine		= xr_new<CGraphEngine>(game_graph().header().vertex_count());
}
Пример #4
0
void CAI_Space::load				(LPCSTR level_name)
{
//	Msg						("level %s",level_name);
	unload					(true);

#ifdef DEBUG
	Memory.mem_compact		();
	u32						mem_usage = Memory.mem_usage();
	CTimer					timer;
	timer.Start				();
#endif

	m_level_graph			= xr_new<CLevelGraph>();
	m_cross_table			= xr_new<CGameLevelCrossTable>();
	R_ASSERT2				(cross_table().header().level_guid() == level_graph().header().guid(), "cross_table doesn't correspond to the AI-map");
	R_ASSERT2				(cross_table().header().game_guid() == game_graph().header().guid(), "graph doesn't correspond to the cross table");
	m_graph_engine			= xr_new<CGraphEngine>(
		_max(
			game_graph().header().vertex_count(),
			level_graph().header().vertex_count()
		)
	);
	
	const CGameGraph::SLevel &current_level = game_graph().header().level(level_name);
	R_ASSERT2				(current_level.guid() == level_graph().header().guid(), "graph doesn't correspond to the AI-map");
	
#ifdef DEBUG
	if (!xr_strcmp(current_level.name(),level_name))
		validate			(current_level.id());
#endif

	level_graph().level_id	(current_level.id());
	game_graph().set_current_level(current_level.id());

	m_cover_manager->compute_static_cover	();

#ifdef DEBUG
	Msg						("* Loading ai space is successfully completed (%.3fs, %7.3f Mb)",timer.GetElapsed_sec(),float(Memory.mem_usage() - mem_usage)/1048576.0);
#endif
}
Пример #5
0
void CLevelSpawnConstructor::init								()
{
	// loading level graph
	string_path				file_name;
	FS.update_path			(file_name,"$game_levels$",*m_level.name());
	strcat_s				(file_name,"\\");
	m_level_graph			= new CLevelGraph(file_name);
	
	// loading cross table
	m_game_spawn_constructor->game_graph().set_current_level	(game_graph().header().level(*m_level.name()).id());
	m_cross_table			= &game_graph().cross_table();

	// loading patrol paths
	FS.update_path			(file_name,"$game_levels$",*m_level.name());
	strcat					(file_name,"\\level.game");
	if (FS.exist(file_name)) {
		IReader				*stream	= FS.r_open(file_name);
		VERIFY				(stream);
		m_game_spawn_constructor->patrol_path_storage().load_raw(&level_graph(),&cross_table(),&game_graph(),*stream);
		FS.r_close			(stream);
	}
}
Пример #6
0
void CLevelSpawnConstructor::fill_level_changers				()
{
	for (u32 i=0, n=(u32)level_changers().size(); i<n; ++i) {
		if (level_id(level_changers()[i]->m_caLevelToChange) != m_level.id())
			continue;

		bool found = false;
		GRAPH_POINT_STORAGE::const_iterator I = m_graph_points.begin();
		GRAPH_POINT_STORAGE::const_iterator E = m_graph_points.end();
		for ( ; I != E; ++I)
			if (!xr_strcmp(*level_changers()[i]->m_caLevelPointToChange,(*I)->name_replace())) {
				bool ok = false;
				for (u32 ii=0, nn = game_graph().header().vertex_count(); ii<nn; ++ii) {
					if ((game_graph().vertex(ii)->level_id() != m_level.id()) || !game_graph().vertex(ii)->level_point().similar((*I)->o_Position,.001f))
						continue;
					level_changers()[i]->m_tNextGraphID		= (GameGraph::_GRAPH_ID)ii;
					level_changers()[i]->m_tNextPosition	= (*I)->o_Position;
					level_changers()[i]->m_tAngles			= (*I)->o_Angle;
					level_changers()[i]->m_dwNextNodeID		= game_graph().vertex(ii)->level_vertex_id();
					ok										= true;
					break;
				}

				R_ASSERT3					(ok,"Cannot find a correspndance between graph and graph points from level editor! Rebuild graph for the level ",*level_changers()[i]->m_caLevelToChange);

				level_changers().erase		(level_changers().begin() + i);
				--i;
				--n;
				found		= true;
				break;
			}

		if (!found) {
			clMsg			("Graph point %s not found (level changer %s)",*level_changers()[i]->m_caLevelPointToChange,level_changers()[i]->name_replace());
			VERIFY			(false);
		}
	}
}
Пример #7
0
void CLevelSpawnConstructor::correct_level_changers				()
{
	LEVEL_CHANGER_STORAGE::const_iterator	I = m_level_changers.begin();
	LEVEL_CHANGER_STORAGE::const_iterator	E = m_level_changers.end();
	for ( ; I != E; ++I) {
		Fvector				position = (*I)->o_Position;
		position.y			+= y_shift_correction;
		(*I)->m_tNodeID		= level_graph().vertex(u32(-1),position);
		VERIFY				(level_graph().valid_vertex_id((*I)->m_tNodeID));

		u32					dwBest = cross_table().vertex((*I)->m_tNodeID).game_vertex_id();
		VERIFY				(game_graph().vertex(dwBest)->level_id() == m_level.id());
		(*I)->m_tGraphID	= (GameGraph::_GRAPH_ID)dwBest;

		(*I)->m_fDistance	= cross_table().vertex((*I)->m_tNodeID).distance();
	}
}
Пример #8
0
void CAI_Space::init				()
{
	VERIFY					(!m_ef_storage);
	m_ef_storage			= xr_new<CEF_Storage>();

	VERIFY					(!m_game_graph);
	m_game_graph			= xr_new<CGameGraph>();

	VERIFY					(!m_graph_engine);
	m_graph_engine			= xr_new<CGraphEngine>(game_graph().header().vertex_count());

	VERIFY					(!m_cover_manager);
	m_cover_manager			= xr_new<CCoverManager>();

	VERIFY					(!m_patrol_path_storage);
	m_patrol_path_storage	= xr_new<CPatrolPathStorage>();

	VERIFY					(!m_script_engine);
	m_script_engine			= xr_new<CScriptEngine>();
	script_engine().init	();

	extern string4096		g_ca_stdout;
	setvbuf					(stderr,g_ca_stdout,_IOFBF,sizeof(g_ca_stdout));
}
Пример #9
0
void CLevelSpawnConstructor::update_artefact_spawn_positions	()
{
	u32									level_point_count = m_game_spawn_constructor->level_point_count();
	SPAWN_STORAGE::iterator				I = m_spawns.begin();
	SPAWN_STORAGE::iterator				E = m_spawns.end();
	for ( ; I != E; ++I) {
		CSE_Abstract					*abstract = *I;
		CSE_ALifeObject					*alife_object = smart_cast<CSE_ALifeObject*>(abstract);
//		R_ASSERT3						(level_graph().valid_vertex_id(alife_object->m_tNodeID),"Invalid node for object ",alife_object->name_replace());
		R_ASSERT2						(alife_object,"Non-ALife object!");
		VERIFY							(game_graph().vertex(alife_object->m_tGraphID)->level_id() == m_level.id());
//		alife_object->m_spawn_control	= "";
		CSE_ALifeAnomalousZone			*zone = smart_cast<CSE_ALifeAnomalousZone*>(abstract);
		if (zone) {
			zone->m_artefact_position_offset		= level_point_count;
			level_point_count			+= zone->m_artefact_spawn_count;
//			Msg							("%s  %f [%f][%f][%f] : artefact spawn positions",zone->name_replace(),zone->m_fRadius,VPUSH(zone->o_Position));
//			for (u32 i=zone->m_artefact_position_offset; i<level_point_count; ++i)
//				Msg						("    [%f][%f][%f] : %f",VPUSH(m_level_points[i].tPoint),zone->o_Position.distance_to(m_level_points[i].tPoint));
		}
	}

	m_game_spawn_constructor->add_level_points	(m_level_points);
}
void CGameSpawnConstructor::save_spawn				(LPCSTR name, LPCSTR output)
{
	CMemoryWriter					stream;

	m_spawn_header.m_version		= XRAI_CURRENT_VERSION;
	m_spawn_header.m_guid			= generate_guid();
	m_spawn_header.m_graph_guid		= game_graph().header().guid();
	m_spawn_header.m_spawn_count	= spawn_graph().vertex_count();
	m_spawn_header.m_level_count	= (u32)m_level_spawns.size();
	
	stream.open_chunk				(0);
	stream.w_u32					(m_spawn_header.m_version);
	save_data						(m_spawn_header.m_guid,stream);
	save_data						(m_spawn_header.m_graph_guid,stream);
	stream.w_u32					(m_spawn_header.m_spawn_count);
	stream.w_u32					(m_spawn_header.m_level_count);
	stream.close_chunk				();
	
	stream.open_chunk				(1);
	save_data						(spawn_graph(),stream);
	stream.close_chunk				();

	stream.open_chunk				(2);
	save_data						(m_level_points,stream);
	stream.close_chunk				();

	stream.open_chunk				(3);
	save_data						(m_patrol_path_storage,stream);
	stream.close_chunk				();

	stream.open_chunk				(4);
	m_game_graph->save				(stream);
	stream.close_chunk				();

	stream.save_to					(*spawn_name(output));
}
Пример #11
0
void CLevelSpawnConstructor::correct_objects					()
{
	u32						m_level_graph_vertex_id = u32(-1);
	u32						dwStart = game_graph().header().vertex_count(), dwFinish = game_graph().header().vertex_count(), dwCount = 0;
	for (u32 i=0; i<game_graph().header().vertex_count(); ++i)
		if (game_graph().vertex(i)->level_id() == m_level.id()) {
			if (m_level_graph_vertex_id == u32(-1))
				m_level_graph_vertex_id = i;
			dwCount++;
		}
	
	for (int i=0; i<(int)game_graph().header().vertex_count(); i++)
		if (game_graph().vertex(i)->level_id() == m_level.id()) {
			if (dwStart > (u32)i)
				dwStart = (u32)i;
		}
		else {
			if ((dwStart <= (u32)i) && (dwFinish > (u32)i)) {
				dwFinish = i;
				break;
			}
		}
	if (dwStart >= dwFinish) {
		string4096			S;
		sprintf				(S,"There are no graph vertices in the game graph for the level '%s' !\n",*m_level.name());
		R_ASSERT2			(dwStart < dwFinish,S);
	}

	for (int i=0; i<(int)m_spawns.size(); i++) {
		if (!m_spawns[i]->used_ai_locations()) {
			m_spawns[i]->m_tGraphID = (GameGraph::_GRAPH_ID)m_level_graph_vertex_id;
			m_spawns[i]->m_fDistance = 0.f;
			m_spawns[i]->m_tNodeID = game_graph().vertex(m_level_graph_vertex_id)->level_vertex_id();
			continue;
		}
		Fvector				position = m_spawns[i]->o_Position;
		position.y			+= y_shift_correction;
		m_spawns[i]->m_tNodeID = level_graph().vertex(u32(-1),position);
		VERIFY				(level_graph().valid_vertex_id(m_spawns[i]->m_tNodeID));
		if (m_spawns[i]->used_ai_locations() && !level_graph().inside(level_graph().vertex(m_spawns[i]->m_tNodeID),position)) {
			Fvector			new_position = level_graph().vertex_position(m_spawns[i]->m_tNodeID);
			clMsg			("[%s][%s][%s] : position changed from [%f][%f][%f] -> [%f][%f][%f]",*m_level.name(),*m_spawns[i]->s_name,m_spawns[i]->name_replace(),VPUSH(position),VPUSH(new_position));
			m_spawns[i]->o_Position	= new_position;
		}
		u32					dwBest = cross_table().vertex(m_spawns[i]->m_tNodeID).game_vertex_id();
		if (game_graph().vertex(dwBest)->level_id() != m_level.id()) {
			string4096	S1;
			char		*S = S1;
			S			+= sprintf(S,"Corresponding graph vertex for the spawn point is located on the ANOTHER level\n",m_spawns[i]->name_replace());
			S			+= sprintf(S,"Current level  : [%d][%s]\n",m_level.id(),*game_graph().header().level(m_level.id()).name());
			S			+= sprintf(S,"Conflict level : [%d][%s]\n",game_graph().vertex(dwBest)->level_id(),*game_graph().header().level(game_graph().vertex(dwBest)->level_id()).name());
			S			+= sprintf(S,"Probably, you filled offsets in \"game_levels.ltx\" incorrect");
			R_ASSERT2	(game_graph().vertex(dwBest)->level_id() == m_level.id(),S1);
		}

		float				fCurrentBestDistance = cross_table().vertex(m_spawns[i]->m_tNodeID).distance();
		if (dwBest == u32(-1)) {
			string4096	S1;
			char		*S = S1;
			S			+= sprintf(S,"Can't find a corresponding GRAPH VERTEX for the spawn-point %s\n",m_spawns[i]->name_replace());
			S			+= sprintf(S,"Level ID    : %d\n",m_level.id());
			S			+= sprintf(S,"Spawn index : %d\n",i);
			S			+= sprintf(S,"Spawn node  : %d\n",m_spawns[i]->m_tNodeID);
			S			+= sprintf(S,"Spawn point : [%7.2f][%7.2f][%7.2f]\n",m_spawns[i]->o_Position.x,m_spawns[i]->o_Position.y,m_spawns[i]->o_Position.z);
			R_ASSERT2	(dwBest != -1,S1);
		}
		m_spawns[i]->m_tGraphID		= (GameGraph::_GRAPH_ID)dwBest;
		m_spawns[i]->m_fDistance	= fCurrentBestDistance;
	}
}
void CGameSpawnConstructor::process_actor			(LPCSTR start_level_name)
{
	m_actor							= 0;
	
	LEVEL_SPAWN_STORAGE::iterator	I = m_level_spawns.begin();
	LEVEL_SPAWN_STORAGE::iterator	E = m_level_spawns.end();
	for ( ; I != E; ++I) {
		if (!(*I)->actor())
			continue;

		Msg							("Actor is on the level %s",*game_graph().header().level(game_graph().vertex((*I)->actor()->m_tGraphID)->level_id()).name());
		VERIFY2						(!m_actor,"There must be the SINGLE level with ACTOR!");
		m_actor						= (*I)->actor();
	}

	R_ASSERT2						(m_actor,"There is no ACTOR spawn point!");

	if (!start_level_name)
		return;

	if (!xr_strcmp(*actor_level_name(),start_level_name))
		return;

	const CGameGraph::SLevel		&level = game_graph().header().level(start_level_name);
	GameGraph::_GRAPH_ID				dest = GameGraph::_GRAPH_ID(-1);
	GraphEngineSpace::CGameLevelParams	evaluator(level.id());
	CGraphEngine					*graph_engine = xr_new<CGraphEngine>(game_graph().header().vertex_count());

	bool							failed = !graph_engine->search(game_graph(),m_actor->m_tGraphID,GameGraph::_GRAPH_ID(-1),0,evaluator);
	if (failed) {
		Msg							("! Cannot build path via game graph from the current level to the level %s!",start_level_name);
		float						min_dist = flt_max;
		Fvector						current = game_graph().vertex(m_actor->m_tGraphID)->game_point();
		GameGraph::_GRAPH_ID			n = game_graph().header().vertex_count();
		for (GameGraph::_GRAPH_ID i=0; i<n; ++i) {
			if (game_graph().vertex(i)->level_id() == level.id()) {
				float				distance = game_graph().vertex(i)->game_point().distance_to_sqr(current);
				if (distance < min_dist) {
					min_dist		= distance;
					dest			= i;
				}
			}
		}
		if (!game_graph().vertex(dest)) {
			Msg						("! There is no game vertices on the level %s, cannot jump to the specified level",start_level_name);
			return;
		}
	}
	else
		dest						= (GameGraph::_GRAPH_ID)evaluator.selected_vertex_id();

	m_actor->m_tGraphID				= dest;
	m_actor->m_tNodeID				= game_graph().vertex(dest)->level_vertex_id();
	m_actor->o_Position				= game_graph().vertex(dest)->level_point();

	xr_delete						(graph_engine);
}