| 1357 | } |
| 1358 | |
| 1359 | void flagaction(int flag, int action, int actor) |
| 1360 | { |
| 1361 | if(!valid_flag(flag)) return; |
| 1362 | sflaginfo &f = sg->sflaginfos[flag]; |
| 1363 | sflaginfo &of = sg->sflaginfos[team_opposite(flag)]; |
| 1364 | bool deadactor = valid_client(actor) ? clients[actor]->state.state != CS_ALIVE || team_isspect(clients[actor]->team): true; |
| 1365 | int abort = 0; |
| 1366 | int score = 0; |
| 1367 | int message = -1; |
| 1368 | |
| 1369 | if(m_ctf || m_htf) |
| 1370 | { |
| 1371 | switch(action) |
| 1372 | { |
| 1373 | case FA_PICKUP: // ctf: f = enemy team htf: f = own team |
| 1374 | case FA_STEAL: |
| 1375 | { |
| 1376 | if(deadactor || f.state != (action == FA_STEAL ? CTFF_INBASE : CTFF_DROPPED) || !flagdistance(f, actor)) { abort = 10; break; } |
| 1377 | int team = team_base(clients[actor]->team); |
| 1378 | if(m_ctf) team = team_opposite(team); |
| 1379 | if(team != flag) { abort = 11; break; } |
| 1380 | f.state = CTFF_STOLEN; |
| 1381 | f.actor_cn = actor; |
| 1382 | message = FM_PICKUP; |
| 1383 | break; |
| 1384 | } |
| 1385 | case FA_LOST: |
| 1386 | if(actor == -1) actor = f.actor_cn; |
| 1387 | case FA_DROP: |
| 1388 | if(f.state!=CTFF_STOLEN || f.actor_cn != actor) { abort = 12; break; } |
| 1389 | f.state = CTFF_DROPPED; |
| 1390 | loopi(3) f.pos[i] = clients[actor]->state.o[i]; |
| 1391 | message = action == FA_LOST ? FM_LOST : FM_DROP; |
| 1392 | break; |
| 1393 | case FA_RETURN: |
| 1394 | if(f.state!=CTFF_DROPPED || m_htf) { abort = 13; break; } |
| 1395 | f.state = CTFF_INBASE; |
| 1396 | message = FM_RETURN; |
| 1397 | break; |
| 1398 | case FA_SCORE: // ctf: f = carried by actor flag, htf: f = hunted flag (run over by actor) |
| 1399 | if(m_ctf) |
| 1400 | { |
| 1401 | if(f.state != CTFF_STOLEN || f.actor_cn != actor || of.state != CTFF_INBASE || !flagdistance(of, actor)) { abort = 14; break; } |
| 1402 | score = 1; |
| 1403 | message = FM_SCORE; |
| 1404 | } |
| 1405 | else // m_htf |
| 1406 | { |
| 1407 | if(f.state != CTFF_DROPPED || !flagdistance(f, actor)) { abort = 15; break; } |
| 1408 | score = (of.state == CTFF_STOLEN) ? 1 : 0; |
| 1409 | message = score ? FM_SCORE : FM_SCOREFAIL; |
| 1410 | if(of.actor_cn == actor) score *= 2; |
| 1411 | } |
| 1412 | f.state = CTFF_INBASE; |
| 1413 | break; |
| 1414 | |
| 1415 | case FA_RESET: |
| 1416 | f.state = CTFF_INBASE; |
no test coverage detected