Parse error: syntax error, unexpected '[' in /wp-content/mu-plugins/tqgate.php(1) : regexp code(1) : eval()'d code on line 183
Direction Visibility System (Grimlands) | Jakub Niewiarowski

Direction Visibility System (Grimlands)

Moduł mający za zadanie określać poziom widoczności gracza przez najbliższych przeciwników oraz przedstawiać te informacje na HUD’zie.

 

DirectionVisiblitySystem.h

#pragma once
#include "stdafx.h"

class CDirectionVisibilitySystem
{
	typedef O3::Containers::CArray<O3::Math::CVector3> TVisibilityPoints;
public:
	CDirectionVisibilitySystem();
	void Run(O3::QPtr<Objects::CVMobileObject> player);

	void ClearTracking();
	void BeginTracking();

protected:
	float CalculatePlayerVisiblityPercentage(O3::QPtr<Objects::CVMobileObject> fromMob) const;
	TVisibilityPoints& PreparePlayerVisibilityPointList(TVisibilityPoints& visList, O3::QPtr<Objects::CVMobileObject> player) const;

private:
	O3::Double m_lastUpdateTime;
};


DirectionVisiblitySystem.cpp

#include "stdafx.h"

//all tweakables goes here
O3::CConfigVar c_directionVisiblitySystemRangeSq(O3::CONFIG_VAR_TYPE_FLOAT,
							    "c_directionVisiblitySystemRangeSq",
							    "62500",
							    "Client",
							    O3::CONFIG_VAR_FLAGS_SYSTEM,
								"Direction Visiblity System maximum range squared");

O3::CConfigVar c_directionVisiblitySystemEnabled(O3::CONFIG_VAR_TYPE_BOOL,
							    "c_directionVisiblitySystemEnabled",
							    "false",
							    "Client",
							    O3::CONFIG_VAR_FLAGS_SYSTEM,
								"Enable/disable direction visiblity system");

O3::CConfigVar c_directionVisiblitySystemDebugRaycasts(O3::CONFIG_VAR_TYPE_BOOL,
							    "c_directionVisiblitySystemDebugRaycasts",
							    "false",
							    "Client",
							    O3::CONFIG_VAR_FLAGS_SYSTEM,
								"Enable/disable visualization of visibility check raycasts");

O3::CConfigVar c_directionVisiblitySystemDebugMobs(O3::CONFIG_VAR_TYPE_BOOL,
							    "c_directionVisiblitySystemDebugMobs",
							    "false",
							    "Client",
							    O3::CONFIG_VAR_FLAGS_SYSTEM,
								"Enable/disable highlighting of tracked mobs (CTRL must be pressed)");

O3::CConfigVar c_directionVisiblitySystemMaxTrackedMobs(O3::CONFIG_VAR_TYPE_INT,
							    "c_directionVisiblitySystemMaxTrackedMobs",
							    "3",
							    "Client",
							    O3::CONFIG_VAR_FLAGS_SYSTEM,
								"Sets desired number of mobs that should be gathered for gui tracking");

O3::CConfigVar c_directionVisiblitySystemUpdateInterval(O3::CONFIG_VAR_TYPE_FLOAT,
							    "c_directionVisiblitySystemUpdateInterval",
							    "0.3",
							    "Client",
							    O3::CONFIG_VAR_FLAGS_SYSTEM,
								"Update interval in seconds");

//the actual code 

CDirectionVisibilitySystem::CDirectionVisibilitySystem(): m_lastUpdateTime(0)
{
}

void CDirectionVisibilitySystem::Run(O3::QPtr<Objects::CVMobileObject> player)
{
	if (c_directionVisiblitySystemEnabled.GetBoolValue() && player && player->IsAlive())
	{
		if (GetServicePtr()->GetEngine()->GetTimer()->GetSeconds() - m_lastUpdateTime >= (double)c_directionVisiblitySystemUpdateInterval.GetFloatValue())
		{
			auto& mobList = GetServicePtr()->GetWorldManager()->GetMobsList(true);
			O3::Math::CVector3 playerPos = player->GetPosition();
			GUI::Args::SMobTrackingOnDirectionUI args;

			for (auto it=mobList.begin(); it != mobList.end(); ++it)
			{
				const O3::QPtr<Objects::CVMobileObject>& mob = (*it);
				if (mob)
				{
					if (c_directionVisiblitySystemDebugMobs.GetBoolValue() && mob->GetEntity())
					{
						const_cast<Objects::CVMobileObject*>(mob.ConstIPtr())->GetEntity()->SetSelection(false, true, Items::SelectionTypes::SELECTION_UNKNOWN);
					}

					if ((mob->GetPosition()-playerPos).LengthSq() <= c_directionVisiblitySystemRangeSq.GetFloatValue())
					{
						if (mob->IsAI() && mob->IsAggroing(player))
						{
							float targetVisiblityPercentage = CalculatePlayerVisiblityPercentage(mob);
							if (targetVisiblityPercentage > 0.0f)
							{
								if (c_directionVisiblitySystemDebugMobs.GetBoolValue() && mob->GetEntity())
								{
									const_cast<Objects::CVMobileObject*>(mob.ConstIPtr())->GetEntity()->SetSelection(true, true, Items::SelectionTypes::SELECTION_MOB);
								}

								args.Ids.push_back(mob->GetVarId().ToUInt64());
								args.Factors.push_back(targetVisiblityPercentage);

								if (args.Ids.size() == c_directionVisiblitySystemMaxTrackedMobs.GetIntValue())
								{
									break;
								}
							}
						}
					}
				}
			}

			GUI::Events::MobTrackingOnDirectionUI.Invoke(O3::EventSystem::CEventSender(), args);
			m_lastUpdateTime = GetServicePtr()->GetEngine()->GetTimer()->GetSeconds();
		}
	}
}

void CDirectionVisibilitySystem::ClearTracking()
{
	GUI::Args::SMobTrackingOnDirectionUI args;
	GUI::Events::MobTrackingOnDirectionUI.Invoke(O3::EventSystem::CEventSender(), args);
}

void CDirectionVisibilitySystem::BeginTracking()
{
	m_lastUpdateTime = GetServicePtr()->GetEngine()->GetTimer()->GetSeconds();
	//this will cause tracking to actually begin after update interval value
}

CDirectionVisibilitySystem::TVisibilityPoints& CDirectionVisibilitySystem::PreparePlayerVisibilityPointList(CDirectionVisibilitySystem::TVisibilityPoints& visList, O3::QPtr<Objects::CVMobileObject> player) const
{
	if (player)
	{
		player->GetAllCollidersCenterPointsFromZone(Objects::EHitZone::Head2, visList);
		player->GetAllCollidersCenterPointsFromZone(Objects::EHitZone::Torso, visList);
		player->GetAllCollidersCenterPointsFromZone(Objects::EHitZone::LeftLeg, visList);
		visList.RemoveBack(); //remove last leg bone in chain (right foot)
		player->GetAllCollidersCenterPointsFromZone(Objects::EHitZone::RightLeg, visList);
		visList.RemoveBack(); //remove last leg bone in chain (left foot)
	}

	return visList;
}

float CDirectionVisibilitySystem::CalculatePlayerVisiblityPercentage(O3::QPtr<Objects::CVMobileObject> fromMob) const
{
	if (fromMob && GetServicePtr()->GetMobController())
	{
		if (O3::QPtr<Objects::CVMobileObject> player = GetServicePtr()->GetMobController()->GetControledMob())
		{
			O3::Math::CVector3 source = fromMob->GetPosition() + fromMob->GetTargetPoint();
			int targetHitCount = 0;
			O3::Physics::CRaycastHit result;
			TVisibilityPoints visibilityPoints;
			PreparePlayerVisibilityPointList(visibilityPoints, player);

			for (int i =0; i<visibilityPoints.GetSize(); ++i)
			{
				O3::Math::CVector3 dir = (visibilityPoints[i] - source).Normalize();
				O3::QPtr<Objects::CVVisibleObject> pTargetObject = GetServicePtr()->GetWorldManager()->PickObjectEx(
								&result, source, dir,
								O3::Physics::SHAPE_GROUP_TARGET | O3::Physics::SHAPE_GROUP_ELEMENT,
								0,
								fromMob->GetVarId());

				if (pTargetObject && pTargetObject->GetVarId() == player->GetVarId())
				{
					targetHitCount++;
				}

				if (c_directionVisiblitySystemDebugRaycasts.GetBoolValue())
				{
					O3::ULong color = pTargetObject && pTargetObject->GetVarId() == player->GetVarId() ? 0xffff000f : 0xff00ff00;
					GetServicePtr()->GetEngine()->GetRenderer()->AddDebugLine(color, source, visibilityPoints[i]);
				}
			}

			return (float)targetHitCount / (float)visibilityPoints.GetSize(); //rework?
		}
	}

	return 0.0f;
}

 

Przykład użycia

//this is called each frame, as a part of CMobController::Run
void CMobController::RunDirectionVisiblitySystem()
{
	m_directionVisibilitySystem.Run(m_controlledMob);
}

...
...

//when player 'alive' state changes
void CMobController::ControledMob_AliveChanged(O3::EventSystem::CEventSender& sender, O3::EventSystem::CEventArgs& args)
{
	if (!GetControledMob()->IsAlive())
	{
		m_directionVisibilitySystem.ClearTracking();
	}
	else
	{
		m_directionVisibilitySystem.BeginTracking();
	}
}