// Assign bitmask to each player to indicate what team they are in // Called at match start and also when a client connects void BotsAssignTeamFlags (void) { gedict_t *p, *p2; int teamflag = 1; char *s = ""; if (!teamplay) return; // Clear teamflag from all items for (p = world; (p = nextent (p)); ) p->fb.teamflag = 0; for ( p = world; (p = find_plr( p )); ) p->k_flag = 0; for ( p = world; (p = find_plr( p )); ) { if( p->k_flag || strnull( s = getteam( p ) ) ) continue; p->k_flag = 1; p->fb.teamflag = teamflag; for (p2 = p; (p2 = find_plr (p2)); ) { if (streq (s, getteam (p2))) { p2->k_flag = 1; p2->fb.teamflag = teamflag; } } teamflag <<= 1; } }
// !!! do not confuse rpickup and pickup void vote_check_rpickup () { float frnd; int i, tn, pl_cnt, pl_idx; gedict_t *p; int veto; if ( match_in_progress || k_captains ) return; if ( !get_votes( OV_RPICKUP ) ) return; // Firstly obtain the number of players we have in total on server pl_cnt = CountPlayers(); if ( pl_cnt < 4 ) return; veto = is_admins_vote( OV_RPICKUP ); if( veto || !get_votes_req( OV_RPICKUP, true ) ) { vote_clear( OV_RPICKUP ); for( p = world; (p = find_plr( p )); ) p->k_teamnumber = 0; for( tn = 1; pl_cnt > 0; pl_cnt-- ) { frnd = g_random(); // bound is macros - so u _can't_ put g_random inside bound pl_idx = bound(0, (int)( frnd * pl_cnt ), pl_cnt-1 ); // select random player between 0 and pl_cnt for( i = 0, p = world; (p = find_plr( p )); ) { if ( p->k_teamnumber ) continue; if ( i == pl_idx ) { p->k_teamnumber = tn; tn = (tn == 1 ? 2 : 1); // next random player will be in other team if( p->k_teamnumber == 1 ) stuffcmd_flags(p, STUFFCMD_IGNOREINDEMO, "break\ncolor 4\nskin \"\"\nteam red\n"); else stuffcmd_flags(p, STUFFCMD_IGNOREINDEMO, "break\ncolor 13\nskin \"\"\nteam blue\n"); break; } i++; } } if ( veto ) G_bprint(2, "console: admin veto for %s\n", redtext("random pickup")); else G_bprint(2, "console: %s game it is then\n", redtext("random pickup")); return; } }
void PlayersStopFire() { gedict_t *p; for( p = world; (p = find_plr( p )); ) PlayerStopFire( p ); }
void AdminMatchStart () { gedict_t *p; int i = 0; for( p = world; (p = find_plr( p )); ) { if( p->ready ) { i++; } else { G_bprint(2, "%s was kicked by admin forcestart\n", p->netname); G_sprint(p, 2, "Bye bye! Pay attention next time.\n"); stuffcmd(p, "disconnect\n"); // FIXME: stupid way } } k_attendees = i; if( k_attendees ) { StartTimer(); } else { G_bprint(2, "Can't start! More players needed.\n"); EndMatch( 1 ); } }
// !!! do not confuse rpickup and pickup void vote_check_pickup () { gedict_t *p; int veto; if ( match_in_progress || k_captains ) return; if ( !get_votes( OV_PICKUP ) ) return; veto = is_admins_vote( OV_PICKUP ); if( veto || !get_votes_req( OV_PICKUP, true ) ) { vote_clear( OV_PICKUP ); if ( veto ) G_bprint(2, "console: admin veto for pickup\n"); else G_bprint(2, "console: a pickup game it is then\n"); for( p = world; (p = find_plr( p )); ) { stuffcmd_flags(p, STUFFCMD_IGNOREINDEMO, "break\n" "color 0\n" "team \"\"\n" "skin base\n"); } return; } }
void mctf() { if( match_in_progress && !k_matchLess ) return; if ( !isCTF() ) { G_sprint ( self, 2, "Can't do this in non CTF mode\n" ); return; } if ( !cvar("k_ctf_hook") && !cvar("k_ctf_runes") ) { G_sprint ( self, 2, "Already done\n" ); return; } cvar_fset("k_ctf_hook", 0); cvar_fset("k_ctf_runes", 0); G_sprint ( self, 2, "%s turn off: %s\n", getname(self), redtext("hook & runes") ); // In matchless mode, toggling runes and hook normally won't do anything since match is already in progress. Call this to handle this scenario. if (k_matchLess) { // If a player is carrying a rune when runes are disabled, get rid of it if (!cvar("k_ctf_runes")) { gedict_t * p; for (p = world; (p = find_plr(p)); ) { p->ctf_flag -= (p->ctf_flag & (CTF_RUNE_MASK)); p->maxspeed = cvar("sv_maxspeed"); // Reset speed, in case was carrying haste } } SpawnRunes( 0 ); AddHook ( false ); } }
void norunes() { if( match_in_progress && !k_matchLess ) return; if ( !isCTF() ) { G_sprint ( self, 2, "Can't do this in non CTF mode\n" ); return; } cvar_toggle_msg( self, "k_ctf_runes", redtext("runes") ); // In matchless mode, toggling runes normally won't do anything since match is already in progress. Call this to handle this scenario. if (k_matchLess) { // If a player is carrying a rune when runes are disabled, get rid of it if (!cvar("k_ctf_runes")) { gedict_t * p; for (p = world; (p = find_plr(p)); ) { p->ctf_flag -= (p->ctf_flag & (CTF_RUNE_MASK)); p->maxspeed = cvar("sv_maxspeed"); // Reset speed, in case was carrying haste } } SpawnRunes(cvar("k_ctf_runes")); // Toggle runes } }
void FrogbotPrePhysics1(void) { // gedict_t* p; for (p = world; (p = find_plr (p)); ) { if (p->isBot && p->s.v.takedamage) { VectorCopy(p->s.v.velocity, p->fb.oldvelocity); } } }
int NumberOfClients (void) { int count = 0; gedict_t* plr = NULL; for (plr = world; (plr = find_plr (plr)); ) { if (plr->ct == ctPlayer) { ++count; } } return count; }
gedict_t* BotsFirstBot (void) { gedict_t* first_bot = NULL; gedict_t* ent; for (ent = world; (ent = find_plr (ent)); ) { if (ent->isBot) { first_bot = ent; break; } } return first_bot; }
void FrogbotPrePhysics2() { no_bots_stuck = true; for (self = world; (self = find_plr (self)); ) { if (self->isBot) { BotDetectTrapped(self); if (self->s.v.takedamage) { VectorCopy(self->s.v.origin, self->s.v.oldorigin); } } } if (no_bots_stuck) { unstick_time = 0; } }
// ktpro (c) void force_spec() { qbool found = false; gedict_t *p = NULL; char *c_fs, arg_2[1024]; int i_fs, argc = trap_CmdArgc(); if ( !is_adm( self ) ) return; trap_CmdArgv( 1, arg_2, sizeof( arg_2 ) ); c_fs = (argc >= 2 ? arg_2 : ezinfokey(self, "fs")); if ( strnull( c_fs ) ) { G_sprint(self, 2, "set setinfo \"fs\" properly\n"); G_sprint(self, 2, "to force spec all not ready players\n"); G_sprint(self, 2, "type: %s\n", redtext("setinfo fs \"*\"")); G_sprint(self, 2, "or: %s to force spec specified player\n", redtext("setinfo fs \"playername\"")); G_sprint(self, 2, "or just: %s\n", redtext("/force_spec \"playername\"")); return; } if ( streq( c_fs, "*") || streq( c_fs, "* ") ) { //ok move all not ready players to specs for( p = world; (p = find_plr( p )); ) { if ( p->ready || p == self ) continue; found = true; do_force_spec(p, self, true); } } else { p = ( (i_fs = atoi( c_fs ) ) < 0 ? spec_by_id( -i_fs ) : SpecPlayer_by_IDorName( c_fs )); if ( p ) { found = true; do_force_spec(p, self, p->ct != ctSpec); } } if ( !found ) G_sprint(self, 2, "can't find specified players\n"); }
// convienence command for ctf admins // often times you play a game on non-symmetrical map as one color then swap teams and play again to be fair void AdminSwapAll() { gedict_t *p; if ( !is_adm( self ) ) return; if ( match_in_progress ) return; if ( !isCTF() ) return; for( p = world; (p = find_plr( p )); ) { if ( streq( getteam(p), "blue" ) ) stuffcmd_flags(p, STUFFCMD_IGNOREINDEMO, "team \"red\"\ncolor 4\n"); else if ( streq( getteam(p), "red" ) ) stuffcmd_flags(p, STUFFCMD_IGNOREINDEMO, "team \"blue\"\ncolor 13\n"); } G_bprint(2, "%s swapped the teams\n", getname( self ) ); }
// add/remove hook item to/from player void AddHook( qbool yes ) { gedict_t *e, *oself; oself = self; for ( e = world; (e = find_plr( e )); ) { e->s.v.items = (yes ? ((int) e->s.v.items | IT_HOOK) : ((int) e->s.v.items & ~IT_HOOK)); self = e; // warning if ( self->hook_out ) GrappleReset( self->hook ); self->hook_out = false; self->on_hook = false; if ( !yes && self->s.v.weapon == IT_HOOK ) { // actually remove hook from hands if hold, not just from items self->s.v.weapon = 0; W_SetCurrentAmmo(); } } self = oself; }
void DropFlag( gedict_t *flag, qbool tossed ) { gedict_t *p = PROG_TO_EDICT( flag->s.v.owner ); gedict_t *p1; p->ctf_flag -= ( p->ctf_flag & CTF_FLAG ); p->s.v.effects -= ( (int) p->s.v.effects & ( EF_FLAG1 | EF_FLAG2 )); p->s.v.items -= ( (int) p->s.v.items & (int) flag->s.v.items ); setorigin( flag, PASSVEC3(p->s.v.origin) ); flag->s.v.origin[2] -= 24; flag->cnt = FLAG_DROPPED; if ( tossed ) { trap_makevectors( p->s.v.v_angle ); if ( p->s.v.v_angle[0] ) { flag->s.v.velocity[0] = g_globalvars.v_forward[0] * 300 + g_globalvars.v_up[0] * 200; flag->s.v.velocity[1] = g_globalvars.v_forward[1] * 300 + g_globalvars.v_up[1] * 200; flag->s.v.velocity[2] = g_globalvars.v_forward[2] * 300 + g_globalvars.v_up[2] * 200; } else { aim( flag->s.v.velocity ); VectorScale( flag->s.v.velocity, 300, flag->s.v.velocity ); flag->s.v.velocity[2] = 200; } } else { SetVector( flag->s.v.velocity, 0, 0, 300 ); } flag->s.v.flags = FL_ITEM; flag->s.v.solid = SOLID_TRIGGER; flag->s.v.movetype = MOVETYPE_TOSS; setmodel( flag, flag->mdl ); setsize ( flag, -16, -16, 0, 16, 16, 74 ); flag->super_time = g_globalvars.time + FLAG_RETURN_TIME; if ( tossed ) { flag->s.v.nextthink = g_globalvars.time + 0.75; flag->s.v.think = (func_t) FlagResetOwner; } else { flag->s.v.owner = EDICT_TO_PROG( flag ); } G_bprint( 2, "%s", p->s.v.netname ); if ( streq(getteam(p), "red") ) G_bprint( 2, " %s the %s flag!\n", tossed ? redtext("tossed") : redtext("lost"), redtext("BLUE") ); else G_bprint( 2, " %s the %s flag!\n", tossed ? redtext("tossed") : redtext("lost"), redtext("RED") ); for ( p1 = world; (p1 = find_plr( p1 )); ) { if ( strneq(getteam(p), getteam(p1)) ) p1->carrier_hurt_time = -1; } refresh_plus_scores (); // update players status bar faster }
void FlagTouch() { gedict_t *p, *owner; if( !k_practice ) if ( match_in_progress != 2 ) return; if ( other->ct != ctPlayer ) return; if ( other->s.v.health < 1 ) return; if ( self->cnt == FLAG_RETURNED ) return; // if owner of the flag, do nothing (probably toss in progress) if ( self->s.v.owner == EDICT_TO_PROG( other ) ) return; // touching their own flag if ((self->k_teamnumber == 1 && streq(getteam(other), "red")) || (self->k_teamnumber == 2 && streq(getteam(other), "blue")) ) { if ( self->cnt == FLAG_AT_BASE ) { if ( other->ctf_flag & CTF_FLAG ) { gedict_t *cflag = NULL; // capture other->ctf_flag -= ( (int) other->ctf_flag & CTF_FLAG ); other->s.v.effects -= ( (int) other->s.v.effects & (EF_FLAG1 | EF_FLAG2) ); sound( other, CHAN_VOICE, "misc/flagcap.wav", 1, ATTN_NONE); G_bprint( 2, "%s", other->s.v.netname ); if ( self->k_teamnumber == 1 ) { cflag = find( world, FOFCLSN, "item_flag_team2" ); G_bprint( 2, " %s the %s flag!\n", redtext("captured"), redtext("BLUE") ); } else { cflag = find( world, FOFCLSN, "item_flag_team1" ); G_bprint( 2, " %s the %s flag!\n", redtext("captured"), redtext("RED") ); } if ( cflag ) G_bprint( 2, "The capture took %.1f seconds\n", cflag->cnt2 ); other->s.v.frags += CAPTURE_BONUS; other->ps.ctf_points += CAPTURE_BONUS; other->ps.caps++; // loop through all players on team to give bonus for ( p = world; (p = find_plr( p )); ) { p->s.v.items -= ( (int) p->s.v.items & (IT_KEY1 | IT_KEY2) ); if ( streq(getteam(p), getteam(other)) ) { if ( p->return_flag_time + RETURN_ASSIST_TIME > g_globalvars.time ) { p->return_flag_time = -1; p->s.v.frags += RETURN_ASSIST_BONUS; p->ps.ctf_points += RETURN_ASSIST_BONUS; G_bprint( 2, "%s gets an assist for returning his flag!\n", p->s.v.netname ); } if ( p->carrier_frag_time + CARRIER_ASSIST_TIME > g_globalvars.time ) { p->carrier_frag_time = -1; p->s.v.frags += CARRIER_ASSIST_BONUS; p->ps.ctf_points += CARRIER_ASSIST_BONUS; G_bprint( 2, "%s gets an assist for fragging the flag carrier!\n", p->s.v.netname ); } if ( p != other ) { p->s.v.frags += TEAM_BONUS; p->ps.ctf_points += TEAM_BONUS; } } else p->carrier_hurt_time = -1; } RegenFlags( true ); k_nochange = 0; // Set it so it should update scores at next attempt. refresh_plus_scores (); return; } return; } else if ( self->cnt == FLAG_DROPPED ) { other->s.v.frags += RETURN_BONUS; other->ps.ctf_points += RETURN_BONUS; other->ps.returns++; other->return_flag_time = g_globalvars.time; sound (other, CHAN_ITEM, self->s.v.noise1, 1, ATTN_NONE); RegenFlag( self ); G_bprint( 2, "%s", other->s.v.netname); if ( self->k_teamnumber == 1) G_bprint( 2, " %s the %s flag!\n", redtext("returned"), redtext("RED") ); else G_bprint( 2, " %s the %s flag!\n", redtext("returned"), redtext("BLUE") ); k_nochange = 0; // Set it so it should update scores at next attempt. refresh_plus_scores (); return; } } if ( strneq(getteam(other), "red") && strneq(getteam(other), "blue")) return; refresh_plus_scores (); // update players status bar faster // Pick up the flag sound( other, CHAN_ITEM, self->s.v.noise, 1, ATTN_NONE ); other->ctf_flag |= CTF_FLAG; other->s.v.items = (int) other->s.v.items | (int) self->s.v.items; self->cnt = FLAG_CARRIED; self->s.v.solid = SOLID_NOT; self->s.v.owner = EDICT_TO_PROG( other ); owner = PROG_TO_EDICT( self->s.v.owner ); owner->ps.pickups++; G_bprint( 2, "%s", other->s.v.netname ); if ( streq(getteam(other), "red") ) { G_bprint( 2, " %s the %s flag!\n", redtext("got"), redtext("BLUE") ); owner->s.v.effects = (int) owner->s.v.effects | EF_FLAG2; } else { G_bprint( 2, " %s the %s flag!\n", redtext("got"), redtext("RED") ); owner->s.v.effects = (int) owner->s.v.effects | EF_FLAG1; } setmodel( self, "" ); }