-
Notifications
You must be signed in to change notification settings - Fork 1
/
Behavior.cpp
123 lines (112 loc) · 3.48 KB
/
Behavior.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
#include "Behavior.h"
namespace Behavior
{
BasicAction BehaviorControls(NpcBehavior behavior, GameObject& npc, GameObject& target, GameObjects& environment)
{
switch (behavior)
{
case eDesire:
{
return GreedyBehavior(npc, target, environment);
}
break;
case eFear:
{
return CowardlyBehavior(npc, target, environment);
}
break;
case eAggression:
{
return AggressiveBehavior(npc, target, environment);
}
break;
case eWander:
{
return WanderingBehavior(npc, target, environment);
}
break;
case eMisc:
{
return MiscellaneousBehavior(npc, target, environment);
}
break;
default:
{
return eStop;
}
break;
}
}
BasicAction AggressiveBehavior(GameObject& npc, GameObject& target, GameObjects& environment)
{
//TODO: there isn't really any point of else if you return in the if above
if (UtilsBehavior::CanHit(npc, target)) {
return eAttack;
} else if (npc.GetFlag(eAttacking) && !UtilsBehavior::CanHit(npc, target)) {
return eStop;
} else if (!npc.GetFlag(eAffectedByGravity) || UtilsBehavior::CanMove(npc, environment)) {
CL_Point destination = target.GetPosition();
if (!UtilsBehavior::IsFacing(npc, target)) {
UtilsBehavior::FaceTarget(npc, target, false);
}
if (npc.GetDirection() == eLeft) {
destination.x += npc.GetStat(eAttackRange);
} else {
destination.x -= npc.GetStat(eAttackRange);
}
UtilsBehavior::DetermineSpeeds(npc, destination);
return eMove;
}
return eStop;
}
BasicAction CowardlyBehavior(GameObject& npc, GameObject& target, GameObjects& environment)
{
if (!UtilsBehavior::IsFacing(npc, target)) {
UtilsBehavior::FaceTarget(npc, target, false);
}
//TODO: there isn't really any point of else if you return in the if above
if (npc.GetFlag(eCanShoot)
//&& Utils::CalculateTrajectory(npc.GetPosition(), target.GetPosition(), npc.GetSpeed(COMPOSITE_SPEED), true) != 0.0f
&& (npc.GetStat(eTimeSinceLastAttack) > npc.GetStat(eAttackCooldown))) {
return eShoot;
} else if (Utility::GetDistance(npc.GetPosition(), target.GetPosition()) < 2 * npc.GetStat(eAttackRange)) {
return eFlee;
}
return eStop;
}
//TODO: do we really need two methods that return the same thing?
//Or are they not implemented yet?
BasicAction GreedyBehavior(GameObject& npc, GameObject& target, GameObjects& environment)
{
return eMove;
}
BasicAction WanderingBehavior(GameObject& npc, GameObject& target, GameObjects& environment)
{
return eMove;
}
BasicAction MiscellaneousBehavior(GameObject& npc, GameObject& target, GameObjects& environment)
{
if (!UtilsBehavior::IsFacing(npc, target)) {
UtilsBehavior::FaceTarget(npc, target, false);
}
//TODO: save stuff in local vars to avoid redundant method invocations
if (Utility::GetDistance(npc.GetPosition(), target.GetPosition()) < npc.GetStat(eAttackRange)) {
return eFlee;
}
//TODO: there isn't really any point of else if you return in the if above
if (UtilsBehavior::CanHit(npc, target)) {
return eAttack;
} else if (abs(npc.GetPosition().y - target.GetPosition().y) < 30) {
if (UtilsBehavior::CanMove(npc, environment)) {
return eMove;
} else if (Utility::CalculateTrajectory(npc.GetPosition(), target.GetPosition(), npc.GetSpeed(eCompositeSpeed), true) != 0.0f) {
return eJump;
}
return eStop;
} else if (Utility::CalculateTrajectory(npc.GetPosition(), target.GetPosition(), npc.GetSpeed(eCompositeSpeed), true) != 0.0f) {
return eJump;
} else {
return eStop;
}
}
}