This commit is contained in:
romkazvo
2023-08-07 19:29:24 +08:00
commit 34d6c5d489
4832 changed files with 1389451 additions and 0 deletions

77
CryAISystem/GoalPipe.h Normal file
View File

@@ -0,0 +1,77 @@
// GoalPipe.h: interface for the CGoalPipe class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_GOALPIPE_H__12BD0344_3B3F_4B55_8500_25581ECF7ACC__INCLUDED_)
#define AFX_GOALPIPE_H__12BD0344_3B3F_4B55_8500_25581ECF7ACC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "IAgent.h"
#include <vector>
#include <string>
#include "pointer_container.h"
class CGoalOp;
class CAISystem;
typedef pointer_container<CGoalOp> GoalPointer;
typedef struct QGoal
{
string name;
GoalPointer pGoalOp;
bool bBlocking;
GoalParameters params;
QGoal()
{
pGoalOp = 0;
bBlocking = false;
}
} QGoal;
typedef std::vector<QGoal> GoalQueue;
/*! This class defines a logical set of actions that an agent performs in succession.
*/
class CGoalPipe : public IGoalPipe
{
CAISystem *m_pAISystem;
GoalQueue m_qGoalPipe;
unsigned int m_nPosition; // position in pipe
CGoalPipe *m_pSubPipe;
public:
void Reset();
CGoalPipe * Clone();
CGoalPipe(const string &name, CAISystem *pAISystem);
virtual ~CGoalPipe();
// IGoalPipe
void PushGoal(const string &pName, bool bBlocking,GoalParameters &params);
GoalPointer PopGoal(bool &blocking, string &name, GoalParameters &params,CPipeUser *pOperand);
string m_sName; // name of this pipe
CAIObject *m_pArgument;
// Makes the IP of this pipe jump to the desired position
void Jump(int position);
bool IsInSubpipe(void);
CGoalPipe * GetSubpipe(void);
void SetSubpipe(CGoalPipe * pPipe);
size_t MemStats();
int GetPosition() { return m_nPosition;}
void SetPosition(int iNewPos) { if ((iNewPos>0) && (iNewPos<(m_qGoalPipe.size()))) m_nPosition=iNewPos;}
};
#endif // !defined(AFX_GOALPIPE_H__12BD0344_3B3F_4B55_8500_25581ECF7ACC__INCLUDED_)

2963
CryAISystem/Graph.cpp Normal file

File diff suppressed because it is too large Load Diff

303
CryAISystem/Graph.h Normal file
View File

@@ -0,0 +1,303 @@
// Graph.h: interface for the CGraph class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_GRAPH_H__6D059D2E_5A74_4352_B3BF_2C88D446A2E1__INCLUDED_)
#define AFX_GRAPH_H__6D059D2E_5A74_4352_B3BF_2C88D446A2E1__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "IAgent.h"
#include "Heuristic.h"
#include <list>
#include <map>
#include <vector>
#ifdef LINUX
#include <winbase.h>
#endif
#define BAI_FILE_VERSION 30
struct IRenderer;
class CCryFile;
#define PATHFINDER_STILLTRACING 0
#define PATHFINDER_WALKINGBACK 1
#define PATHFINDER_BEAUTIFYINGPATH 2
#define PATHFINDER_POPNEWREQUEST 3
#define PATHFINDER_CLEANING_GRAPH 4
#define PATHFINDER_PATHFOUND 10
#define PATHFINDER_NOPATH 11
#define PATHFINDER_ITERATIONS 30
class CAISystem;
struct IStatObj;
class ICrySizer;
class CAIObject;
struct IVisArea;
typedef struct NodeDescriptor
{
int64 id; //AMD Port
bool bCreated;
int building;
GameNodeData data;
bool bEntrance;
bool bExit;
int nObstacles;
int obstacle[10];
int pad; //padding to make it aligned to a multiple of 8 byte, be careful when changing it
} NodeDescriptor;
typedef std::list<GraphNode *> ListNodes;
typedef std::vector<GraphNode *> VectorNodes;
typedef struct NodeWithHistory
{
GraphNode *pNode;
ListNodes lstParents;
} NodeWithHistory;
typedef struct LinkDescriptor
{
int64 nSourceNode; //AMD Port
int64 nTargetNode;
float fMaxPassRadius;
char nStartIndex,nEndIndex;
Vec3d vEdgeCenter;
Vec3d vWayOut;
} LinkDescriptor;
class CHeuristic;
typedef std::multimap<float,GraphNode*> CandidateMap;
typedef std::multimap<float,NodeWithHistory> CandidateHistoryMap;
// NOTE: INT_PTR here avoids a tiny performance impact on 32-bit platform
// for the cost of loss of full compatibility: 64-bit generated BAI files
// can't be used on 32-bit platform safely. Change the key to int64 to
// make it fully compatible. The code that uses this map will be recompiled
// to use the full 64-bit key on both 32-bit and 64-bit platforms.
typedef std::multimap<INT_PTR,GraphNode*> EntranceMap;
typedef std::list<Vec3d> ListPositions;
typedef std::list<ObstacleData> ListObstacles;
typedef std::list<GraphNode*>::iterator graphnodeit;
typedef std::vector<NodeDescriptor> NodeBuffer;
typedef std::vector<GraphNode> NodeMemory;
typedef std::vector<int> LinkBuffer;
typedef std::vector<LinkDescriptor> LinkDescBuffer;
class CGraph : public IGraph
{
protected:
int m_nAStarDistance;
GraphNode *m_pCurrent;
GraphNode *m_pPathfinderCurrent;
// GraphNode *m_pFirst;
GraphNode *m_pPathBegin;
GraphNode *m_pWalkBackCurrent;
CHeuristic *m_pHeuristic;
CandidateHistoryMap m_mapCandidates; // used by pathfinder
CandidateMap m_mapGreedyWalkCandidates; // used by get enclosing
VectorNodes m_lstTagTracker; // for quick cleaning of the tag
VectorNodes m_lstMarkTracker; // for quick cleaning of the mark
ListNodes m_lstDeleteStack; // for non-recursive deletion of the graph (stack emulator)
ListNodes m_lstNodeStack;
ListNodes m_lstLastPath;
NodeBuffer m_vBuffer;
LinkBuffer m_vLinks;
LinkDescBuffer m_vLinksDesc;
EntranceMap m_mapReadNodes; // when the graph is read
NodeMemory m_vNodes;
Vec3d m_vBBoxMin;
Vec3d m_vBBoxMax;
CAISystem *m_pAISystem;
ListNodes::iterator m_iFirst, m_iSecond, m_iThird;
Vec3d m_vBeautifierStart;
Vec3d m_vLastIntersection;
bool m_bBeautifying;
CAIObject* m_pRequester; // the puppet which whant's the path
public:
void SetRequester( CAIObject* rq) {m_pRequester = rq;}
CAIObject* GetRequester( ) { return m_pRequester;}
GraphNode * CheckClosest(GraphNode *pCurrent, const Vec3d &pos);
void ClearDebugFlag(GraphNode *pNode);
int WalkBack(GraphNode *pBegin,GraphNode *pEnd, int &nIterations);
int ContinueAStar(GraphNode *pEnd, int &nIterations);
bool ClearTags();
int WalkAStar(GraphNode *pBegin, GraphNode *pEnd,int &nIterations);
void DEBUG_DrawCenters(GraphNode *pNode, IRenderer *pRenderer,int dist);
void GetFieldCenter(Vec3d &pos);
void DrawPath(IRenderer *pRenderer);
void WriteToFile(const char *pname);
void Connect(GraphNode *one, GraphNode *two);
void DisableInSphere(const Vec3 &pos,float fRadius);
void EnableInSphere(const Vec3 &pos,float fRadius);
CGraph(CAISystem *);
virtual ~CGraph();
CandidateMap m_lstVisited; // debug map... remove later
EntranceMap m_mapEntrances;
EntranceMap m_mapExits;
GraphNode *m_pFirst;
GraphNode *m_pSafeFirst;
ListPositions m_lstPath;
ListNodes m_lstTrapNodes;
ListNodes m_lstSaveStack;
ListNodes m_lstCurrentHistory;
int nNodes;
float m_fDistance;
Vec3d m_vRealPathfinderEnd;
ListNodes m_lstNodesInsideSphere;
ListObstacles m_lstSelected;
GraphNode *GetCurrent();
virtual GraphNode *GetEnclosing(const Vec3d &pos, GraphNode *pStart = 0 ,bool bOutsideOnly = false);
protected:
int GetNodesInSphere(const Vec3 &pos, float fRadius);
void DeleteGraph(GraphNode *, int depth);
void ClearPath();
void EvaluateNode(GraphNode *pNode,GraphNode *pEnd, GraphNode *pParent);
GraphNode * ASTARStep(GraphNode *pBegin, GraphNode *pEnd);
void DebugWalk(GraphNode *pNode, const Vec3d &pos);
#ifndef __MWERKS__
GraphNode *WriteLine(GraphNode *pNode);
#endif
private:
int m_nTagged;
public:
void TagNode(GraphNode *pNode);
void Disconnect(GraphNode * pDisconnected, bool bDelete = true);
// walk that will always produce a result, for indoors
void IndoorDebugWalk(GraphNode * pNode, const Vec3d & pos, IVisArea *pArea = 0);
// Clears the tags of the graph without time-slicing the operation
void ClearTagsNow(void);
// Check whether a position is within a node's triangle
bool PointInTriangle(const Vec3d & pos, GraphNode * pNode);
// uses mark for internal graph operation without disturbing the pathfinder
void MarkNode(GraphNode * pNode);
public:
// clears the marked nodes
void ClearMarks(bool bJustClear = false);
protected:
// iterative function to quickly converge on the target position in the graph
GraphNode * GREEDYStep(GraphNode * pBegin, const Vec3d & pos, bool bIndoor = false);
public:
// adds an entrance for easy traversing later
void AddIndoorEntrance(int nBuildingID, GraphNode* pNode, bool bExitOnly = false);
// Reads the AI graph from a specified file
bool ReadFromFile(const char * szName);
// reads all the nodes in a map
bool ReadNodes( CCryFile &file );
// defines bounding rectangle of this graph
void SetBBox(const Vec3d & min, const Vec3d & max);
// how is that for descriptive naming of functions ??
bool OutsideOfBBox(const Vec3d & pos);
void FillGreedyMap(GraphNode * pNode, const Vec3d &pos, IVisArea *pTargetArea, bool bStayInArea);
bool RemoveEntrance(int nBuildingID, GraphNode * pNode);
void RemoveIndoorNodes(void);
void REC_RemoveNodes(GraphNode * pNode);
GraphNode * CreateNewNode(bool bFromTriangulation = false);
void DeleteNode(GraphNode * pNode);
int SelectNodesInSphere(const Vec3d & vCenter, float fRadius, GraphNode *pStart = 0);
void SelectNodeRecursive(GraphNode* pNode, const Vec3d & vCenter, float fRadius);
void SelectNodesRecursiveIndoors(GraphNode * pNode, const Vec3d & vCenter, float fRadius, float fDistance);
void AddHidePoint(GraphNode* pOwner, const Vec3d & pos, const Vec3d & dir);
void RemoveHidePoint(GraphNode * pOwner, const Vec3d & pos, const Vec3d & dir);
void DisconnectUnreachable(void);
void DisconnectLink(GraphNode * one, GraphNode * two, bool bOneWay = false);
int BeautifyPath(int &nIterations, const Vec3d &start, const Vec3d &end);
int BeautifyPathCar(int &nIterations, const Vec3d &start, const Vec3d &end);
int BeautifyPathCarOld(int &nIterations, const Vec3d &start, const Vec3d &end);
void ResolveLinkData(GraphNode* pOne, GraphNode* pTwo);
// merging, optimization stuff
typedef std::multimap< float, GraphNode* > NodesList;
//******
typedef std::list<int> ObstacleIndexList;
int Rearrange( ListNodes& nodesList, const Vec3d& cutStart, const Vec3d& cutEnd );
bool ProcessRearrange( GraphNode *node1, GraphNode *node2, ListNodes& nodesList );
int ProcessRearrange( ListNodes& nodesList, const Vec3d& cutStart, const Vec3d& cutEnd );
// bool ProcessMerge( GraphNode *curNode, ListNodes& nodesList );
int ProcessMegaMerge( ListNodes& nodesList, const Vec3d& cutStart, const Vec3d& cutEnd );
// bool CreateOutline( ListNodes& insideNodes, ListNodes& nodesList, ListPositions& outline);
//******
bool CreateOutline( ListNodes& insideNodes, ListNodes& nodesList, ObstacleIndexList& outline);
//******
void TriangulateOutline( ListNodes& nodesList, ObstacleIndexList& outline, bool orientation );
bool ProcessMerge( GraphNode *curNode, CGraph::NodesList& ndList );
// GraphNode* CanMerge( GraphNode *curNode, int& curIdxToDelete, int& curIdxToKeep, int& nbrIdxToDelete, int& nbrIdxToKeep );
// bool CanMergeNbr( GraphNode *nbr1, GraphNode *nbr2 );
// GraphNode* DoMerge( GraphNode *node1, GraphNode *node2, int curIdxToDelete, int curIdxToKeep, int nbrIdxToDelete, int nbrIdxToKeep );
void ConnectNodes(ListNodes & lstNodes);
void FillGraphNodeData(GraphNode* pNode);
size_t MemStats( );
bool DbgCheckList( ListNodes& nodesList ) const;
void SetCurrentHeuristic(unsigned int heuristic_type);
void ResolveTotalLinkData(void);
bool CanReuseLastPath(GraphNode * pBegin);
GraphNode * GetThirdNode(const Vec3d & vFirst, const Vec3d & vSecond, const Vec3d & vThird);
ListPositions m_DEBUG_outlineListL;
ListPositions m_DEBUG_outlineListR;
void Reset(void);
void FindTrapNodes(GraphNode *pNode, int recCount);
GraphNode * GetEntrance(int nBuildingID,const Vec3d &pos);
void RemoveDegenerateTriangle(GraphNode * pDegenerate, bool bRecurse = true);
void FixDegenerateTriangles(void);
};
#endif // !defined(AFX_GRAPH_H__6D059D2E_5A74_4352_B3BF_2C88D446A2E1__INCLUDED_)

1166
CryAISystem/GraphUtility.cpp Normal file

File diff suppressed because it is too large Load Diff

174
CryAISystem/Heuristic.cpp Normal file
View File

@@ -0,0 +1,174 @@
// Heuristic.cpp: implementation of the CHeuristic class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "IAgent.h"
#include "Heuristic.h"
#include "Graph.h"
#include "AIObject.h"
#include "Cry_Math.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHeuristic::CHeuristic()
{
}
CHeuristic::~CHeuristic()
{
}
float CHeuristic::Estimate(GraphNode *pNode, CGraph* graph)
{
// DEFAULT HEURISTIC LIKES EVERYTHING :)
//if (m_BaseValues.bWater != data.bWater) return 0;
// float diff;
// diff = m_BaseValues.fSlope - data.fSlope;
return 1;
}
float CStandardHeuristic::Estimate(GraphNode *pNode, CGraph* graph)
{
float estimation = 0.0f;
GameNodeData data = pNode->data;
// avoids water
// if (data.bWater)
// return estimation;
// avoids big slopes
//estimation = 1 - data.fSlope;
// calculate minimum distance from all tagged neighboors
float mindist = 1000.f; // an arbitrary large value
GraphNode *pPrevious = 0;
VectorOfLinks::iterator vli;
for (vli=pNode->link.begin();vli!=pNode->link.end();vli++)
{
if ((*vli).pLink->tag)
{
float dist = ((*vli).pLink->data.m_pos - pNode->data.m_pos).GetLength();
if (dist < mindist)
{
mindist = dist;
pPrevious = (*vli).pLink;
}
}
}
if (pPrevious)
{
// paths that are very much longer than the straight path should be suppressed
pNode->fDistance = pPrevious->fDistance + mindist;
estimation += 1.f - (pNode->fDistance / graph->m_fDistance) * 0.5f;
}
return estimation;
}
float CVehicleHeuristic::Estimate(GraphNode *pNode, CGraph* graph)
{
float estimation = 0.0f;
Vec3d candidateDir;
Vec3d curDir;
GraphNode *pPrev = 0;
float maxheur=pNode->fHeuristic;
//VectorOfLinks::iterator vi;
bool firstStep = false;
//return 1;
if( pNode->nBuildingID<0 ) // outdoors
{
CStandardHeuristic outdoorHeur;
estimation = outdoorHeur.Estimate(pNode, graph);
// just use it for now - somehove vehicle heuristic seems not to work, blin
return estimation;
// return outdoorHeur.Estimate(pNode, graph);
}
//return 5 - estimation;
size_t sz = graph->m_lstCurrentHistory.size();
if(sz>2)
int tooBig=1;
if(graph->m_lstCurrentHistory.size()==2)
{
ListNodes::iterator prev = graph->m_lstCurrentHistory.begin();
ListNodes::iterator prevPrev = prev;
++prevPrev;
curDir = (*graph->m_lstCurrentHistory.begin())->data.m_pos - (*(++graph->m_lstCurrentHistory.begin()))->data.m_pos;
candidateDir = pNode->data.m_pos - (*graph->m_lstCurrentHistory.begin())->data.m_pos;
}
else if(graph->m_lstCurrentHistory.size()==1)
{
curDir = (*graph->m_lstCurrentHistory.begin())->data.m_pos - graph->GetRequester()->GetPos();
candidateDir = pNode->data.m_pos - (*graph->m_lstCurrentHistory.begin())->data.m_pos;
}
else
{
Vec3d vAngles = graph->GetRequester()->GetAngles();
curDir = Vec3d(0, -1, 0);
Matrix44 mat;
mat.SetIdentity();
mat=Matrix44::CreateRotationZYX(-gf_DEGTORAD*vAngles)*mat; //NOTE: angles in radians and negated
curDir = mat.TransformPointOLD(curDir);
candidateDir = pNode->data.m_pos - graph->GetRequester()->GetPos();
firstStep = true;
}
candidateDir.z = 0.0f;
curDir.z = 0.0f;
candidateDir.normalize();
curDir.normalize();
float dotz = candidateDir.x * curDir.x + candidateDir.y * curDir.y;
// if( fabs(dotz)<.05f )
// return estimation;
if(firstStep) // first step - use requester direction)
{
if( dotz<0.0f ) // it's behind
dotz = (dotz + 1.0f)*.2f;
else
{
// if(dotz < .8f)
// dotz = .8f + (dotz-.8f)*.2f;
dotz = .2f + dotz*dotz*dotz*dotz*5.0f;
}
}
else
{
if( dotz<0.0f ) // it's behind
dotz = (dotz + 1.0f)*.2f;
else
{
// if(dotz > .8f)
// dotz = .8f + (dotz-.8f)*.2f;
dotz = .2f + dotz*dotz*8.37f;
}
}
// estimation = dotz*.7f + (1 - pNode->data.fSlope)*.3f;
// estimation = dotz;//*.7f + (1 - data.fSlope)*.3f;
// estimation += dotz*.3f;//*.7f + (1 - data.fSlope)*.3f;
estimation += dotz*.3f;//*.7f + (1 - data.fSlope)*.3f;
// avoids water
// if (data.bWater)
// return 0;
// avoids big slopes
return estimation;
}

38
CryAISystem/Heuristic.h Normal file
View File

@@ -0,0 +1,38 @@
// Heuristic.h: interface for the CHeuristic class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_HEURISTIC_H__84C857C2_E03E_46B5_B45F_1F0E470A7352__INCLUDED_)
#define AFX_HEURISTIC_H__84C857C2_E03E_46B5_B45F_1F0E470A7352__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CGraph;
class CHeuristic
{
//GameNodeData m_BaseValues;
public:
CHeuristic(/*const GameNodeData &basevalues*/);
virtual ~CHeuristic();
virtual float Estimate(GraphNode *pNode, CGraph* graph );
};
class CStandardHeuristic : public CHeuristic
{
public:
float Estimate(GraphNode *pNode, CGraph* graph);
};
class CVehicleHeuristic : public CHeuristic
{
public:
float Estimate(GraphNode *pNode, CGraph* graph);
};
#endif // !defined(AFX_HEURISTIC_H__84C857C2_E03E_46B5_B45F_1F0E470A7352__INCLUDED_)

2
CryAISystem/IAgent.cpp Normal file
View File

@@ -0,0 +1,2 @@
#include "stdafx.h"
#include "IAgent.h"

5
CryAISystem/MSSCCPRJ.SCC Normal file
View File

@@ -0,0 +1,5 @@
SCC = This is a source code control file
[CryAISystem.vcproj]
SCC_Aux_Path = "P4SCC#perforce:1666##marcoc_code##PC018"
SCC_Project_Name = Perforce Project

427
CryAISystem/PipeUser.cpp Normal file
View File

@@ -0,0 +1,427 @@
#include "stdafx.h"
#include "CAISystem.h"
#include <ISystem.h>
#include <IConsole.h>
#include <ITimer.h>
#include "GoalOp.h"
#include "pipeuser.h"
#include <stream.h>
CPipeUser::CPipeUser(void)
{
m_bMovementSupressed = false;
m_bDirectionalNavigation = false;
m_pReservedNavPoint = 0;
m_AvoidingCrowd = false;
m_bHiding = false;
m_bStartTiming = false;
m_fEngageTime = 0;
}
CPipeUser::~CPipeUser(void)
{
}
void CPipeUser::GetStateFromActiveGoals(SOBJECTSTATE &state)
{
FUNCTION_PROFILER(GetAISystem()->m_pSystem,PROFILE_AI);
bool bSkipAdd = false;
if (m_pCurrentGoalPipe)
{
if (!m_bBlocked) // if goal queue not blocked
{
QGoal Goal;
while (Goal.pGoalOp = m_pCurrentGoalPipe->PopGoal(Goal.bBlocking,Goal.name, Goal.params,this))
{
if (Goal.name == AIOP_LOOP)
{
bSkipAdd = true;
if ( (m_vActiveGoals.empty()) && (m_lstPath.empty()) )
{
if (Goal.params.nValue == 1)
{
if (!m_bLastHideResult)
break;
}
else
break;
}
m_pCurrentGoalPipe->Jump((int)Goal.params.fValue);
break;
}
if (Goal.name == AIOP_CLEAR)
{
m_vActiveGoals.clear();
GetAISystem()->FreeFormationPoint(m_Parameters.m_nGroup,this);
SetAttentionTarget(0);
m_bBlocked = false;
m_bUpdateInternal = true;
return;
}
if (!Goal.pGoalOp->Execute(this))
break;
}
if (!Goal.pGoalOp)
m_pCurrentGoalPipe->Reset();
else
{
if (!bSkipAdd)
{
m_vActiveGoals.push_back(Goal);
m_bBlocked = Goal.bBlocking;
}
}
}
}
if (!m_vActiveGoals.empty())
{
//ListOGoals::iterator gi;
//for (gi=m_lstActiveGoals.begin();gi!=m_lstActiveGoals.end();)
for (size_t i = 0; i < m_vActiveGoals.size(); i++)
{
//QGoal Goal = (*gi);
QGoal Goal = m_vActiveGoals[i];
m_sDEBUG_GOAL = Goal.name;
ITimer *pTimer = GetAISystem()->m_pSystem->GetITimer();
int val = GetAISystem()->m_cvProfileGoals->GetIVal();
if (val)
pTimer->MeasureTime("");
bool exec = Goal.pGoalOp->Execute(this);
if (val)
{
float f = pTimer->MeasureTime("");
TimingMap::iterator ti;
ti = GetAISystem()->m_mapDEBUGTimingGOALS.find(Goal.name);
if (ti == GetAISystem()->m_mapDEBUGTimingGOALS.end())
GetAISystem()->m_mapDEBUGTimingGOALS.insert(TimingMap::iterator::value_type(Goal.name,f));
else
{
if (f > ti->second)
ti->second = f;
}
}
if (exec)
{
RemoveActiveGoal(i);
if (!m_vActiveGoals.empty())
i--;
if (Goal.bBlocking)
m_bBlocked = false;
}
}
}
}
void CPipeUser::SetLastOpResult(CAIObject * pObject)
{
if (m_pLastOpResult)
if (m_pLastOpResult->GetType()==AIOBJECT_HIDEPOINT)
GetAISystem()->RemoveObject(m_pLastOpResult);
m_pLastOpResult = pObject;
}
void CPipeUser::SetAttentionTarget(CAIObject *pTarget)
{
if (pTarget==0)
{
m_bHaveLiveTarget = false;
if (m_pAttentionTarget && m_bCanReceiveSignals) // if I had a target previously I want to reevaluate
m_State.bReevaluate = true;
}
else if (m_pAttentionTarget!=pTarget)
m_State.bReevaluate = true;
if(m_pAttentionTarget!=0 && m_pAttentionTarget->GetType()!=AIOBJECT_DUMMY
&& m_pAttentionTarget->GetType()!=200) //FIXME not to remember grenades - not good, needs change
m_pPrevAttentionTarget = m_pAttentionTarget;
m_pAttentionTarget = pTarget;
}
void CPipeUser::RestoreAttentionTarget( )
{
//fixMe - need to do something
return;
SetAttentionTarget( m_pPrevAttentionTarget );
// m_pAttentionTarget = m_pPrevAttentionTarget;
// if (m_pAttentionTarget==0)
// m_bHaveLiveTarget = false;
}
void CPipeUser::RequestPathTo(const Vec3d &pos)
{
m_nPathDecision=PATHFINDER_STILLTRACING;
Vec3d myPos = m_vPosition;
if (m_nObjectType == AIOBJECT_PUPPET)
myPos.z-=m_fEyeHeight;
GetAISystem()->TracePath(myPos,pos,this);
}
CGoalPipe *CPipeUser::GetGoalPipe(const char *name)
{
CGoalPipe *pPipe = (CGoalPipe*) GetAISystem()->OpenGoalPipe(name);
if (pPipe)
return pPipe;
else
return 0;
}
void CPipeUser::RemoveActiveGoal(int nOrder)
{
if (m_vActiveGoals.empty())
return;
int size = (int)m_vActiveGoals.size();
if (size == 1)
{
m_vActiveGoals.front().pGoalOp->Reset(this);
m_vActiveGoals.clear();
return;
}
if (nOrder != (size-1))
m_vActiveGoals[nOrder] = m_vActiveGoals[size-1];
if (m_vActiveGoals.back().name == AIOP_TRACE)
m_pReservedNavPoint = 0;
m_vActiveGoals.back().pGoalOp->Reset(this);
m_vActiveGoals.pop_back();
}
bool CPipeUser::SelectPipe(int id, const char *name, IAIObject *pArgument)
{
if (pArgument)
SetLastOpResult((CAIObject *) pArgument);
if (m_pCurrentGoalPipe)
{
if (m_pCurrentGoalPipe->m_sName == string(name))
{
if (pArgument)
m_pCurrentGoalPipe->m_pArgument = (CAIObject*)pArgument;
return true;
}
}
CGoalPipe *pPipe = 0;
if (pPipe=GetAISystem()->IsGoalPipe(name))
{
pPipe->m_pArgument = (CAIObject*) pArgument;
ResetCurrentPipe();
m_pCurrentGoalPipe = pPipe; // this might be too slow, in which case we will go back to registration
m_pCurrentGoalPipe->Reset();
}
else
return false;
m_pReservedNavPoint = 0;
m_bDirectionalNavigation = false;
/* if (m_pMyObstacle)
{
m_pMyObstacle->bOccupied = false;
m_pMyObstacle = 0;
}
*/
return true;
}
void CPipeUser::RegisterAttack(const char *name)
{
/*
CGoalPipe *pPipe = GetGoalPipe(name);
if ((pPipe) && (m_mapAttacks.find(name)==m_mapAttacks.end()))
{
// clone this pipe first.. each puppet must use its own copy
CGoalPipe *pClone = pPipe->Clone();
m_mapAttacks.insert(GoalMap::iterator::value_type(name,pClone));
}
*/
}
void CPipeUser::RegisterRetreat(const char *name)
{
/*
CGoalPipe *pPipe = GetGoalPipe(name);
if ((pPipe) && (m_mapRetreats.find(name)==m_mapRetreats.end()))
{
// clone this pipe first.. each puppet must use its own copy
CGoalPipe *pClone = pPipe->Clone();
m_mapRetreats.insert(GoalMap::iterator::value_type(name,pClone));
}
*/
}
void CPipeUser::RegisterIdle(const char *name)
{
/*
CGoalPipe *pPipe = GetGoalPipe(name);
if ((pPipe) && (m_mapIdles.find(name)==m_mapIdles.end()))
{
// clone this pipe first.. each puppet must use its own copy
CGoalPipe *pClone = pPipe->Clone();
m_mapIdles.insert(GoalMap::iterator::value_type(name,pClone));
}
*/
}
void CPipeUser::RegisterWander(const char *name)
{
/*
CGoalPipe *pPipe = GetGoalPipe(name);
if ((pPipe) && (m_mapWanders.find(name)==m_mapWanders.end()))
{
// clone this pipe first.. each puppet must use its own copy
CGoalPipe *pClone = pPipe->Clone();
m_mapWanders.insert(GoalMap::iterator::value_type(name,pClone));
}
*/
}
bool CPipeUser::InsertSubPipe(int id, const char * name, IAIObject * pArgument)
{
if (!m_pCurrentGoalPipe)
{
return false;
}
if (m_pCurrentGoalPipe->m_sName == name)
return false;
// first lets find the goalpipe
CGoalPipe *pPipe = 0;
if (pPipe=GetAISystem()->IsGoalPipe(name))
{
// now find the innermost pipe
CGoalPipe *pExecutingPipe = m_pCurrentGoalPipe;
while (pExecutingPipe->IsInSubpipe())
{
pExecutingPipe = pExecutingPipe->GetSubpipe();
if (pExecutingPipe->m_sName == name)
{
delete pPipe;
return false;
}
}
//if (pExecutingPipe->m_sName != name)
//{
if (!m_vActiveGoals.empty() && m_bBlocked)
{
// pop the last executing goal
RemoveActiveGoal(m_vActiveGoals.size()-1);
// but make sure we end up executing it again
pExecutingPipe->Jump(-1);
}
pExecutingPipe->SetSubpipe(pPipe);
// unblock current pipe
m_bBlocked = false;
pPipe->m_pArgument = (CAIObject*) pArgument;
// }
// else
// {
// delete pPipe;
// return false;
// }
}
else
return false;
if (pArgument)
SetLastOpResult((CAIObject *) pArgument);
m_bDirectionalNavigation = false;
return true;
}
void CPipeUser::ResetCurrentPipe()
{
if (!m_vActiveGoals.empty())
{
VectorOGoals::iterator li;
for (li=m_vActiveGoals.begin();li!=m_vActiveGoals.end();li++)
{
QGoal goal = (*li);
goal.pGoalOp->Reset(this);
}
m_vActiveGoals.clear();
}
if (m_pCurrentGoalPipe)
{
delete m_pCurrentGoalPipe;
m_pCurrentGoalPipe = 0;
}
m_bBlocked = false;
m_bUpdateInternal = true;
m_bLooseAttention = false;
if (m_pLooseAttentionTarget)
m_pAISystem->RemoveDummyObject(m_pLooseAttentionTarget);
m_pLooseAttentionTarget = 0;
m_State.left = m_State.right = false;
}
void CPipeUser::Save(CStream & stm)
{
}
void CPipeUser::Load(CStream & stm)
{
}

108
CryAISystem/PipeUser.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef _PIPE_USER_
#define _PIPE_USER_
// created by Petar
#include "GoalPipe.h"
#include "AIObject.h"
#include "Graph.h"
#include <vector>
class CGoalPipe;
typedef std::vector<QGoal> VectorOGoals;
class CPipeUser :public CAIObject , public IPipeUser
{
protected:
AgentParameters m_Parameters;
VectorOGoals m_vActiveGoals;
bool m_bBlocked;
bool m_bStartTiming;
float m_fEngageTime;
CGoalPipe *m_pCurrentGoalPipe;
Vec3d m_vLastHidePoint;
public:
CPipeUser(void);
virtual ~CPipeUser(void);
void GetStateFromActiveGoals(SOBJECTSTATE &state);
CGoalPipe *GetGoalPipe(const char *name);
void RemoveActiveGoal(int nOrder);
void SetAttentionTarget(CAIObject *pObject);
void RestoreAttentionTarget( );
void SetLastOpResult(CAIObject * pObject);
virtual void Steer(const Vec3d & vTargetPos, GraphNode * pNode) {}
virtual Vec3d FindHidePoint(float fSearchDistance, int nMethod, bool bIndoor = false, bool bSameOk=false) {return m_vPosition;}
virtual void RequestPathTo(const Vec3d &pos);
virtual void Devalue(CAIObject *pObject,bool bDevaluePuppets) {}
virtual void Forget(CAIObject *pDummyObject) {}
virtual void Navigate(CAIObject *pTarget) {}
virtual void CreateFormation(const char * szName) {}
CGoalPipe *GetCurrentGoalPipe() { return m_pCurrentGoalPipe;}
void ResetCurrentPipe();
void RegisterAttack(const char *name);
void RegisterRetreat(const char *name);
void RegisterWander(const char *name);
void RegisterIdle(const char *name);
bool SelectPipe(int id,const char *name, IAIObject *pArgument);
bool InsertSubPipe(int id, const char * name, IAIObject * pArgument);
IAIObject *GetAttentionTarget(void) { return m_pAttentionTarget; }
AgentParameters &GetParameters() { return m_Parameters;}
// DEBUG MEMBERS
string m_sDEBUG_GOAL;
Vec3d m_vDEBUG_VECTOR;
bool m_bDEBUG_Unstuck;
//-----------------------------------
bool m_bMovementSupressed;
CAIObject *m_pAttentionTarget;
CAIObject *m_pPrevAttentionTarget;
CAIObject *m_pLastOpResult;
CAIObject *m_pReservedNavPoint;
ListPositions m_lstPath;
bool m_bHaveLiveTarget;
bool m_AvoidingCrowd;
float m_fTimePassed; //! how much time passed since last full update
bool m_bHiding;
bool m_bAllowedToFire;
bool m_bSmartFire;
bool m_bDirectionalNavigation; // true if the enemy should look where he is going
bool m_bLooseAttention; // true when we have don't have to look exactly at our target all the time
CAIObject *m_pLooseAttentionTarget; // optional
bool m_bUpdateInternal;
bool m_bLastHideResult;
Vec3d m_vLastHidePos;
int m_nPathDecision;
virtual void Save(CStream & stm);
virtual void Load(CStream & stm);
};
#endif

3081
CryAISystem/Puppet.cpp Normal file

File diff suppressed because it is too large Load Diff

268
CryAISystem/Puppet.h Normal file
View File

@@ -0,0 +1,268 @@
// Puppet.h: interface for the CPuppet class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_PUPPET_H__539B7168_3AA0_47B1_9D72_723B52A869E2__INCLUDED_)
#define AFX_PUPPET_H__539B7168_3AA0_47B1_9D72_723B52A869E2__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "CAISystem.h"
#include "PipeUser.h"
#include "AgentParams.h"
#include "IAgent.h"
#include "GoalPipe.h"
#include "Graph.h"
#include <list>
#include <map>
#include <vector>
#define PUPPETSTATE_NONE 0
#define PUPPETSTATE_ATTACKING 1
#define PUPPETSTATE_RETREATING 2
#define PUPPETSTATE_IDLING 3
#define PUPPETSTATE_WANDERING 4
class CGoalOp;
//! vision sensory data
typedef struct VisionSD
{
bool bFrameTag; // set to true if this object was seen this frame
float fExposureTime;
float fThreatIndex; // how interesting is this sensory data
float fInterestIndex; // how interesting is this sensory data
float fExpirationTime;
VisionSD()
{
bFrameTag = false;
fExposureTime = 0;
fThreatIndex =0;
fInterestIndex = 0;
fExpirationTime = 0;
}
} VisionSD;
typedef struct SoundSD
{
float fThreatIndex;
float fInterestIndex;
Vec3d vPosition;
float fTimeout;
CAIObject *pDummyRepresentation;
CAIObject *pOwner;
} SoundSD;
typedef struct MemoryRecord
{
CAIObject *pDummyRepresentation;
float fIntensity;
float fThreatIndex;
Vec3d vLastKnownPosition;
} MemoryRecord;
typedef std::vector<QGoal> VectorOGoals;
typedef std::map<CAIObject*,VisionSD> VisibilityMap;
typedef std::map<int,SoundSD> AudibilityMap;
typedef std::map<CAIObject*,MemoryRecord> MemoryMap;
typedef std::map<CAIObject*,float> DevaluedMap;
typedef std::map<CAIObject*,CAIObject*> ObjectObjectMap;
class CPuppet : public CPipeUser, IPuppet
{
//VehicleChange
protected:
//AgentParameters m_Parameters;
float m_fDEBUG_MaxHealth;
float m_fMotionAddition;
float m_fSuppressFiring; // in seconds
float m_fAIMTime;
bool m_bInFire;
Vec3d m_vLastTargetVector;
int m_nSampleFrequency;
bool m_bTargetDodge;
bool m_bOnceWithinAttackRange; //<<FIXME>> Remove this
// to prevent puppet firing gun while still not looking straight at the target
bool m_bAccurateDirectionFire;
float m_fMaxThreat;
float m_fRespawnTime;
GoalMap m_mapAttacks;
GoalMap m_mapRetreats;
GoalMap m_mapWanders;
GoalMap m_mapIdles;
// Vec3d m_vLastHidePoint;
// bool m_bLastHideResult;
// VectorOGoals m_vActiveGoals;
// bool m_bBlocked;
float m_fAccuracySupressor;
bool m_bRunning;
bool m_bLeftStrafe;
bool m_bRightStrafe;
ObstacleData *m_pMyObstacle; // used to track when this puppet occupies a hiding place
public:
// void SetAttentionTarget(CAIObject *pObject);
bool PointAudible(const Vec3d &pos, float fRadius);
void Forget(CAIObject *pDummyObject);
void OnObjectRemoved(CAIObject *pObject);
bool m_bDryUpdate;
void RequestPathTo(const Vec3d &pos);
void Navigate(CAIObject *pTarget);
bool PointVisible(const Vec3d &pos);
void Event(unsigned short eType, SAIEVENT *pEvent);
void UpdatePuppetInternalState();
bool CanBeConvertedTo(unsigned short type, void **pConverted);
void AddToVisibleList(CAIObject *pAIObject, bool bForce = false, float fAdditionalMultiplier=1.f);
void QuickVisibility();
CPuppet();
virtual ~CPuppet();
//void RegisterAttack(const char *name);
//void RegisterRetreat(const char *name);
//void RegisterWander(const char *name);
//void RegisterIdle(const char *name);
//bool SelectPipe(int id,const char *name, IAIObject *pArgument);
AgentParameters GetPuppetParameters() { return GetParameters();}
void SetPuppetParameters(AgentParameters &pParams) { SetParameters(pParams);}
void ParseParameters(const AIObjectParameters &params);
void Update();
void Devalue(CAIObject *pObject, bool bDevaluePuppets);
//AgentParameters &GetParameters() { return m_Parameters;}
bool m_bMeasureAll;
//bool m_bHaveLiveTarget;
CFormation *m_pFormation;
IPuppetProxy *m_pProxy;
float m_fUrgency;
bool m_bVisible;
// bool m_bDEBUG_Unstuck;
// bool m_bUpdateInternal;
//bool m_bLooseAttention; // true when we have don't have to look exactly at our target all the time
// CGoalPipe *m_pCurrentGoalPipe;
float m_fCos;
float m_fBound;
// Vec3d m_vDEBUG_VECTOR;
//string m_sDEBUG_GOAL;
// move these to private after debug stage
VisibilityMap m_mapVisibleAgents;
MemoryMap m_mapMemory;
DevaluedMap m_mapDevaluedPoints;
DevaluedMap m_mapPotentialTargets;
ObjectObjectMap m_mapInterestingDummies;
AudibilityMap m_mapSoundEvents;
// CAIObject *m_pAttentionTarget;
// CAIObject *m_pLastOpResult; // temporary here while real system in development
// int m_nPathDecision;
// ListPositions m_lstPath;
// bool m_bAllowedToFire;
// bool m_bSmartFire;
int m_nBodyPos;
float m_DEBUG_LASTUPDATETIME;
CAIObject *m_pDEBUGLastHideSpot;
void GetAgentParams(AgentParameters &params) { params = m_Parameters; }
void GetCurrentGoalName(string &name) { if (m_pCurrentGoalPipe) name = m_pCurrentGoalPipe->m_sName;
else name = "";}
protected:
void HandleSoundEvent(SAIEVENT *pEvent);
void HandlePathDecision(SAIEVENT *pEvent);
//void ResetCurrentPipe();
void AssessThreat(CAIObject *pObject, VisionSD &data);
void Remember(CAIObject *pObject, VisionSD &data);
void HandleVisualStimulus(SAIEVENT *pEvent);
// void GetStateFromActiveGoals(SOBJECTSTATE &state);
// CGoalPipe *GetGoalPipe(const char *name);
//VehicleChange
//private:
float m_fHorizontalFOVrad;
protected:
// calculates threat based on input parameters and this puppet's parameters
float CalculateThreat(const AgentParameters & params);
// calculates interest value of the target with the given parameters
float CalculateInterest(const AgentParameters & params);
public:
// Steers the puppet outdoors and makes it avoid the immediate obstacles
//VehicleChange
virtual void Steer(const Vec3d & vTargetPos, GraphNode * pNode);
// debug function to unstuck the puppet if it is stuck
void CreateFormation(const char * szName);
void Reset(void);
void ReleaseFormation(void);
// removes a goal from the active goals and reshuffles the active goals
//void RemoveActiveGoal(int nOrder);
Vec3d GetIndoorHidePoint(int nMethod, float fSearchDistance, bool bSameOK);
protected:
// decides whether to fire or not
void FireCommand(void);
public:
void AddToMemory(CAIObject * pObject);
// finds hide point in graph based on specified search method
Vec3d FindHidePoint(float fSearchDistance, int nMethod, bool bIndoor = false, bool bSameOk = false);
// Evaluates whether the chosen navigation point will expose us too much to the target
bool Compromising(const ObstacleData &od,bool bIndoor);
// returns true if puppet visible
bool Sees(CPuppet * pObject);
void SetParameters(AgentParameters & sParams);
//void SetLastOpResult(CAIObject * pObject);
///bool InsertSubPipe(int id, const char * name, IAIObject * pArgument);
Vec3d GetOutdoorHidePoint(int nMethod, float fSearchDistance, bool bSameOk);
virtual IUnknownProxy* GetProxy() { return m_pProxy; };
void CheckTargetLateralMovement();
size_t MemStats();
bool m_bCloseContact;
float m_fLastUpdateTime;
void CrowdControl(void);
void CheckPlayerTargeting(void);
void RemoveFromGoalPipe(CAIObject* pObject);
CAIObject * GetMemoryOwner(CAIObject * pMemoryRepresentation);
void Save(CStream & stm);
void Load(CStream & stm);
void Load_PATCH_1(CStream & stm);
};
#endif // !defined(AFX_PUPPET_H__539B7168_3AA0_47B1_9D72_723B52A869E2__INCLUDED_)

41
CryAISystem/ReadMe.txt Normal file
View File

@@ -0,0 +1,41 @@
========================================================================
DYNAMIC LINK LIBRARY : CryAISystem
========================================================================
AppWizard has created this CryAISystem DLL for you.
This file contains a summary of what you will find in each of the files that
make up your CryAISystem application.
CryAISystem.dsp
This file (the project file) contains information at the project level and
is used to build a single project or subproject. Other users can share the
project (.dsp) file, but they should export the makefiles locally.
CryAISystem.cpp
This is the main DLL source file.
When created, this DLL does not export any symbols. As a result, it
will not produce a .lib file when it is built. If you wish this project
to be a project dependency of some other project, you will either need to
add code to export some symbols from the DLL so that an export library
will be produced, or you can check the "doesn't produce lib" checkbox in
the Linker settings page for this project.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named CryAISystem.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

9
CryAISystem/StdAfx.cpp Normal file
View File

@@ -0,0 +1,9 @@
// stdafx.cpp : source file that includes just the standard includes
// CryAISystem.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

62
CryAISystem/StdAfx.h Normal file
View File

@@ -0,0 +1,62 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__81DAABA0_0054_42BF_8696_D99BA6832D03__INCLUDED_)
#define AFX_STDAFX_H__81DAABA0_0054_42BF_8696_D99BA6832D03__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//////////////////////////////////////////////////////////////////////////
// THIS MUST BE AT THE VERY BEGINING OF STDAFX.H FILE.
// Disable STL threading support, (makes STL faster)
//////////////////////////////////////////////////////////////////////////
#define _NOTHREADS
#define _STLP_NO_THREADS
//////////////////////////////////////////////////////////////////////////
#include <platform.h>
#ifndef _XBOX
#ifdef WIN32
// Insert your headers here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#endif
#else
#include <xtl.h>
#endif
#include <stdlib.h>
#define USE_NEWPOOL
#include <CryMemoryManager.h>
#include "Cry_Math.h"
#include "Cry_XOptimise.h" // required by AMD64 compiler
#include "Cry_Camera.h"
// TODO: reference additional headers your program requires here
class CAISystem;
CAISystem *GetAISystem();
//////////////////////////////////////////////////////////////////////////
// Report AI warnings to validator.
//////////////////////////////////////////////////////////////////////////
//! Reports an AI Warning to validator with WARNING severity.
void AIWarning( const char *format,... );
//! Reports an AI Warning to validator with ERROR severity.
void AIError( const char *format,... );
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__81DAABA0_0054_42BF_8696_D99BA6832D03__INCLUDED_)

View File

@@ -0,0 +1,81 @@
#include "stdafx.h"
#include "vertexlist.h"
#include <ISystem.h>
#include <CryFile.h>
CVertexList::CVertexList(void)
{
m_vList.clear();
}
CVertexList::~CVertexList(void)
{
}
int CVertexList::AddVertex(const ObstacleData & od)
{
int index=FindVertex(od);
if (index<0)
{
m_vList.push_back(od);
index = (int)m_vList.size()-1;
}
return index;
}
int CVertexList::FindVertex(const ObstacleData & od)
{
Obstacles::iterator oi,oiend = m_vList.end();
int index=0;
for (oi=m_vList.begin();oi!=oiend;++oi,index++)
{
if ( (*oi) == od )
return index;
}
return -1;
}
const ObstacleData CVertexList::GetVertex(int index)
{
if ((index<0) || (index >= (int)(m_vList.size())))
CryError("[AISYSTEM] Tried to retrieve a non existing vertex from vertex list.Please regenerate the triangulation and re-export the map.");
return m_vList[index];
}
ObstacleData &CVertexList::ModifyVertex(int index)
{
if ((index<0) || (index >= (int)(m_vList.size())))
CryError("[AISYSTEM] Tried to retrieve a non existing vertex from vertex list.Please regenerate the triangulation and re-export the map.");
return m_vList[index];
}
void CVertexList::WriteToFile( CCryFile& file )
{
int iNumber = (int)m_vList.size();
file.Write( &iNumber, sizeof( int ) );
if (!iNumber)
return;
file.Write( &m_vList[ 0 ], iNumber * sizeof( ObstacleData ) );
}
void CVertexList::ReadFromFile( CCryFile &file )
{
int iNumber;
file.Read( &iNumber, sizeof(int) );
if (iNumber>0)
{
m_vList.resize(iNumber);
file.Read( &m_vList[0], iNumber*sizeof(ObstacleData) );
}
}

29
CryAISystem/VertexList.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef _VERTEX_LIST_
#define _VERTEX_LIST_
#include <iagent.h>
class CCryFile;
class CVertexList
{
Obstacles m_vList;
public:
CVertexList(void);
~CVertexList(void);
int AddVertex(const ObstacleData & od);
const ObstacleData GetVertex(int index);
ObstacleData &ModifyVertex(int index);
int FindVertex(const ObstacleData & od);
void WriteToFile( CCryFile& file );
void ReadFromFile( class CCryFile &file );
void Clear() {m_vList.clear();}
int GetSize() {return m_vList.size();}
};
#endif // #ifndef _VERTEX_LIST_

View File

@@ -0,0 +1,100 @@
//
// Reference linked smart pointer template
//
// Created by Petar
// cleaned up and added operator* by Petar 27 Feb 2003
// added derived class that releases the underlying pointer
#pragma once
template <class PtrClass>
class pointer_container
{
protected:
mutable PtrClass *m_pContent;
mutable const pointer_container *m_pNext;
mutable const pointer_container *m_pPrevious;
inline void init(PtrClass *initial_content)
{
m_pContent = initial_content;
m_pNext=this;
m_pPrevious=this;
}
inline void insert(const pointer_container &other) const
{
m_pNext = &other;
m_pPrevious = other.m_pPrevious;
other.m_pPrevious->m_pNext = this;
other.m_pPrevious = this;
}
inline void remove() const
{
m_pNext->m_pPrevious = m_pPrevious;
m_pPrevious->m_pNext = m_pNext;
}
inline void cleanup() const
{
remove();
if (m_pNext == this)
{
delete m_pContent;
m_pContent = 0;
}
}
public:
pointer_container(PtrClass *initial_content=0)
{
init(initial_content);
}
// copy constructor
pointer_container(const pointer_container &copy)
{
init(0);
operator=(copy);
}
~pointer_container()
{
cleanup();
}
inline const pointer_container &operator=(const pointer_container &copy)
{
cleanup();
m_pContent = copy.m_pContent;
if (copy.m_pContent)
insert(copy);
return *this;
}
inline PtrClass &operator*() { return *m_pContent;}
inline PtrClass *operator->() { return m_pContent;}
inline bool operator==(const pointer_container &other)
{
return m_pContent == other.m_pContent;
}
inline bool operator!=(const pointer_container &other)
{
return !operator==(other);
}
inline operator PtrClass* () const
{
return m_pContent;
}
inline bool operator!()
{
return !m_pContent;
}
};