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