void nospecs( ) { int votes; if ( match_in_progress ) { G_sprint(self, 2, "%s mode %s\n", redtext("No spectators"), OnOff(cvar("_k_nospecs"))); return; } // admin may turn this status alone on server... if ( !is_adm( self ) ) { // Dont need to bother if less than 2 players if ( CountPlayers() < 2 && !cvar("_k_nospecs") ) { G_sprint(self, 2, "You need at least 2 players to do this.\n"); return; } } self->v.nospecs = !self->v.nospecs; G_bprint(2, "%s %s!%s\n", self->netname, (self->v.nospecs ? redtext(va("votes for nospecs %s", OnOff(!cvar("_k_nospecs")))) : redtext(va("withdraws %s nospecs vote", g_his(self)))), ((votes = get_votes_req( OV_NOSPECS, true )) ? va(" (%d)", votes) : "")); vote_check_nospecs (); }
// !!! 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 BecomeAdmin(gedict_t *p, int adm_flags) { G_bprint(2, "%s %s!\n", p->netname, redtext("gains admins status")); G_sprint(p, 2, "Please give up admin rights when you're done\n" "Type %s for info\n", redtext("commands")); p->k_admin |= adm_flags; on_admin( p ); }
void sv_lock () { int lock_time = 15; if ( !k_sv_locktime ) { G_bprint(2, "%s %s for %s seconds\n", getname(self), redtext("locked server"), dig3(lock_time)); k_sv_locktime = g_globalvars.time + lock_time; } else { G_bprint(2, "%s %s\n", getname(self), redtext("unlocked server")); k_sv_locktime = 0; } }
// this was part of T_Damage(), but I split it, so less mess void MidairDamageBonus(gedict_t *attacker, float midheight) { attacker->ps.mid_total++; G_bprint( 2, "%s got ", attacker->s.v.netname ); if ( midheight > 1024 ) { attacker->ps.mid_platinum++; attacker->s.v.frags += 8; G_bprint( 2, "%s", redtext("platinum") ); } else if ( midheight > 512 ) { attacker->ps.mid_gold++; attacker->s.v.frags += 4; G_bprint( 2, "%s", redtext("gold") ); } else if ( midheight > 256 ) { attacker->ps.mid_silver++; attacker->s.v.frags += 2; G_bprint( 2, "%s", redtext("silver") ); } else { attacker->ps.mid_bronze++; attacker->s.v.frags += 1; G_bprint( 2, "%s", redtext("bronze") ); } G_bprint(2, " midair"); if (midheight > 128) G_bprint(2, " (height: %s)\n", dig3s( "%.1f", midheight)); else G_bprint(2, "\n"); if (attacker->ps.mid_total > 1) { attacker->ps.mid_totalheight += midheight; attacker->ps.mid_avgheight = attacker->ps.mid_totalheight / attacker->ps.mid_total; } else { attacker->ps.mid_totalheight = attacker->ps.mid_avgheight = midheight; } if (attacker->ps.mid_maxheight < midheight) attacker->ps.mid_maxheight = midheight; }
void NextClient () { int from = 0; if( !self->k_kicking ) return; self->k_playertokick = (self->k_playertokick ? self->k_playertokick : world); from = ( self->k_playertokick != world && self->k_playertokick->ct == ctSpec ); self->k_playertokick = find_plrspc(self->k_playertokick, &from); if ( !self->k_playertokick ) { // try find anyone at least from = 0; self->k_playertokick = find_plrspc(world, &from); } if ( !self->k_playertokick ) { G_sprint(self, 2, "Can't find anybody to kick\n"); ExitKick ( self ); return; } G_sprint(self, 2, "Kick %s %s?\n", redtext(self->k_playertokick->ct == ctPlayer ? "player" : "spectator"), getname(self->k_playertokick)); }
void FlagThink() { if ( !isCTF() ) return; self->s.v.nextthink = g_globalvars.time + 0.1; if (self->cnt == FLAG_AT_BASE) return; if (self->cnt == FLAG_DROPPED) { self->cnt2 += 0.1; if ( g_globalvars.time > self->super_time ) { RegenFlag( self ); G_bprint( 2, "The %s flag has been returned\n", redtext( ( (int) self->s.v.items & IT_KEY1) ? "BLUE" : "RED" ) ); } return; } if (self->cnt == FLAG_RETURNED) { setorigin( self, PASSVEC3(self->s.v.oldorigin) ); self->cnt = FLAG_AT_BASE; return; } self->cnt2 += 0.1; }
void ReadyThink () { float i1; char *txt, *gr; gedict_t *p=NULL, *p2=NULL; p2 = PROG_TO_EDICT( self->s.v.owner ); if( ( p2->ct == ctPlayer && !( p2->ready ) ) // forcestart breaked via break command || ( p2->ct == ctSpec && !k_force ) // forcestart breaked via forcebreak command (spectator admin) ) { k_force = 0; G_bprint(2, "%s interrupts countdown\n", p2->netname ); ent_remove ( self ); return; } k_attendees = CountPlayers(); if ( !isCanStart(NULL, true) ) { k_force = 0; G_bprint(2, "Forcestart canceled\n"); ent_remove ( self ); return; } self->attack_finished--; i1 = self->attack_finished; if( i1 <= 0 ) { k_force = 0; AdminMatchStart(); ent_remove ( self ); return; } txt = va( "%s second%s left before game starts", dig3( i1 ), ( i1 == 1 ? "" : "s") ); gr = va( "\n%s!", redtext("Get ready") ); for( p = world; (p = find_client( p )); ) if ( p->ct == ctPlayer ) G_centerprint(p, "%s%s", txt, (p->ready ? "" : gr)); else G_centerprint(p, "%s", txt); self->s.v.nextthink = g_globalvars.time + 1; }
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 AdminImpBot () { float coef, i1; if( self->k_adminc < 1 ) { self->k_adminc = 0; return; } i1 = (int)(self->k_adminc -= 1); coef = self->s.v.impulse; while( i1 > 0 ) { coef *= 10; i1--; } self->k_added += coef; if( self->k_adminc < 1 ) { int iPass = cvar( "k_admincode" ); int till = Q_rint(self->k_adm_lasttime + 5 - g_globalvars.time); self->k_adminc = 0; if( self->k_adm_lasttime && till > 0 ) { // probably must help against brute force G_sprint(self, 2, "Wait %d second%s!\n", till, count_s(till) ); return; } if( iPass && self->k_added == iPass ) { BecomeAdmin(self, AF_REAL_ADMIN); return; } else { G_sprint(self, 2, "%s...\n", redtext("Access denied")); self->k_adm_lasttime = g_globalvars.time; } } else G_sprint(self, 2, "%d %s\n", (int)self->k_adminc, redtext("more to go")); }
void FixNoSpecs( void ) { // turn off "no specs" mode if there no players left if ( g_globalvars.time > 10 && !match_in_progress && !CountPlayers() && cvar("_k_nospecs") ) { G_bprint(2, "%s mode turned off\n", redtext("No spectators")); cvar_set("_k_nospecs", "0"); } }
void vote_check_nospecs () { int veto; if ( match_in_progress || intermission_running || match_over ) return; if ( !get_votes( OV_NOSPECS ) ) return; veto = is_admins_vote( OV_NOSPECS ); if( veto || !get_votes_req( OV_NOSPECS, true ) ) { vote_clear( OV_NOSPECS ); // set no specs mode cvar_fset("_k_nospecs", !cvar("_k_nospecs")); if ( veto ) G_bprint(2, "%s\n", redtext(va("No spectators mode %s by admin veto", OnOff(cvar("_k_nospecs"))))); else G_bprint(2, "%s\n", redtext(va("No spectators mode %s by majority vote", OnOff(cvar("_k_nospecs"))))); // kick specs if ( cvar("_k_nospecs") ) { gedict_t *spec; for ( spec = world; (spec = find_spc( spec )); ) { if ( VIP( spec ) & ALLOWED_NOSPECS_VIPS ) continue; // don't kick this VIP if ( is_real_adm(spec) ) continue; // don't kick real admin stuffcmd(spec, "disconnect\n"); // FIXME: stupid way } } return; } }
void votecoop( ) { int votes; if ( deathmatch && match_in_progress ) { G_sprint(self, 2, "Match in progress and deathmatch is non zero, you can't vote for coop\n"); return; } self->v.coop = !self->v.coop; G_bprint(2, "%s %s!%s\n", self->s.v.netname, (self->v.coop ? redtext(va("votes for coop %s", OnOff(!cvar("coop")))) : redtext(va("withdraws %s coop vote", g_his(self)))), ((votes = get_votes_req( OV_COOP, true )) ? va(" (%d)", votes) : "")); vote_check_coop (); }
// 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"); }
void TogglePreWar () { int k_prewar = bound(0, cvar( "k_prewar" ), 2); if (!is_adm(self)) { return; } if (++k_prewar > 2) { k_prewar = 0; } switch ( k_prewar ) { case 1: if( !match_in_progress ) G_bprint(2, "Players may fire before match\n"); else G_sprint(self, 2, "Players may fire before match\n"); break; case 2: if ( !match_in_progress ) { G_bprint(2, "Players may fire and jump when %s\n", redtext("ready")); PlayersStopFire(); } else G_sprint(self, 2, "Players may fire and jump when %s\n", redtext("ready")); break; case 0: default: if ( !match_in_progress ) { G_bprint(2, "Players may %s fire before match\n", redtext("not")); PlayersStopFire(); } else G_sprint(self, 2, "Players may %s fire before match\n", redtext("not")); break; } cvar_fset( "k_prewar", k_prewar ); }
void ToggleFallBunny () { if( match_in_progress ) return; if ( k_yawnmode ) { G_sprint(self, 2, "Command blocked because yawnmode is active\n"); return; } cvar_toggle_msg( self, "k_fallbunny", redtext("fallbunny") ); }
qbool SpecCanConnect( gedict_t *spec ) { extern qbool nospecs_canconnect( gedict_t *spec ); if ( !nospecs_canconnect( spec ) ) { G_sprint( spec, 2, "%s mode, you can't connect\n", redtext("No spectators") ); return false; } return true; }
void norunes() { if( match_in_progress ) 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") ); }
void noga() { if( match_in_progress ) return; if ( !isCTF() ) { G_sprint ( self, 2, "Can't do this in non CTF mode\n" ); return; } cvar_toggle_msg( self, "k_ctf_ga", redtext("green armor") ); }
void AdminForceStart () { gedict_t *mess; if (match_in_progress || match_over || !is_adm(self)) { return; } // no forcestart in practice mode if ( k_practice ) { G_sprint(self, 2, "%s\n", redtext("Server in practice mode")); return; } if( self->ct == ctPlayer && !self->ready ) { PlayerReady(); if ( !self->ready ) { G_sprint(self, 2, "Ready yourself first\n"); return; } } if( find(world, FOFCLSN, "mess") ) { G_sprint(self, 2, "forcestart already in progress!\n"); return; } k_attendees = CountPlayers(); if ( !isCanStart( self, true ) ) { G_sprint(self, 2, "Can't issue!\n"); return; } if( k_attendees ) { G_bprint(2, "%s forces matchstart!\n", self->netname); k_force = 1; mess = spawn(); mess->classname = "mess"; mess->s.v.owner = EDICT_TO_PROG( self ); mess->think = ( func_t ) ReadyThink; mess->s.v.nextthink = g_globalvars.time + 0.1; mess->attack_finished = 10 + 1; } else G_sprint(self, 2, "Can't issue! More players needed.\n"); }
void vote_check_map () { int vt_req = get_votes_req( OV_MAP, true ); char *m = ""; if ( maps_voted_idx < 0 || strnull( m = GetMapName(maps_voted[maps_voted_idx].map_id) ) ) return; if ( !k_matchLess ) if ( match_in_progress ) return; if ( maps_voted[maps_voted_idx].admins ) G_bprint(2, "%s\n", redtext("Admin veto")); else if( !vt_req ) G_bprint(2, "%s votes for mapchange.\n", redtext("Majority")); else return; vote_clear( OV_MAP ); changelevel( m ); }
void vote_check_break () { if ( !match_in_progress || intermission_running || match_over ) return; if( !get_votes_req( OV_BREAK, true ) ) { vote_clear( OV_BREAK ); G_bprint(2, "%s\n", redtext("Match stopped by majority vote")); EndMatch( 1 ); return; } }
void KickThink () { if( !self->k_kicking ) return; if ( self->k_kicking + 60 < g_globalvars.time ) { // Check the 1 minute timeout for kick mode G_sprint( self, 2, "Your %s mode has timed out\n", redtext("kick")); ExitKick( self ); return; } if ( !is_adm( self ) ) { ExitKick( self ); // not admin now, so cancel kick mode, just for sanity return; } }
void CTFBasedSpawn() { if( match_in_progress ) return; if ( !isCTF() ) { G_sprint ( self, 2, "Can't do this in non CTF mode\n" ); return; } if ( cvar("k_ctf_based_spawn") && ( find_cnt(FOFCLSN, "info_player_deathmatch") <= 1 ) ) { G_sprint ( self, 2, "Spawn on base enforced due to map limitation\n" ); return; } cvar_toggle_msg( self, "k_ctf_based_spawn", redtext("spawn on base") ); }
void mctf() { if( match_in_progress ) 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") ); }
void AdminKick () { int argc = trap_CmdArgc(); if( !is_adm( self ) ) { G_sprint(self, 2, "You are not an admin\n"); return; } if( self->k_kicking ) { ExitKick( self ); return; } if ( argc >= 2 ) { gedict_t *p; char arg_2[1024], *str; trap_CmdArgv( 1, arg_2, sizeof( arg_2 ) ); if ( !(p = SpecPlayer_by_IDorName( arg_2 )) && !(p = not_connected_by_IDorName( arg_2 )) ) { G_sprint(self, 2, "kick: client %s not found\n", arg_2); return; } if ( DoKick( p, self ) && !strnull( str = params_str(2, -1) ) ) // show reason G_bprint(2, "\x90%s\x91\n", str); return; } G_sprint(self, 2, "Kicking process started\n" "�����������������������\n" "Type \371 to kick, \356 for next, %s to leave\n", redtext("kick")); self->k_kicking = g_globalvars.time; self->k_playertokick = world; NextClient(); }
void nohook() { 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_hook", redtext("hook") ); // In matchless mode, toggling hook normally won't do anything since match is already in progress. Call this to handle this scenario. if (k_matchLess) { if ( cvar("k_ctf_hook") ) { AddHook( true ); } else { AddHook( false ); } } }
void VoteAdmin() { gedict_t *p; int till; gedict_t *electguard; // Can't allow election and code entering for the same person at the same time if( self->k_adminc ) { G_sprint(self, 2, "Finish entering the code first\n"); return; } if( is_adm( self ) ) { G_sprint(self, 2, "You are already an admin\n"); return; } if( is_elected( self, etAdmin ) ) { G_bprint(2, "%s %s!\n", self->netname, redtext("aborts election")); AbortElect(); return; } // Only one election per server because otherwise we wouldn't know how to count // "yes"s or "no"s if( get_votes( OV_ELECT ) ) { G_sprint(self, 2, "An election is already in progress\n"); return; } if( !cvar( "k_admins" ) ) { G_sprint(self, 2, "%s on this server!\n", redtext("NO admins")); return; } // Check if voteadmin is allowed if( !cvar( "k_allowvoteadmin" ) ) { G_sprint(self, 2, "Admin election is not allowed on this server\n"); return; } if( (till = Q_rint( self->v.elect_block_till - g_globalvars.time)) > 0 ) { G_sprint(self, 2, "Wait %d second%s!\n", till, count_s(till) ); return; } if( self->ct == ctSpec && match_in_progress ) return; G_bprint(2, "%s has %s rights!\n", self->netname, redtext("requested admin")); for( p = world; (p = find_client( p )); ) if ( p != self && p->ct == ctPlayer ) G_sprint(p, 2, "Type %s in console to approve\n", redtext("yes")); G_sprint(self, 2, "Type %s to abort election\n", redtext("elect")); // announce the election self->v.elect = 1; self->v.elect_type = etAdmin; electguard = spawn(); // Check the 1 minute timeout for election electguard->s.v.owner = EDICT_TO_PROG( world ); electguard->classname = "electguard"; electguard->think = ( func_t ) ElectThink; electguard->s.v.nextthink = g_globalvars.time + 60; }
void ReqAdmin () { // check for election if( is_elected(self, etAdmin) ) { G_sprint(self, 2, "Abort %sion first\n", redtext("elect")); return; } if( is_adm( self ) ) { G_bprint(2, "%s is no longer an %s\n", self->netname, redtext("admin")); if( self->k_kicking ) ExitKick( self ); self->k_admin = 0; // ok, remove all admin flags on_unadmin( self ); return; } if( self->k_adminc ) { G_sprint(self, 2, "%s code canceled\n", redtext("admin")); self->k_adminc = 0; return; } if( !cvar( "k_admins" ) ) { G_sprint(self, 2, "%s on this server!\n", redtext("NO admins")); return; } if ( VIP_IsFlags( self, VIP_ADMIN ) ) // this VIP does't required pass { BecomeAdmin(self, AF_REAL_ADMIN); return; } // parse /admin <pass> if ( trap_CmdArgc() == 2 ) { char arg_2[1024]; char *pass = cvar_string( "k_admincode" ); int till = Q_rint(self->k_adm_lasttime + 5 - g_globalvars.time); if( self->k_adm_lasttime && till > 0 ) { // probably must help against brute force G_sprint(self, 2, "Wait %d second%s!\n", till, count_s(till) ); return; } trap_CmdArgv( 1, arg_2, sizeof( arg_2 ) ); if ( !strnull(pass) && strneq(pass, "none") && streq(arg_2, pass) ) BecomeAdmin(self, AF_REAL_ADMIN); else { G_sprint(self, 2, "%s...\n", redtext("Access denied")); self->k_adm_lasttime = g_globalvars.time; } return; } self->k_adminc = 6; self->k_added = 0; // You can now use numbers to enter code G_sprint(self, 2, "Use %s or %s to enter code\n", redtext("numbers"), redtext("impulses") ); }