123
This commit is contained in:
77
CryAISystem/GoalPipe.h
Normal file
77
CryAISystem/GoalPipe.h
Normal 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 ¶ms);
|
||||
|
||||
GoalPointer PopGoal(bool &blocking, string &name, GoalParameters ¶ms,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
2963
CryAISystem/Graph.cpp
Normal file
File diff suppressed because it is too large
Load Diff
303
CryAISystem/Graph.h
Normal file
303
CryAISystem/Graph.h
Normal 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
1166
CryAISystem/GraphUtility.cpp
Normal file
File diff suppressed because it is too large
Load Diff
174
CryAISystem/Heuristic.cpp
Normal file
174
CryAISystem/Heuristic.cpp
Normal 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
38
CryAISystem/Heuristic.h
Normal 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
2
CryAISystem/IAgent.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "stdafx.h"
|
||||
#include "IAgent.h"
|
||||
5
CryAISystem/MSSCCPRJ.SCC
Normal file
5
CryAISystem/MSSCCPRJ.SCC
Normal 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
427
CryAISystem/PipeUser.cpp
Normal 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
108
CryAISystem/PipeUser.h
Normal 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
3081
CryAISystem/Puppet.cpp
Normal file
File diff suppressed because it is too large
Load Diff
268
CryAISystem/Puppet.h
Normal file
268
CryAISystem/Puppet.h
Normal 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 ¶ms);
|
||||
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 ¶ms) { 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
41
CryAISystem/ReadMe.txt
Normal 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
9
CryAISystem/StdAfx.cpp
Normal 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
62
CryAISystem/StdAfx.h
Normal 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_)
|
||||
81
CryAISystem/VertexList.cpp
Normal file
81
CryAISystem/VertexList.cpp
Normal 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
29
CryAISystem/VertexList.h
Normal 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_
|
||||
100
CryAISystem/pointer_container.h
Normal file
100
CryAISystem/pointer_container.h
Normal 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 ©)
|
||||
{
|
||||
init(0);
|
||||
operator=(copy);
|
||||
}
|
||||
|
||||
~pointer_container()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
inline const pointer_container &operator=(const pointer_container ©)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user