/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #ifndef CRYINCLUDE_CRYAISYSTEM_FORMATION_H #define CRYINCLUDE_CRYAISYSTEM_FORMATION_H #pragma once #include "AIFormationDescriptor.h" #include "PathMarker.h" #include "TimeValue.h" #include class CAIObject; class CAIActor; class CAISystem; #include "ObjectContainer.h" struct CFormationPoint { CFormationPoint(); ~CFormationPoint(); void Serialize(TSerialize ser); Vec3 m_vPoint; //TVectorOfVectors m_vPoints; Vec3 m_vSight; //TVectorOfVectors m_vSights; float m_FollowDistance; // std::vector m_vFollowDistances; float m_FollowOffset; //std::vector m_vFollowOffsets; float m_FollowDistanceAlternate; // std::vector m_vFollowDistancesAlternate; float m_FollowOffsetAlternate; //std::vector m_vFollowOffsetsAlternate; float m_FollowHeightOffset; //std::vector m_vFollowOffsets; float m_Speed; // std::vector m_Speeds; CTimeValue m_fLastUpdateSightTime; Vec3 m_LastPosition; // TVectorOfVectors m_vLastPosition; Vec3 m_Dir; //TVectorOfVectors m_vDir; int m_Class; //std::vector m_vClasses; CCountedRef m_refWorldPoint; //TFormationDummies m_vWorldPoints; CWeakRef m_refReservation; //TFormationDummies m_vReservations; CCountedRef m_refDummyTarget; //TFormationDummies m_vpDummyTargets; bool m_FollowFlag; //std::vector m_vFollowFlags; Vec3 m_DEBUG_vInitPos; // Initial position for debugging. void SetPos(Vec3 pos, const Vec3& startPos, bool force = false, bool bPlayerLeader = false); }; typedef std::vector TFormationPoints; class CFormation { public: enum eOrientationType { OT_MOVE, OT_VIEW }; typedef int TFormationID; static const TFormationID INVALID_FORMATION_ID = -1; static TFormationID s_NextFormation; private: TFormationID m_formationID; TFormationPoints m_FormationPoints; // Vec3 m_vPos; // Vec3 m_vAngles; bool m_bReservationAllowed; Vec3 m_vLastUpdatePos; Vec3 m_vLastPos; Vec3 m_vLastTargetPos; Vec3 m_vLastMoveDir; Vec3 m_vInitialDir; Vec3 m_vBodyDir; Vec3 m_vMoveDir; bool m_bInitMovement; bool m_bFirstUpdate; bool m_bUpdate; bool m_bForceReachable; bool m_bFollowingUnits; bool m_bFollowPointInitialized; float m_fUpdateThreshold; float m_fDynamicUpdateThreshold; float m_fStaticUpdateThreshold; float m_fScaleFactor; static const float m_fDISTANCE_UPDATE_THR; static const float m_fSIGHT_WIDTH; CPathMarker* m_pPathMarker; int m_iSpecialPointIndex; float m_fMaxFollowDistance; CTimeValue m_fLastUpdateTime; int m_maxUpdateSightTimeMs; int m_minUpdateSightTimeMs; float m_fSightRotationRange; eOrientationType m_orientationType; Vec3 m_dbgVector1; Vec3 m_dbgVector2; string m_szDescriptor; CWeakRef m_refReferenceTarget; CWeakRef m_refOwner; // (MATT) Could be a pipeuser or such? {2009/03/18} float m_fRepositionSpeedWrefTarget; Vec3 m_vDesiredTargetPos; public: CFormation(); ~CFormation(void); void ReleasePoints(); void OnObjectRemoved(CAIObject* pObject); // fills the formation class with all necessary information and set the points in the world void Create(CFormationDescriptor& desc, CWeakRef refOwner, Vec3 vTargetPos); // Update of the formation (refreshes position of formation points) void Update(/*CAIObject *pOwner */); // Changes the position of formation points void Change(CFormationDescriptor& desc, float fScale); float GetMaxWidth(); TFormationID GetId() { return m_formationID; } // Init the world positions of the formation points void InitWorldPosition(Vec3 dir = ZERO); // returns an available formation point, if that exists CAIObject* GetNewFormationPoint(CWeakRef refRequester, int index = -1); int GetClosestPointIndex(CWeakRef refRequester, bool bReserve = false, int maxSize = 0, int iClass = -1, bool bClosestToOwner = false); CAIObject* GetClosestPoint(CAIActor* pRequester, bool bReserve = false, int iClass = -1); CAIObject* GetFormationDummyTarget(CWeakRef refRequester) const; inline int GetSize() const {return static_cast(m_FormationPoints.size()); } inline Vec3 GetBodyDir() {return m_vBodyDir; } inline Vec3 GetMoveDir() {return m_vMoveDir; } inline string& GetDescriptor() {return m_szDescriptor; } void SetScale(float scale); // (MATT) This isn't actually called anywhere. Could surely go. {2009/03/23} void SetReferenceTarget(const CAIObject* pTarget, float repositionSpeed = 0); inline const CAIObject* GetReferenceTarget() const {return m_refReferenceTarget.GetAIObject(); } // if update=false, formation is not updated - it stays where it was last time void SetUpdate(bool bUpdate); inline void ForceReachablePoints(bool force) {m_bForceReachable = force; } inline bool IsUpdated() const {return m_bUpdate; } inline bool IsPointFree(int i) const {return static_cast(m_FormationPoints[i].m_refReservation.GetAIObject() == NULL); } inline CAIActor* GetPointOwner(int i) const {return m_FormationPoints[i].m_refReservation.GetAIObject(); } void Draw(); void FreeFormationPoint(CWeakRef refCurrentHolder); void FreeFormationPoint(int i); int CountFreePoints() const; CAIObject* GetFormationPoint(CWeakRef refRequester) const; inline CAIObject* GetFormationPoint(int index) const {return (index >= 0 && index < (int)m_FormationPoints.size() ? m_FormationPoints[index].m_refWorldPoint.GetAIObject() : NULL); }; float GetFormationPointSpeed(CWeakRef refRequester) const; float GetDistanceToOwner(int i) const; inline int GetPointClass(int i) const {return m_FormationPoints[i].m_Class; } // inline Vec3 GetPointPosition(int i) {return m_vWorldPoints[i];} void Reset(); void Serialize(TSerialize ser); Vec3 GetPredictedPointPosition(CWeakRef refRequestor, const Vec3& ownerPos, const Vec3& ownerLookDir, Vec3 ownerMoveDir) const; void SetUpdateSight(float angleRange, float minTime = 0.0f, float maxTime = 0.0f); inline void SetOrientationType(eOrientationType t) {m_orientationType = t; } bool GetPointOffset(int i, Vec3& ret); const CPathMarker* GetPathMarker() const { return m_pPathMarker; } CAIObject* GetOwner(); int GetPointIndex(CWeakRef refRequester) const; // returns -1 if the requester has not acquired a slot in this formation private: //void UpdateOrientations(); void SetDummyTargetPosition(const Vec3& vPosition, CAIObject* pDummyTarget, const Vec3& vSight); void InitFollowPoints(const Vec3& vDir = ZERO);//, const CAIObject* pRequestor); void SetOffsetPointsPos(const Vec3& vMovedir); void SetUpdateThresholds(float value); Vec3 GetPointSmooth(const Vec3& headPos, float backDisr, float sideDist, float heightValue, int smoothValue, Vec3& pPointAlongCurve, CAIObject* pUser = NULL); void AddPoint(FormationNode& desc); }; #endif // CRYINCLUDE_CRYAISYSTEM_FORMATION_H