void UEnvQueryGenerator_OnCircle::GenerateItems(FEnvQueryInstance& QueryInstance) const
{
	float AngleDegree = 360.f;
	float RadiusValue = 0.f;
	float ItemSpace = 1.0f;

	if (QueryInstance.GetParamValue(Angle, AngleDegree, TEXT("Angle")) == false
		|| QueryInstance.GetParamValue(Radius, RadiusValue, TEXT("Radius")) == false
		|| QueryInstance.GetParamValue(ItemSpacing, ItemSpace, TEXT("ItemSpacing")) == false
		|| AngleDegree <= 0.f || AngleDegree > 360.f
		|| RadiusValue <= 0.f)
	{
		return;
	}

	AngleRadians = FMath::DegreesToRadians(Angle.Value);

	// first generate points on a circle
	const float CircumferenceLength = 2.f * PI * RadiusValue;
	const float ArcAnglePercentage = Angle.Value / 360.f;
	const float ArcLength = CircumferenceLength * ArcAnglePercentage;
	const int32 StepsCount = FMath::CeilToInt(ArcLength / ItemSpace) + 1;
	const float AngleStep = AngleDegree / (StepsCount - 1);

	FVector StartDirection = CalcDirection(QueryInstance);
	TArray<FVector> CenterLocationCandidates;
	QueryInstance.PrepareContext(CircleCenter, CenterLocationCandidates);

	StartDirection = StartDirection.RotateAngleAxis(-AngleDegree/2, FVector::UpVector) * RadiusValue;

	int NumCenterLocations = CenterLocationCandidates.Num();
	if (NumCenterLocations > 0)
	{
		for (int i = 0; i < NumCenterLocations; ++i)
		{
			GenerateItemsForCircle(CenterLocationCandidates[i], StartDirection, StepsCount, AngleStep, QueryInstance);
		}
	}
	else
	{
		FVector CenterLocation(0);

		AActor* Querier = Cast<AActor>(QueryInstance.Owner.Get());
		if (Querier)
		{
			CenterLocation = Querier->GetActorLocation();
		}

		GenerateItemsForCircle(CenterLocation, StartDirection, StepsCount, AngleStep, QueryInstance);
	}
}
void UEnvQueryGenerator_OnCircle::GenerateItems(FEnvQueryInstance& QueryInstance) const
{
	CircleRadius.BindData(QueryInstance.Owner.Get(), QueryInstance.QueryID);
	SpaceBetween.BindData(QueryInstance.Owner.Get(), QueryInstance.QueryID);
	ArcAngle.BindData(QueryInstance.Owner.Get(), QueryInstance.QueryID);

	float AngleDegree = ArcAngle.GetValue();
	float RadiusValue = CircleRadius.GetValue();
	float ItemSpace = SpaceBetween.GetValue();

	if ((AngleDegree <= 0.f) || (AngleDegree > 360.f) || (RadiusValue <= 0.f) || (ItemSpace <= 0.f))
	{
		return;
	}

	AngleRadians = FMath::DegreesToRadians(AngleDegree);

	// first generate points on a circle
	const float CircumferenceLength = 2.f * PI * RadiusValue;
	const float ArcAnglePercentage = AngleDegree / 360.f;
	const float ArcLength = CircumferenceLength * ArcAnglePercentage;
	const int32 StepsCount = FMath::CeilToInt(ArcLength / ItemSpace) + 1;
	const float AngleStep = AngleDegree / (StepsCount - 1);

	FVector StartDirection = CalcDirection(QueryInstance);
	StartDirection = StartDirection.RotateAngleAxis(-AngleDegree/2, FVector::UpVector) * RadiusValue;
	
	// gather context with raw data, so it can be used by derived generators
	FEnvQueryContextData ContextData;
	const bool bSuccess = QueryInstance.PrepareContext(CircleCenter, ContextData);

	if (bSuccess && ContextData.ValueType && ContextData.ValueType->IsChildOf(UEnvQueryItemType_VectorBase::StaticClass()))
	{
		UEnvQueryItemType_VectorBase* DefTypeOb = (UEnvQueryItemType_VectorBase*)ContextData.ValueType->GetDefaultObject();
		const uint16 DefTypeValueSize = DefTypeOb->GetValueSize();
		uint8* RawData = ContextData.RawData.GetData();

		for (int32 ValueIndex = 0; ValueIndex < ContextData.NumValues; ValueIndex++)
		{
			const FVector ContextItemLocation = DefTypeOb->GetItemLocation(RawData);
			GenerateItemsForCircle(RawData, DefTypeOb, ContextItemLocation, StartDirection, StepsCount, AngleStep, QueryInstance);

			RawData += DefTypeValueSize;
		}
	}
}
Esempio n. 3
0
void CMapLocation::UpdateSpot(CUICustomMap* map, CMapSpot* sp )
{
	if( map->MapName() == GetLevelName() )
	{
		bool b_alife = !!ai().get_alife();

		if ( b_alife && m_flags.test(eHideInOffline) && !m_owner_se_object->m_bOnline )
		{
			return;
		}

		if ( b_alife && m_owner_se_object->m_flags.test(CSE_ALifeObject::flVisibleForMap) == FALSE )
		{
			return;
		}

		if ( IsGameTypeSingle() )
		{
			CGameTask* ml_task = Level().GameTaskManager().HasGameTask( this, true );
			if ( ml_task )
			{
				CGameTask* active_task = Level().GameTaskManager().ActiveTask();
				bool border_show = ( ml_task == active_task );
				if ( m_minimap_spot )
				{
					m_minimap_spot->show_static_border( border_show );
				}
				if ( m_level_spot )
				{
					m_level_spot->show_static_border( border_show );
				}
				if ( m_complex_spot )
				{
					m_complex_spot->show_static_border( border_show );
				}
			}
		}

		//update spot position
		Fvector2 position	= GetPosition();

		m_position_on_map	= map->ConvertRealToLocal(position, (map->Heading())?false:true); //for visibility calculating

		sp->SetWndPos		(m_position_on_map);

		Frect wnd_rect		= sp->GetWndRect();

		if ( map->IsRectVisible(wnd_rect) ) 
		{
			//update heading if needed
			if( sp->Heading() && !sp->GetConstHeading() )
			{
				Fvector2 dir_global = CalcDirection();
				float h = dir_global.getH();
				float h_ = map->GetHeading()+h;
				sp->SetHeading( h_ );
			}
			map->AttachChild	(sp);
		}

		if ( IsGameTypeSingle() )
		{
			CMapSpot* s = GetSpotBorder( sp );
			if ( s )
			{
				s->SetWndPos( sp->GetWndPos() );
				map->AttachChild( s );
			}
		}


		bool b_pointer =( GetSpotPointer(sp) && map->NeedShowPointer(wnd_rect));

		if(map->Heading())
		{
			m_position_on_map	= map->ConvertRealToLocal(position, true); //for drawing
			sp->SetWndPos		(m_position_on_map);
		}

		if(b_pointer)
			UpdateSpotPointer( map, GetSpotPointer(sp) );
	}
	else if ( Level().name() == map->MapName() && GetSpotPointer(sp) )
	{
		GameGraph::_GRAPH_ID		dest_graph_id;

		dest_graph_id		= m_owner_se_object->m_tGraphID;

		map_point_path.clear();

		VERIFY( Actor() );
		GraphEngineSpace::CGameVertexParams		params(Actor()->locations().vertex_types(),flt_max);
		bool res = ai().graph_engine().search(
			ai().game_graph(),
			Actor()->ai_location().game_vertex_id(),
			dest_graph_id,
			&map_point_path,
			params
			);

		if ( res )
		{
			xr_vector<u32>::reverse_iterator it = map_point_path.rbegin();
			xr_vector<u32>::reverse_iterator it_e = map_point_path.rend();

			xr_vector<CLevelChanger*>::iterator lit = g_lchangers.begin();
			//xr_vector<CLevelChanger*>::iterator lit_e = g_lchangers.end();
			bool bDone						= false;
			//for(; (it!=it_e)&&(!bDone) ;++it){
			//	for(lit=g_lchangers.begin();lit!=lit_e; ++lit){

			//		if((*it)==(*lit)->ai_location().game_vertex_id() )
			//		{
			//			bDone = true;
			//			break;
			//		}

			//	}
			//}
			static bool bbb = false;
			if(!bDone&&bbb)
			{
				Msg("! Error. Path from actor to selected map spot does not contain level changer :(");
				Msg("Path:");
				xr_vector<u32>::iterator it			= map_point_path.begin();
				xr_vector<u32>::iterator it_e		= map_point_path.end();
				for(; it!=it_e;++it){
					//					Msg("%d-%s",(*it),ai().game_graph().vertex(*it));
					Msg("[%d] level[%s]",(*it),*ai().game_graph().header().level(ai().game_graph().vertex(*it)->level_id()).name());
				}
				Msg("- Available LevelChangers:");
				xr_vector<CLevelChanger*>::iterator lit,lit_e;
				lit_e							= g_lchangers.end();
				for(lit=g_lchangers.begin();lit!=lit_e; ++lit){
					GameGraph::_GRAPH_ID gid = (*lit)->ai_location().game_vertex_id();
					Msg("[%d]",gid);
					Fvector p = ai().game_graph().vertex(gid)->level_point();
					Msg("lch_name=%s pos=%f %f %f",*ai().game_graph().header().level(ai().game_graph().vertex(gid)->level_id()).name(), p.x, p.y, p.z);
				}


			};
			if(bDone)
			{
				Fvector2 position;
				position.set			((*lit)->Position().x, (*lit)->Position().z);
				m_position_on_map		= map->ConvertRealToLocal(position, false);
				UpdateSpotPointer		(map, GetSpotPointer(sp));
			}
			else
			{
				xr_vector<u32>::reverse_iterator it = map_point_path.rbegin();
				xr_vector<u32>::reverse_iterator it_e = map_point_path.rend();
				for(; (it!=it_e)&&(!bDone) ;++it)
				{
					if(*ai().game_graph().header().level(ai().game_graph().vertex(*it)->level_id()).name()==Level().name())
						break;
				}
				if(it!=it_e)
				{
					Fvector p = ai().game_graph().vertex(*it)->level_point();
					if(Actor()->Position().distance_to_sqr(p)>45.0f*45.0f)
					{
						Fvector2 position;
						position.set			(p.x, p.z);
						m_position_on_map		= map->ConvertRealToLocal(position, false);
						UpdateSpotPointer		(map, GetSpotPointer(sp));
					}
				}
			}
		}
	}


}