void TBI_SpawnPlayers() { int CurrentRedSpawn, CurrentBlueSpawn; int i_maxclients = maxclients->value; edict_t *cl_ent; CurrentRedSpawn = CurrentBlueSpawn = 0; OrganizeTeams(true); // Assign everyone a spawn for (cl_ent = g_edicts + 1; cl_ent != g_edicts + i_maxclients + 1; cl_ent++) { if (cl_ent->client && cl_ent->inuse && !G_IsSpectator(cl_ent)) // we never know { if (cl_ent->teamnum == RED_TEAM) // Red team { if (tbi_game.EntRedSpawns[CurrentRedSpawn] != NULL) // we got a valid spawn point { cl_ent->spawn = tbi_game.EntRedSpawns[CurrentRedSpawn]; CurrentRedSpawn++; if (CurrentRedSpawn == tbi_game.TotalRedSpawns) // we're out of spawns then huh CurrentRedSpawn = 0; } }else // Blue team { if (tbi_game.EntBlueSpawns[CurrentBlueSpawn] != NULL) { cl_ent->spawn = tbi_game.EntBlueSpawns[CurrentBlueSpawn]; CurrentBlueSpawn++; if (CurrentBlueSpawn == tbi_game.TotalBlueSpawns) CurrentBlueSpawn = 0; } } } } for (cl_ent = g_edicts + 1; cl_ent != g_edicts + i_maxclients + 1; cl_ent++) { vec3_t start; // Alrighty, everyone's got spawns. if (cl_ent->client && cl_ent->inuse && !G_IsSpectator(cl_ent)) { respawn(cl_ent); } } G_ResetPlayerState(NULL); }
int AddAllyExp (edict_t *ent, int exp) { int i, allies=0; edict_t *cl_ent; // get number of players allied with us allies = numAllies(ent); if (!allies) return 0; // divide experience evenly among allies exp /= allies+1; // award points to allies for (i=0 ; i<game.maxclients ; i++) { cl_ent = g_edicts+1+i; if (!cl_ent->inuse) continue; if (cl_ent->teamnum != ent->teamnum) continue; if (cl_ent->health < 0) continue; if (G_IsSpectator(cl_ent)) continue; if (cl_ent->flags & FL_CHATPROTECT) continue; V_AddFinalExp(cl_ent, exp); } //V_AddFinalExp(ent, exp); return exp; }
qboolean IsValidChaseTarget (edict_t *ent) { if (!ent->inuse) return false; // don't chase spectators if (ent->client) { if (G_IsSpectator(ent)) return false; } else { //gi.dprintf("not a client\n"); // the non-player entity must have the chaseable flag set if (!(ent->flags & FL_CHASEABLE)) return false; // don't chase dead monsters if ((ent->health < 1) || (ent->deadflag == DEAD_DEAD)) return false; } // don't chase any entity that is in noclip if ((ent->movetype == MOVETYPE_NOCLIP) && !(ent->flags & FL_WORMHOLE))//4.2 added wormhole exception { //gi.dprintf("noclip\n"); return false; } return true; }
void INV_AwardPlayers (void) { int i, points, credits, num_spawns = INV_GetNumPlayerSpawns(), num_winners = 0; edict_t *player; // we're not in invasion mode if (!INVASION_OTHERSPAWNS_REMOVED) return; // if map didn't end normally, don't award points if (level.time < timelimit->value*60) return; // no award if the humans were unable to defend their spawns if (num_spawns < 1) return; for (i=0; i<game.maxclients; i++) { player = g_edicts+1+i; if (!player->inuse) continue; if (invasion->value == 2) points = player->client->resp.score*((float)num_spawns/invasion_max_playerspawns) + 500 * invasion_difficulty_level; else points = player->client->resp.score*((float)num_spawns/invasion_max_playerspawns); if (invasion->value == 1 && points > INVASION_BONUS_EXP) points = INVASION_BONUS_EXP; //points = INVASION_BONUS_EXP*((float)num_spawns/invasion_max_playerspawns); if (invasion->value < 2) credits = INVASION_BONUS_CREDITS*((float)num_spawns/invasion_max_playerspawns); else credits = INVASION_BONUS_CREDITS*((float)num_spawns/invasion_max_playerspawns) + 1000 * invasion_difficulty_level; // gi.dprintf("points=%d credits=%d spawns=%d max=%d\n", // points, credits, num_spawns, invasion_max_playerspawns); if (!G_IsSpectator(player)) { int fexp = V_AddFinalExp(player, points); player->myskills.credits += credits; safe_cprintf(player, PRINT_MEDIUM, "Earned %d exp and %d credits!\n", fexp, credits); if (player->client && player->client->pers.score) // we've been here for a while at least num_winners++; } } if (num_winners) gi.bprintf(PRINT_HIGH, "Humans win! Players were awarded a bonus.\n"); }
int TBI_CountTeamPlayers(int team) { edict_t *cl_ent; int i_maxclients = maxclients->value; int total = 0; for (cl_ent = g_edicts + 1; cl_ent != g_edicts + i_maxclients + 1; cl_ent++) { if (!G_IsSpectator(cl_ent) && cl_ent->client && cl_ent->inuse && cl_ent->teamnum == team) total++; } return total; }
int V_HighestFragScore (void) { int i, highScore=0; edict_t *cl_ent; for (i=0 ; i<game.maxclients ; i++) { cl_ent = g_edicts + 1 + i; if (!cl_ent->inuse || G_IsSpectator(cl_ent)) continue; if (!highScore || (cl_ent->client->resp.frags > highScore)) highScore = cl_ent->client->resp.frags; } return highScore; }
int TeamValue (int teamnum) { int i, value=0; edict_t *cl_ent; for (i=0 ; i<game.maxclients ; i++) { cl_ent = g_edicts+1+i; if (!cl_ent->inuse) continue; if (G_IsSpectator(cl_ent)) continue; if (cl_ent->teamnum != teamnum) continue; value += cl_ent->myskills.level+1; // gi.dprintf("value %d: %d\n", teamnum, value); } return value; }
static edict_t *HiPlayer (void) { int i, j=0; edict_t *cl_ent, *found=NULL; for (i=0 ; i<game.maxclients ; i++) { cl_ent = g_edicts+1+i; if (!cl_ent->inuse) continue; if (G_IsSpectator(cl_ent)) continue; if (cl_ent->teamnum) continue; // already assigned a team if (!j || (cl_ent->myskills.level > j)) found = cl_ent; } return found; }
void dom_awardpoints (void) { int i, points, credits; edict_t *cl_ent; // flag has not been captured if (!DEFENSE_TEAM) return; FLAG_FRAMES++; // record frames flag has been captured // if (!(FLAG_FRAMES % 10)) // gi.dprintf("frames %d\n", FLAG_FRAMES); if (level.framenum % DOMINATION_AWARD_FRAMES) return; // not enough players if (total_players() < DOMINATION_MINIMUM_PLAYERS) return; for (i=0 ; i<game.maxclients ; i++) { cl_ent = g_edicts+1+i; //if (G_EntIsAlive(cl_ent) && (cl_ent->teamnum == DEFENSE_TEAM)) if (cl_ent && cl_ent->inuse && cl_ent->client && (cl_ent->health>0) && !G_IsSpectator(cl_ent) && (cl_ent->teamnum==DEFENSE_TEAM)) { points = DOMINATION_POINTS; credits = DOMINATION_CREDITS; // flag carrier gets extra points if (cl_ent->client->pers.inventory[flag_index]) { points *= 3; credits *= 3; } /* cl_ent->myskills.experience += points; cl_ent->client->resp.score += points; check_for_levelup(cl_ent); */ cl_ent->myskills.credits += credits; V_AddFinalExp(cl_ent, points); } } }
qboolean V_CanPickUpItem (edict_t *ent) { int i; // only allow clients that are alive and haven't just // respawned to pick up a rune //if (!ent->client || !G_EntIsAlive(ent) || (ent->client->respawn_time > level.time)) // return false; if (!ent || !ent->inuse || !ent->client || G_IsSpectator(ent) || (ent->client->respawn_time > level.time)) return false; // do we have any space in our inventory? // Skip hand, neck, and belt slots for (i=3; i < MAX_VRXITEMS; ++i) { if (!ent->myskills.items[i].itemtype) return true; } return false; }
edict_t *INV_SelectPlayerSpawnPoint (edict_t *ent) { if (!ent || !ent->inuse) return NULL; // spectators always get a spawn if (G_IsSpectator(ent)) return INV_GetRandomSpawn(); if (ent->spawn && ent->spawn->inuse) return ent->spawn; else // We requested a spawn point, but we don't have one. What now? { // Try to find one. But only if the spawn que is empty. if (INV_IsSpawnQueEmpty()) return INV_GetRandomSpawn(); } return NULL; }
edict_t* TBI_FindSpawn(edict_t *ent) { edict_t *potential_spot; int iter = 0; if (!ent) return NULL; if (!ent->client || !ent->inuse) return NULL; if (G_IsSpectator(ent)) { return SelectDeathmatchSpawnPoint(ent); } if (!ent->teamnum) { TBI_AssignTeam(ent); } if (ent->spawn) { edict_t* spawn = ent->spawn; ent->spawn = NULL; return spawn; } potential_spot = TBI_FindRandomSpawnForTeam(ent->teamnum); while (potential_spot->deadflag == DEAD_DEAD && iter != 256) { iter++; // don't let it drift off for too long potential_spot = TBI_FindRandomSpawnForTeam(ent->teamnum); } if (potential_spot->deadflag == DEAD_DEAD) // so didn't find an alive spot? return SelectDeathmatchSpawnPoint(ent) ; // find a random one return potential_spot; }
void TBI_AwardTeam(int Teamnum, int exp, qboolean Broadcast) { edict_t *cl_ent; int i_maxclients = maxclients->value; if (TBI_CountActivePlayers() < 4) // we can't give experience if there's not enough active players return; for (cl_ent = g_edicts + 1; cl_ent != g_edicts + i_maxclients + 1; cl_ent++) { if (!G_IsSpectator(cl_ent) && cl_ent->client && cl_ent->inuse) { if (cl_ent->teamnum == Teamnum) V_AddFinalExp(cl_ent, exp); cl_ent->myskills.credits += exp * 2 / 3; // 2/3s the exp. } } if (Broadcast) gi.bprintf(PRINT_HIGH, "Awarded team %s a total of %d experience points and %d credits!\n", Teamnum == RED_TEAM ? "Red" : "Blue", exp, exp * 2 / 3); }
void dom_dropflag (edict_t *ent, gitem_t *item) { edict_t *flag; //if (!G_EntExists(ent)) // return; if (!ent || !ent->inuse || G_IsSpectator(ent)) return; if (!domination->value || !ent->client->pers.inventory[flag_index]) return; gi.bprintf(PRINT_HIGH, "%s dropped the flag.\n", ent->client->pers.netname); flag = Drop_Item (ent, item); flag->think = dom_flagthink; flag->count = 0; //Wait a second before starting to think flag->nextthink = level.time + 1.0; ent->client->pers.inventory[ITEM_INDEX(item)] = 0; ValidateSelectedItem (ent); DEFENSE_TEAM = 0; //FLAG_FRAMES = 0; if (SpawnWaitingPlayers()) OrganizeTeams(true); }
void UpdateChaseCam (edict_t *ent) { int i; edict_t *old, *targ; vec3_t start, goal; vec3_t angles, forward, right; trace_t tr; qboolean eyecam=false; if (!ent->client->chase_target) return; if (!G_IsSpectator(ent)) return; //gi.dprintf("updating chase for %s\n", ent->client->pers.netname); // is our chase target no longer valid? if (!IsValidChaseTarget(ent->client->chase_target)) { old = ent->client->chase_target; ChaseNext(ent); // try to find a new chase target if (ent->client->chase_target == old) { // switch out of chase-cam mode ent->client->chase_target = NULL; ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION; ent->client->ps.pmove.pm_flags &= ~PMF_DUCKED; // quit ducked. return; } } targ = ent->client->chase_target; if (PM_MonsterHasPilot(targ)) targ = targ->owner; VectorCopy(targ->s.origin, start); // use client's viewing angle if (targ->client) VectorCopy(targ->client->v_angle, angles); // use pilot's viewing angle /* else if (PM_MonsterHasPilot(targ)) { VectorCopy(targ->owner->s.origin, start); VectorCopy(targ->owner->client->v_angle, angles); } */ // use non-client's angles else VectorCopy(targ->s.angles, angles); if (ent->client->chasecam_mode) eyecam = true; // if we're chasing a non-client entity that has a valid enemy // within our sights, then modify our viewing pitch if (eyecam && !targ->client && G_ValidTarget(targ, targ->enemy, true) && infov(targ, targ->enemy, 90)) { VectorSubtract(targ->enemy->s.origin, targ->s.origin, forward); vectoangles(forward, forward); angles[PITCH] = forward[PITCH]; //gi.dprintf("pitch %d\n", (int)forward[PITCH]); } if (!eyecam) { if (angles[PITCH] > 56) angles[PITCH] = 56; if (angles[PITCH] < -56) angles[PITCH] = -56; } AngleVectors (angles, forward, right, NULL); VectorNormalize(forward); if (eyecam) { // save current player fov float fov = ent->client->ps.fov; if (targ->viewheight) start[2] += targ->viewheight; else start[2] = targ->absmax[2]-8; VectorMA(start, targ->maxs[1]+16, forward, start); // update HUD if (targ->client) ent->client->ps = targ->client->ps; else ent->client->ps.gunindex = 0; // restore player's fov (don't use target's fov) ent->client->ps.fov = fov; } else { ent->client->ps.gunindex = 0; // special conditions for upside-down minisentry if (targ->owner && (targ->mtype == M_MINISENTRY) && (targ->owner->style == SENTRY_FLIPPED)) { start[2] = targ->absmin[2]-16; } else { if (targ->viewheight) start[2] += targ->viewheight; else start[2] = targ->absmax[2]-8; VectorMA(start, targ->mins[1]-16, forward, start); } } // jump animation lifts if (!targ->groundentity) start[2] += 16; tr = gi.trace(targ->s.origin, NULL, NULL, start, targ, MASK_SOLID); VectorCopy(tr.endpos, start); if (tr.fraction < 1) { if (eyecam) VectorMA(start, -12, forward, start); else VectorMA(start, 12, forward, start); } VectorCopy(start, goal); // pad for floors and ceilings VectorCopy(goal, start); start[2] += 6; tr = gi.trace(goal, vec3_origin, vec3_origin, start, targ, MASK_SOLID); if (tr.fraction < 1) { VectorCopy(tr.endpos, goal); goal[2] -= 6; } VectorCopy(goal, start); start[2] -= 6; tr = gi.trace(goal, vec3_origin, vec3_origin, start, targ, MASK_SOLID); if (tr.fraction < 1) { VectorCopy(tr.endpos, goal); goal[2] += 6; } if (targ->deadflag) ent->client->ps.pmove.pm_type = PM_DEAD; else ent->client->ps.pmove.pm_type = PM_FREEZE; VectorCopy(goal, ent->s.origin); for (i=0 ; i<3 ; i++) { ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(angles[i] - ent->client->resp.cmd_angles[i]); } if (targ->deadflag) { ent->client->ps.viewangles[ROLL] = 40; ent->client->ps.viewangles[PITCH] = -15; if (targ->client) ent->client->ps.viewangles[YAW] = targ->client->killer_yaw; else ent->client->ps.viewangles[YAW] = 0; } else { VectorCopy(angles, ent->client->ps.viewangles); VectorCopy(angles, ent->client->v_angle); } ent->viewheight = 0; ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION; gi.linkentity(ent); }
qboolean validDmgPlayer (edict_t *player) { return (player && player->inuse && player->client && !G_IsSpectator(player)); }
qboolean dom_pickupflag (edict_t *ent, edict_t *other) { int i; edict_t *cl_ent; //if (!G_EntExists(other)) // return false; if (!other || !other->inuse || !other->client || G_IsSpectator(other)) return false; //if ((other->myskills.class_num == CLASS_POLTERGEIST) || other->mtype) // return false; // poltergeist and morphed players can't pick up flag // unmorph morphed players if (other->mtype) { other->mtype = 0; other->s.modelindex = 255; other->s.skinnum = ent-g_edicts-1; ShowGun(other); } // if this is a player-monster, remove the monster and restore the player if (PM_PlayerHasMonster(other)) PM_RemoveMonster(other); // disable movement abilities if (other->client) { //jetpack other->client->thrusting = 0; //grapple hook other->client->hook_state = HOOK_READY; } // super speed other->superspeed = false; // antigrav other->antigrav = false; VortexRemovePlayerSummonables(other); // disable scanner if (other->client->pers.scanner_active & 1) other->client->pers.scanner_active = 0; // reset their velocity VectorClear(other->velocity); // alert everyone gi.bprintf(PRINT_HIGH, "%s got the flag!\n", other->client->pers.netname); gi.bprintf(PRINT_HIGH, "The %s team is now in control.\n", TeamName(other)); // alert teammates for (i=0 ; i<game.maxclients ; i++) { cl_ent = g_edicts+1+i; if (G_EntExists(cl_ent) && (cl_ent->teamnum == other->teamnum) && (cl_ent != other)) gi.centerprintf(cl_ent, "Protect the flag carrier!\n"); } DEFENSE_TEAM = other->teamnum; // if a new team takes control of the flag, then reset the counter if (PREV_DEFENSE_TEAM != DEFENSE_TEAM) FLAG_FRAMES = 0; PREV_DEFENSE_TEAM = DEFENSE_TEAM; gi.sound(other, CHAN_ITEM, gi.soundindex("world/xianbeats.wav"), 1, ATTN_NORM, 0); other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1; return true; }
void dom_fragaward (edict_t *attacker, edict_t *target) { int points = DOMINATION_FRAG_POINTS; float dist; edict_t *carrier, *targ; targ = target; // this could possibly be a non-client entity attacker = G_GetClient(attacker); target = G_GetClient(target); if (!DEFENSE_TEAM) return; if (FLAG_FRAMES < 100) return; // flag must be captured for at least 10 seconds //if (!G_EntExists(attacker) || !G_EntExists(target)) // return; // basic sanity checks if (!attacker || !attacker->inuse || G_IsSpectator(attacker) || !target || !target->inuse || G_IsSpectator(target)) return; if (attacker == target) return; if (attacker->health < 1) return; if (((carrier = dom_flagcarrier()) != NULL) && (carrier != attacker)) { dist = entdist(carrier, targ); if (OnSameTeam(attacker, carrier)) { // if we are on the same team as the flag carrier and the // enemy was close to the carrier, then award a bonus for // protecting the flag if (dist <= DOMINATION_DEFEND_RANGE) { gi.bprintf(PRINT_HIGH, "%s defends the flag carrier!\n", attacker->client->pers.netname); points = DOMINATION_DEFEND_BONUS; gi.sound(carrier, CHAN_ITEM, gi.soundindex("speech/excelent.wav"), 1, ATTN_NORM, 0); } } else if (carrier == targ) { // award a bonus for killing the flag carrier gi.bprintf(PRINT_HIGH, "%s kills the flag carrier!\n", attacker->client->pers.netname); points = DOMINATION_CARRIER_BONUS; gi.sound(attacker, CHAN_ITEM, gi.soundindex("ctf/flagcap.wav"), 1, ATTN_NORM, 0); } else if (dist <= DOMINATION_DEFEND_RANGE) { // award a bonus for killing flag defense gi.bprintf(PRINT_HIGH, "%s kills a defender!\n", attacker->client->pers.netname); points = DOMINATION_OFFENSE_BONUS; gi.sound(attacker, CHAN_ITEM, gi.soundindex("speech/idoasskk.wav"), 1, ATTN_NORM, 0); } } else if (attacker->teamnum == DEFENSE_TEAM) return; // no further bonuses available for defense team /* attacker->myskills.experience += points; attacker->client->resp.score += points; check_for_levelup(attacker); */ V_AddFinalExp(attacker, points); }