-
Notifications
You must be signed in to change notification settings - Fork 60
/
NetworkAiComponent.cpp
126 lines (113 loc) · 4.99 KB
/
NetworkAiComponent.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Source/Components/NetworkAiComponent.h>
#include <Source/Components/NetworkPlayerMovementComponent.h>
#include <Source/Components/NetworkWeaponsComponent.h>
#include <Multiplayer/Components/NetBindComponent.h>
#include <Multiplayer/Components/LocalPredictionPlayerInputComponent.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Time/ITime.h>
namespace ${SanitizedCppName}
{
constexpr static float SecondsToMs = 1000.f;
NetworkAiComponentController::NetworkAiComponentController(NetworkAiComponent& parent)
: NetworkAiComponentControllerBase(parent)
{
}
#if AZ_TRAIT_SERVER
void NetworkAiComponentController::TickMovement(NetworkPlayerMovementComponentController& movementController, float deltaTime)
{
// TODO: Execute this tick only if this component is owned by this endpoint (currently ticks on server only)
float deltaTimeMs = deltaTime * SecondsToMs;
ModifyRemainingTimeMs() -= deltaTimeMs;
if (GetRemainingTimeMs() <= 0)
{
// Determine a new directive after 500 to 9500 ms
SetRemainingTimeMs(m_lcg.GetRandomFloat() * (GetActionIntervalMaxMs() - GetActionIntervalMinMs()) + GetActionIntervalMinMs());
SetTurnRate(1.f / GetRemainingTimeMs());
// Randomize new target yaw and pitch and compute the delta from the current yaw and pitch respectively
SetTargetYawDelta(-movementController.m_viewYaw + (m_lcg.GetRandomFloat() * 2.f - 1.f));
SetTargetPitchDelta(-movementController.m_viewPitch + (m_lcg.GetRandomFloat() - 0.5f));
// Randomize the action and strafe direction (used only if we decide to strafe)
SetAction(static_cast<Action>(m_lcg.GetRandom() % static_cast<int>(Action::COUNT)));
SetStrafingRight(static_cast<bool>(m_lcg.GetRandom() % 2));
}
// Translate desired motion into inputs
// Interpolate the current view yaw and pitch values towards the desired values
movementController.m_viewYaw += GetTurnRate() * deltaTimeMs * GetTargetYawDelta();
movementController.m_viewPitch += GetTurnRate() * deltaTimeMs * GetTargetPitchDelta();
// Reset keyboard movement inputs decided on the previous frame
movementController.m_forwardDown = false;
movementController.m_backwardDown = false;
movementController.m_leftDown = false;
movementController.m_rightDown = false;
movementController.m_sprinting = false;
movementController.m_jumping = false;
movementController.m_crouching = false;
switch (GetAction())
{
case Action::Default:
movementController.m_forwardDown = true;
break;
case Action::Sprinting:
movementController.m_forwardDown = true;
movementController.m_sprinting = true;
break;
case Action::Jumping:
movementController.m_forwardDown = true;
movementController.m_jumping = true;
break;
case Action::Crouching:
movementController.m_forwardDown = true;
movementController.m_crouching = true;
break;
case Action::Strafing:
if (GetStrafingRight())
{
movementController.m_rightDown = true;
}
else
{
movementController.m_leftDown = true;
}
break;
default:
break;
}
}
void NetworkAiComponentController::TickWeapons(NetworkWeaponsComponentController& weaponsController, float deltaTime)
{
// TODO: Execute this tick only if this component is owned by this endpoint (currently ticks on server only)
ModifyTimeToNextShot() -= deltaTime * SecondsToMs;
if (GetTimeToNextShot() <= 0)
{
if (GetShotFired())
{
// Fire weapon between 100 and 10000 ms from now
SetTimeToNextShot(m_lcg.GetRandomFloat() * (GetFireIntervalMaxMs() - GetFireIntervalMinMs()) + GetFireIntervalMinMs());
SetShotFired(false);
weaponsController.m_weaponFiring = false;
}
else
{
weaponsController.m_weaponFiring = true;
SetShotFired(true);
}
}
}
void NetworkAiComponentController::ConfigureAi(
float fireIntervalMinMs, float fireIntervalMaxMs, float actionIntervalMinMs, float actionIntervalMaxMs, uint64_t seed)
{
SetFireIntervalMinMs(fireIntervalMinMs);
SetFireIntervalMaxMs(fireIntervalMaxMs);
SetActionIntervalMinMs(actionIntervalMinMs);
SetActionIntervalMaxMs(actionIntervalMaxMs);
m_lcg.SetSeed(seed);
}
#endif
}