1 struct defendservmode : defendstate, servmode 2 { 3 int scoresec; 4 bool hasflaginfo; 5 defendservmodedefendservmode6 defendservmode() : scoresec(0), hasflaginfo(false) {} 7 resetdefendservmode8 void reset() 9 { 10 defendstate::reset(); 11 scoresec = 0; 12 hasflaginfo = false; 13 } 14 stealaffinitydefendservmode15 void stealaffinity(int n, int team) 16 { 17 flag &b = flags[n]; 18 loopv(clients) if(AA(clients[i]->actortype, abilities)&(1<<A_A_AFFINITY)) 19 { 20 server::clientinfo *ci = clients[i]; 21 if(ci->state==CS_ALIVE && ci->team && ci->team == team && insideaffinity(b, ci->o)) 22 b.enter(ci->team); 23 } 24 sendaffinity(n); 25 } 26 moveaffinitydefendservmode27 void moveaffinity(int team, const vec &oldpos, const vec &newpos) 28 { 29 if(!team) return; 30 loopv(flags) 31 { 32 flag &b = flags[i]; 33 bool leave = insideaffinity(b, oldpos), 34 enter = insideaffinity(b, newpos); 35 if(leave && !enter && b.leave(team)) sendaffinity(i); 36 else if(enter && !leave && b.enter(team)) sendaffinity(i); 37 else if(leave && enter && b.steal(team)) stealaffinity(i, team); 38 } 39 } 40 leaveaffinitydefendservmode41 void leaveaffinity(int team, const vec &o) 42 { 43 moveaffinity(team, o, vec(-1e10f, -1e10f, -1e10f)); 44 } 45 enteraffinitydefendservmode46 void enteraffinity(int team, const vec &o) 47 { 48 moveaffinity(team, vec(-1e10f, -1e10f, -1e10f), o); 49 } 50 addscoredefendservmode51 void addscore(int i, int team, int points) 52 { 53 if(!points) return; 54 flag &b = flags[i]; 55 loopvk(clients) if(AA(clients[k]->actortype, abilities)&(1<<A_A_AFFINITY) && team == clients[k]->team && insideaffinity(b, clients[k]->o)) givepoints(clients[k], points, m_points(gamemode, mutators), false); 56 score &cs = teamscore(team); 57 cs.total += points; 58 sendf(-1, 1, "ri3", N_SCORE, team, cs.total); 59 } 60 updatedefendservmode61 void update() 62 { 63 int t = (gamemillis/G(defendinterval))-((gamemillis-(curtime+scoresec))/G(defendinterval)); 64 if(t < 1) { scoresec += curtime; return; } 65 else scoresec = 0; 66 loopv(flags) 67 { 68 flag &b = flags[i]; 69 if(b.enemy) 70 { 71 if(!b.owners || !b.enemies) 72 { 73 int pts = b.occupy(b.enemy, G(defendpoints)*(b.enemies ? b.enemies : -(1+b.owners))*t, defendcount, m_dac_quick(gamemode, mutators)); 74 if(pts > 0) loopvk(clients) if(AA(clients[k]->actortype, abilities)&(1<<A_A_AFFINITY) && b.owner == clients[k]->team && insideaffinity(b, clients[k]->o)) givepoints(clients[k], G(defendpoints), m_points(gamemode, mutators), false); 75 } 76 sendaffinity(i); 77 } 78 else if(b.owner) 79 { 80 if(!m_dac_king(gamemode, mutators) || b.owners) 81 { 82 b.points += G(defendpoints)*t; 83 int score = 0; 84 while(b.points >= G(defendhold)) 85 { 86 b.points -= G(defendhold); 87 score++; 88 } 89 if(score) addscore(i, b.owner, score); 90 } 91 sendaffinity(i); 92 } 93 } 94 } 95 96 void sendaffinity(int i, bool interim = false) 97 { 98 flag &b = flags[i]; 99 sendf(-1, 1, "ri5", N_INFOAFFIN, i, interim ? -1 : (b.enemy ? b.converted : 0), b.owner, b.enemy); 100 } 101 sendaffinitydefendservmode102 void sendaffinity() 103 { 104 packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); 105 initclient(NULL, p, false); 106 sendpacket(-1, 1, p.finalize()); 107 } 108 initclientdefendservmode109 void initclient(clientinfo *ci, packetbuf &p, bool connecting) 110 { 111 if(!hasflaginfo) return; 112 putint(p, N_SETUPAFFIN); 113 putint(p, flags.length()); 114 loopv(flags) 115 { 116 flag &b = flags[i]; 117 putint(p, b.kinship); 118 putint(p, b.yaw); 119 putint(p, b.pitch); 120 putint(p, b.converted); 121 putint(p, b.owner); 122 putint(p, b.enemy); 123 loopj(3) putint(p, int(b.o[j]*DMF)); 124 sendstring(b.name, p); 125 } 126 loopv(clients) 127 { 128 clientinfo *oi = clients[i]; 129 if(!oi || !oi->connected || (ci && oi->clientnum == ci->clientnum) || !oi->lastbuff) continue; 130 putint(p, N_SPHY); 131 putint(p, oi->clientnum); 132 putint(p, SPHY_BUFF); 133 putint(p, 1); 134 } 135 } 136 entergamedefendservmode137 void entergame(clientinfo *ci) 138 { 139 if(!canplay() || !hasflaginfo || ci->state != CS_ALIVE || !(AA(ci->actortype, abilities)&(1<<A_A_AFFINITY))) return; 140 enteraffinity(ci->team, ci->o); 141 } 142 spawneddefendservmode143 void spawned(clientinfo *ci) 144 { 145 if(!canplay() || !hasflaginfo || !(AA(ci->actortype, abilities)&(1<<A_A_AFFINITY))) return; 146 enteraffinity(ci->team, ci->o); 147 } 148 149 void leavegame(clientinfo *ci, bool disconnecting = false) 150 { 151 if(!canplay() || !hasflaginfo || ci->state != CS_ALIVE || !(AA(ci->actortype, abilities)&(1<<A_A_AFFINITY))) return; 152 leaveaffinity(ci->team, ci->o); 153 } 154 dieddefendservmode155 void died(clientinfo *ci, clientinfo *v) 156 { 157 if(!canplay() || !hasflaginfo || !(AA(ci->actortype, abilities)&(1<<A_A_AFFINITY))) return; 158 leaveaffinity(ci->team, ci->o); 159 } 160 moveddefendservmode161 void moved(clientinfo *ci, const vec &oldpos, const vec &newpos) 162 { 163 if(!canplay() || !hasflaginfo || !(AA(ci->actortype, abilities)&(1<<A_A_AFFINITY)) || ci->state != CS_ALIVE) return; 164 moveaffinity(ci->team, oldpos, newpos); 165 } 166 regendefendservmode167 void regen(clientinfo *ci, int &total, int &amt, int &delay) 168 { 169 if(!canplay() || !hasflaginfo || !G(defendregenbuff) || !ci->lastbuff) return; 170 if(G(maxhealth)) total = max(m_maxhealth(gamemode, mutators, ci->actortype), total); 171 if(ci->lastregen && G(defendregendelay)) delay = G(defendregendelay); 172 if(G(defendregenextra)) amt += G(defendregenextra); 173 } 174 checkclientdefendservmode175 void checkclient(clientinfo *ci) 176 { 177 if(!canplay() || !hasflaginfo || ci->state != CS_ALIVE || m_insta(gamemode, mutators)) return; 178 #define defendbuff4 (G(defendbuffing)&4 && b.occupied(m_dac_quick(gamemode, mutators), defendcount) >= G(defendbuffoccupy)) 179 #define defendbuff1 (G(defendbuffing)&1 && b.owner == ci->team && (!b.enemy || defendbuff4)) 180 #define defendbuff2 (G(defendbuffing)&2 && b.owner == T_NEUTRAL && (b.enemy == ci->team || defendbuff4)) 181 if(G(defendbuffing)) loopv(flags) 182 { 183 flag &b = flags[i]; 184 if((defendbuff1 || defendbuff2) && (G(defendbuffarea) ? insideaffinity(b, ci->o, G(defendbuffarea)) : true)) 185 { 186 if(!ci->lastbuff) sendf(-1, 1, "ri4", N_SPHY, ci->clientnum, SPHY_BUFF, 1); 187 ci->lastbuff = gamemillis; 188 return; 189 } 190 } 191 if(ci->lastbuff && (!G(defendbuffing) || gamemillis-ci->lastbuff >= G(defendbuffdelay))) 192 { 193 ci->lastbuff = 0; 194 sendf(-1, 1, "ri4", N_SPHY, ci->clientnum, SPHY_BUFF, 0); 195 } 196 } 197 parseaffinitydefendservmode198 void parseaffinity(ucharbuf &p) 199 { 200 int numflags = getint(p); 201 if(numflags) 202 { 203 loopi(numflags) 204 { 205 int kin = getint(p), yaw = getint(p), pitch = getint(p); 206 vec o; 207 loopj(3) o[j] = getint(p)/DMF; 208 string name; 209 getstring(name, p); 210 if(p.overread()) break; 211 if(!hasflaginfo && i < MAXPARAMS) addaffinity(o, kin, yaw, pitch, name); 212 } 213 if(!hasflaginfo) 214 { 215 hasflaginfo = true; 216 sendaffinity(); 217 loopv(clients) if(clients[i]->state == CS_ALIVE) entergame(clients[i]); 218 } 219 } 220 } 221 pointsdefendservmode222 int points(clientinfo *m, clientinfo *v) 223 { 224 bool isteam = m==v || m->team == v->team; 225 int p = isteam ? -1 : 1, q = p; 226 loopv(flags) if(insideaffinity(flags[i], m->o)) p += q; 227 return p; 228 } 229 balancedefendservmode230 void balance(int oldbalance) 231 { 232 static vector<int> owners[T_TOTAL], enemies[T_TOTAL], modified; 233 loopk(T_TOTAL) 234 { 235 owners[k].setsize(0); 236 enemies[k].setsize(0); 237 } 238 modified.setsize(0); 239 loopv(flags) 240 { 241 if(isteam(gamemode, mutators, flags[i].owner, T_FIRST)) 242 owners[flags[i].owner-T_FIRST].add(i); 243 if(isteam(gamemode, mutators, flags[i].enemy, T_FIRST)) 244 enemies[flags[i].enemy-T_FIRST].add(i); 245 } 246 loopk(numteams(gamemode, mutators)) 247 { 248 int from = mapbals[oldbalance][k], fromt = from-T_FIRST, to = mapbals[curbalance][k]; 249 loopv(owners[fromt]) 250 { 251 flags[owners[fromt][i]].owner = to; 252 if(modified.find(owners[fromt][i]) < 0) modified.add(owners[fromt][i]); 253 } 254 loopv(enemies[fromt]) 255 { 256 flags[enemies[fromt][i]].enemy = to; 257 if(modified.find(enemies[fromt][i]) < 0) modified.add(enemies[fromt][i]); 258 } 259 } 260 loopv(modified) sendaffinity(modified[i], true); 261 } 262 } defendmode; 263