1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "AIMoveSimulation.h"
5 #include "Objects\EntityObject.h"
6 #include "GameEngine.h"
7 #include <CryAISystem/IAIObject.h>
9 #include <CryAISystem/IAIActorProxy.h>
10 #include <CryAISystem/IMovementSystem.h>
11 #include <CryAISystem/MovementRequest.h>
13 //////////////////////////////////////////////////////////////////////////
14 CAIMoveSimulation::CAIMoveSimulation()
18 //////////////////////////////////////////////////////////////////////////
19 CAIMoveSimulation::~CAIMoveSimulation()
24 //////////////////////////////////////////////////////////////////////////
25 void CAIMoveSimulation::CancelMove()
27 CRY_ASSERT(gEnv
&& gEnv
->pAISystem
&& gEnv
->pAISystem
->GetMovementSystem());
29 for (const SMovingAI
& movingAI
: m_movingAIs
)
31 gEnv
->pAISystem
->GetMovementSystem()->CancelRequest(movingAI
.m_movementRequestID
);
36 //////////////////////////////////////////////////////////////////////////
37 bool CAIMoveSimulation::UpdateAIMoveSimulation(CViewport
* pView
, const CPoint
& point
)
39 CGameEngine
* pGameEngine
= GetIEditorImpl()->GetGameEngine();
40 CRY_ASSERT(pGameEngine
);
42 // Cancel the current move order
45 const CSelectionGroup
* selection
= GetIEditorImpl()->GetSelection();
46 if (!selection
->GetCount())
49 std::vector
<CEntityObject
*> selectedEntityObjects
;
50 selectedEntityObjects
.reserve(selection
->GetCount());
51 for (int i
= 0; i
< selection
->GetCount(); ++i
)
53 CBaseObject
* selectedObject
= selection
->GetObject(i
);
54 if (selectedObject
->IsKindOf(RUNTIME_CLASS(CEntityObject
)))
56 selectedEntityObjects
.push_back(static_cast<CEntityObject
*>(selectedObject
));
60 if (selectedEntityObjects
.size() == 0)
64 Vec3
vGotoPoint(ZERO
);
65 if (GetAIMoveSimulationDestination(pView
, point
, vGotoPoint
))
67 for (CEntityObject
* pEntityObject
: selectedEntityObjects
)
69 IEntity
* pEntity
= pEntityObject
->GetIEntity();
70 if (pEntity
) // Not every EntityObject actually has entity...
72 MovementRequestID movementRequestId
= SendAIMoveSimulation(pEntity
, vGotoPoint
);
73 if (!movementRequestId
.IsInvalid())
75 m_movingAIs
.push_back({ pEntityObject
->GetId(), movementRequestId
});
84 //////////////////////////////////////////////////////////////////////////
85 bool CAIMoveSimulation::GetAIMoveSimulationDestination(CViewport
* pView
, const CPoint
& point
, Vec3
& outGotoPoint
) const
88 pView
->HitTest(point
, hitInfo
);
90 // TODO Get point or projected point on hit object's bounds
91 CBaseObject
* pHitObj
= hitInfo
.object
;
95 pHitObj
->GetBoundBox(bbox
);
97 // TODO Get closest approachable point to bounds
98 outGotoPoint
= pView
->SnapToGrid(pView
->ViewToWorld(point
));
102 outGotoPoint
= pView
->SnapToGrid(pView
->ViewToWorld(point
));
108 //////////////////////////////////////////////////////////////////////////
109 MovementStyle::Speed
GetSpeedToUseForSimulation()
111 MovementStyle::Speed speedToUse
= MovementStyle::Run
;
113 if (const bool bShift
= ((GetKeyState(VK_SHIFT
) & 0x8000) != 0))
115 speedToUse
= MovementStyle::Walk
;
118 if (const bool bControl
= ((GetKeyState(VK_MENU
) & 0x8000) != 0))
120 speedToUse
= MovementStyle::Sprint
;
126 MovementRequestID
CAIMoveSimulation::SendAIMoveSimulation(IEntity
* pEntity
, const Vec3
& vGotoPoint
)
130 // ensure that a potentially running animation doesn't block the movement
131 if (pEntity
->HasAI())
133 IAIObject
* pAI
= pEntity
->GetAI();
136 if (IAIActorProxy
* aiProxy
= pAI
->GetProxy())
138 aiProxy
->ResetAGInput(AIAG_ACTION
);
139 aiProxy
->SetAGInput(AIAG_ACTION
, "idle", true);
144 MovementRequest request
;
145 request
.type
= MovementRequest::MoveTo
;
146 request
.destination
= vGotoPoint
;
147 request
.style
.SetSpeed(GetSpeedToUseForSimulation());
148 request
.style
.SetStance(MovementStyle::Stand
);
149 request
.entityID
= pEntity
->GetId();
151 CRY_ASSERT(gEnv
&& gEnv
->pAISystem
&& gEnv
->pAISystem
->GetMovementSystem());
153 return gEnv
->pAISystem
->GetMovementSystem()->QueueRequest(request
);