1 #ifdef CPP_GAME_SERVER
2     #define defendstate stfservstate
3     #define defendcount (m_dac_king(gamemode, mutators) ? G(defendking) : G(defendoccupy))
4 #else
5     #define defendcount (m_dac_king(game::gamemode, game::mutators) ? G(defendking) : G(defendoccupy))
6 #endif
7 
8 struct defendstate
9 {
10     struct flag
11     {
12         vec o;
13         int kinship, yaw, pitch, owner, enemy;
14         string name;
15 #ifndef CPP_GAME_SERVER
16         string info;
17         bool hasflag;
18         int lasthad;
19         vec render;
20         modelstate mdl;
21 #endif
22         int owners, enemies, converted, points;
23 
flagdefendstate::flag24         flag()
25         {
26             kinship = T_NEUTRAL;
27             reset();
28         }
29 
noenemydefendstate::flag30         void noenemy()
31         {
32             enemy = T_NEUTRAL;
33             enemies = 0;
34             converted = 0;
35         }
36 
resetdefendstate::flag37         void reset()
38         {
39             noenemy();
40             owner = kinship;
41             yaw = pitch = owners = points = 0;
42 #ifndef CPP_GAME_SERVER
43             hasflag = false;
44             lasthad = 0;
45 #endif
46         }
47 
enterdefendstate::flag48         bool enter(int team)
49         {
50             if(owner == team)
51             {
52                 owners++;
53                 return false;
54             }
55             if(!enemies)
56             {
57                 if(enemy != team)
58                 {
59                     converted = 0;
60                     enemy = team;
61                 }
62                 enemies++;
63                 return true;
64             }
65             else if(enemy != team) return false;
66             else enemies++;
67             return false;
68         }
69 
stealdefendstate::flag70         bool steal(int team)
71         {
72             return !enemies && owner != team;
73         }
74 
leavedefendstate::flag75         bool leave(int team)
76         {
77             if(owner == team)
78             {
79                 owners--;
80                 return false;
81             }
82             if(enemy != team) return false;
83             enemies--;
84             return !enemies;
85         }
86 
occupydefendstate::flag87         int occupy(int team, int units, int occupy, bool instant)
88         {
89             if(enemy != team) return -1;
90             converted += units;
91 
92             if(units < 0)
93             {
94                 if(converted <= 0) noenemy();
95                 return -1;
96             }
97             else if(converted < occupy) return -1;
98 
99             if(!instant && owner)
100             {
101                 owner = T_NEUTRAL;
102                 converted = points = 0;
103                 enemy = team;
104                 return 0;
105             }
106             else
107             {
108                 owner = team;
109                 points = 0;
110                 owners = enemies;
111                 noenemy();
112                 return 1;
113             }
114         }
115 
occupieddefendstate::flag116         float occupied(bool instant, float amt)
117         {
118             return (enemy ? enemy : owner) ? (!owner || enemy ? clamp(converted/amt, 0.f, 1.f) : 1.f) : 0.f;
119         }
120 #ifndef CPP_GAME_SERVER
setpositiondefendstate::flag121         void setposition(const vec &pos)
122         {
123             o = render = pos;
124             render.z += 4;
125             physics::droptofloor(render);
126             render.z -= 1.5f;
127             float offset = o.z-render.z;
128             if(offset < 0)
129             {
130                 o = render;
131                 offset = 0;
132             }
133             if(offset < 4) o.z += 4-offset;
134         }
135 #endif
136     };
137 
138     vector<flag> flags;
139 
defendstatedefendstate140     defendstate() { reset(); }
141 
resetdefendstate142     void reset()
143     {
144         flags.shrink(0);
145     }
146 
addaffinitydefendstate147     void addaffinity(const vec &o, int team, int yaw, int pitch, const char *name)
148     {
149         flag &b = flags.add();
150         b.kinship = team;
151         b.reset();
152         b.yaw = yaw;
153         b.pitch = pitch;
154 #ifdef CPP_GAME_SERVER
155         b.o = o;
156 #else
157         b.setposition(o);
158 #endif
159         copystring(b.name, name);
160     }
161 
initaffinitydefendstate162     void initaffinity(int i, int kin, int yaw, int pitch, vec &o, int owner, int enemy, int converted, const char *name)
163     {
164         if(!flags.inrange(i)) return;
165         flag &b = flags[i];
166         b.kinship = kin;
167         b.reset();
168         b.yaw = yaw;
169         b.pitch = pitch;
170 #ifdef CPP_GAME_SERVER
171         b.o = o;
172 #else
173         b.setposition(o);
174 #endif
175         b.owner = owner;
176         b.enemy = enemy;
177         b.converted = converted;
178         copystring(b.name, name);
179     }
180 
hasaffinitydefendstate181     bool hasaffinity(int team)
182     {
183         loopv(flags)
184         {
185             flag &b = flags[i];
186             if(b.owner && b.owner == team) return true;
187         }
188         return false;
189     }
190 
disttoenemydefendstate191     float disttoenemy(flag &b)
192     {
193         float dist = 1e10f;
194         loopv(flags)
195         {
196             flag &e = flags[i];
197             if(e.owner && b.owner != e.owner)
198                 dist = min(dist, b.o.dist(e.o));
199         }
200         return dist;
201     }
202 
203     bool insideaffinity(const flag &b, const vec &o, float radius = 0)
204     {
205         if(radius <= 0) radius = enttype[AFFINITY].radius;
206         float dx = (b.o.x-o.x), dy = (b.o.y-o.y), dz = (b.o.z-o.z);
207         return dx*dx + dy*dy <= radius*radius && fabs(dz) <= radius;
208     }
209 };
210 
211 #ifndef CPP_GAME_SERVER
212 namespace defend
213 {
214     extern defendstate st;
215     extern void sendaffinity(packetbuf &p);
216     extern void parseaffinity(ucharbuf &p);
217     extern void updateaffinity(int i, int owner, int enemy, int converted);
218     extern void setscore(int team, int total);
219     extern void reset();
220     extern void setup();
221     extern void drawnotices(int w, int h, int &tx, int &ty, int tr, int tg, int tb, float blend);
222     extern void drawevents(int w, int h, int &tx, int &ty, int tr, int tg, int tb, float blend);
223     extern void drawonscreen(int w, int h, float blend);
224     extern void preload();
225     extern void render();
226     extern void adddynlights();
227     extern void aifind(gameent *d, ai::aistate &b, vector<ai::interest> &interests);
228     extern bool aicheck(gameent *d, ai::aistate &b);
229     extern bool aidefense(gameent *d, ai::aistate &b);
230     extern bool aipursue(gameent *d, ai::aistate &b);
231     extern bool aicheckpos(gameent *d, ai::aistate &b);
232     extern void removeplayer(gameent *d);
233     extern void checkcams(vector<cament *> &cameras);
234     extern void updatecam(cament *c);
235 }
236 #endif
237