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 spawn_item_flag() { if ( k_ctf_custom_models ) setmodel( self, "progs/flag.mdl" ); self->s.v.noise = "misc/flagtk.wav"; self->s.v.noise1 = "doors/runetry.wav"; setsize( self, -16, -16, 0, 16, 16, 74); self->mdl = self->s.v.model; self->s.v.flags = FL_ITEM; self->s.v.solid = SOLID_TRIGGER; self->s.v.movetype = MOVETYPE_TOSS; SetVector( self->s.v.velocity, 0, 0, 0 ); self->s.v.origin[2] += 6; self->s.v.think = (func_t) FlagThink; self->s.v.touch = (func_t) FlagTouch; self->s.v.nextthink = g_globalvars.time + 0.1; self->cnt = FLAG_AT_BASE; self->cnt2 = 0.0; VectorCopy( self->s.v.angles, self->mangle ); self->s.v.effects = (int) self->s.v.effects | EF_DIMLIGHT; if ( !droptofloor( self ) ) ent_remove( self ); else VectorCopy( self->s.v.origin, self->s.v.oldorigin ); if ( !isCTF() ) { setmodel( self, "" ); self->s.v.touch = (func_t) SUB_Null; } }
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 LoadMap(void) { // Need to do this anyway, otherwise teleporters will be broken CreateItemMarkers(); if (!(isRACE () || isCTF ())) { // If we have a .bot file, use that if (LoadBotRoutingFromFile ()) { map_supported = true; CustomiseFrogbotMap (); AssignVirtualGoals (); AllMarkersLoaded (); return; } } // At this point it's an unsupported map CustomiseFrogbotMap (); if (FrogbotOptionEnabled (FB_OPTION_EDITOR_MODE)) { gedict_t* e; // We don't want spawnpoint markers or powerups to mess with colours for (e = world; (e = nextent (e)); ) { e->s.v.effects = (int)e->s.v.effects & ~(EF_BLUE | EF_GREEN | EF_RED); } AssignGoalNumbers (); } }
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 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 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") ); }
// 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 ) ); }
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 CTF_CheckFlagsAsKeys( void ) { gedict_t *flag1, *flag2; if ( !isCTF() ) return; flag1 = find( world, FOFCLSN, "item_flag_team1" ); // RED flag2 = find( world, FOFCLSN, "item_flag_team2" ); // BLUE if ( !flag1 || !flag2 ) return; // remove keys/flags. self->s.v.items = (int) self->s.v.items & ~(IT_KEY1 | IT_KEY2); // add gold/RED. if ( flag1->cnt != FLAG_AT_BASE ) self->s.v.items = (int) self->s.v.items | IT_KEY2; // add silver/BLUE. if ( flag2->cnt != FLAG_AT_BASE ) self->s.v.items = (int) self->s.v.items | IT_KEY1; }
void PlayerDie() { self->ca_alive = false; DropPowerups(); if ( isCTF() ) { if ( self->hook_out ) { GrappleReset( self->hook ); self->attack_finished = g_globalvars.time + 0.75; self->hook_out = true; // FIXME: for which reason this set to true? } DropRune(); PlayerDropFlag( self, false ); } TeamplayDeathEvent (self); #ifdef BOT_SUPPORT BotPlayerDeathEvent (self); #endif self->s.v.items -= ( int ) self->s.v.items & IT_INVISIBILITY; self->invisible_finished = 0; // don't die as eyes self->invincible_finished = 0; // so we have quad few milleseconds after death // self->super_damage_finished = 0; // moved to prethink, like in ktpro self->radsuit_finished = 0; self->s.v.modelindex = modelindex_player; // don't use eyes DropBackpack(); self->weaponmodel = ""; if (vw_enabled) self->vw_index = 9; // null vwep model SetVector( self->s.v.view_ofs, 0, 0, -8 ); self->s.v.deadflag = DEAD_DYING; self->s.v.solid = SOLID_NOT; self->s.v.flags -= ( ( int ) ( self->s.v.flags ) ) & FL_ONGROUND; self->s.v.movetype = MOVETYPE_TOSS; if ( self->s.v.velocity[2] < 10 ) self->s.v.velocity[2] = self->s.v.velocity[2] + g_random() * 300; if ( self->s.v.health < -40 || dtSQUISH == self->deathtype || dtSUICIDE == self->deathtype || isRA() || isCA() ) { GibPlayer(); // Yawnmode: respawn has the same delay (900ms) regardless of deathtype gib/normal // - Molgrum // Hoonymode: Also force some time, e.g. to prevent instant respawn after /kill which // can cause bug if kill telefrags an idle player (counts as two points...) // only ever happens in testing, but oh well --phil if ( k_yawnmode || isHoonyModeDuel() ) { self->s.v.nextthink = g_globalvars.time + 0.9; self->think = ( func_t ) PlayerDead; return; } PlayerDead(); return; } if( match_in_progress == 2 ) DeathSound(); self->s.v.angles[0] = 0; self->s.v.angles[2] = 0; // function part split and called here StartDie(); }
void CTF_Obituary( gedict_t *targ, gedict_t *attacker ) { qbool carrier_bonus = false; qbool flagdefended = false; gedict_t *head; char *attackerteam; if ( !isCTF() ) return; attackerteam = getteam(attacker); // 2 point bonus for killing enemy flag carrier if ( targ->ctf_flag & CTF_FLAG ) { attacker->ps.c_frags++; attacker->s.v.frags += 2; attacker->ps.ctf_points += 2; attacker->carrier_frag_time = g_globalvars.time; //G_sprint( attacker, 1, "Enemy flag carrier killed: 2 bonus frags\n" ); } // defending carrier from aggressive player if (( targ->carrier_hurt_time + CARRIER_DEFEND_TIME > g_globalvars.time ) && !( attacker->ctf_flag & CTF_FLAG ) ) { carrier_bonus = true; attacker->ps.c_defends++; attacker->s.v.frags += 2; attacker->ps.ctf_points += 2; // Yes, aggressive is spelled wrong.. but dont want to fix now and break stat parsers G_bprint( 2, "%s defends %s's flag carrier against an agressive enemy\n", attacker->s.v.netname, streq( getteam(attacker), "red" ) ? redtext("RED") : redtext("BLUE") ); } head = trap_findradius( world, targ->s.v.origin, 400 ); while ( head ) { if ( head->ct == ctPlayer ) { if ( (head->ctf_flag & CTF_FLAG) && ( head != attacker ) && streq(getteam(head), getteam(attacker)) && !carrier_bonus ) { attacker->ps.c_defends++; attacker->s.v.frags++; attacker->ps.ctf_points++; G_bprint( 2, "%s defends %s's flag carrier\n", attacker->s.v.netname, streq(getteam(attacker), "red") ? redtext("RED") : redtext("BLUE")); } } if ( (streq(getteam(attacker), "red") && streq(head->s.v.classname, "item_flag_team1")) || (streq(getteam(attacker), "blue") && streq(head->s.v.classname, "item_flag_team2")) ) { flagdefended = true; attacker->ps.f_defends++; attacker->s.v.frags += 2; attacker->ps.ctf_points += 2; G_bprint( 2, "%s defends the %s flag\n", attacker->s.v.netname, streq(getteam(attacker), "red") ? redtext("RED") : redtext("BLUE")); } head = trap_findradius( head, targ->s.v.origin, 400 ); } // Defend bonus if attacker is close to flag even if target is not head = trap_findradius( world, attacker->s.v.origin, 400 ); while ( head ) { if ( ( streq(head->s.v.classname, "item_flag_team1") && streq(attackerteam, "red" ) ) || ( streq(head->s.v.classname, "item_flag_team2") && streq(attackerteam, "blue") ) ) { if (!flagdefended) { attacker->ps.f_defends++; attacker->s.v.frags += 2; attacker->ps.ctf_points += 2; G_bprint( 2, "%s defends the %s flag\n", attacker->s.v.netname, streq(attackerteam, "red") ? redtext("RED") : redtext("BLUE")); } } head = trap_findradius( head, attacker->s.v.origin, 400 ); } }
void FlagStatus() { gedict_t *flag1, *flag2; if ( !isCTF() ) return; flag1 = find( world, FOFCLSN, "item_flag_team1" ); flag2 = find( world, FOFCLSN, "item_flag_team2" ); if (!flag1 || !flag2) return; if ( self->ct == ctSpec ) { switch ( (int) flag1->cnt ) { case FLAG_AT_BASE: G_sprint( self, 2, "The %s flag is in base.\n", redtext("RED") ); break; case FLAG_CARRIED: G_sprint( self, 2, "%s has the %s flag.\n", PROG_TO_EDICT( flag1->s.v.owner )->s.v.netname, redtext("RED") ); break; case FLAG_DROPPED: G_sprint( self, 2, "The %s flag is lying about.\n", redtext("RED") ); break; } switch ( (int) flag2->cnt ) { case FLAG_AT_BASE: G_sprint( self, 2, "The %s flag is in base. ", redtext("BLUE") ); break; case FLAG_CARRIED: G_sprint( self, 2, "%s has the %s flag. ", PROG_TO_EDICT( flag1->s.v.owner )->s.v.netname, redtext("BLUE") ); break; case FLAG_DROPPED: G_sprint( self, 2, "The %s flag is lying about. ", redtext("BLUE") ); break; } return; } // Swap flags so that flag1 is "your" flag if ( streq(getteam(self), "blue") ) { gedict_t *swap = flag1; flag1 = flag2; flag2 = swap; } switch ( (int) flag1->cnt ) { case FLAG_AT_BASE: G_sprint( self, 2, "Your flag is in base. " ); break; case FLAG_CARRIED: G_sprint( self, 2, "%s has your flag. ", PROG_TO_EDICT( flag1->s.v.owner )->s.v.netname ); break; case FLAG_DROPPED: G_sprint( self, 2, "Your flag is lying about. " ); break; } switch ( (int) flag2->cnt ) { case FLAG_AT_BASE: G_sprint ( self, 2, "The enemy flag is in their base.\n" ); break; case FLAG_CARRIED: if ( self == PROG_TO_EDICT( flag2->s.v.owner )) G_sprint ( self, 2, "You have the enemy flag.\n" ); else G_sprint ( self, 2, "%s has the enemy flag.\n", PROG_TO_EDICT( flag2->s.v.owner)->s.v.netname ); break; case FLAG_DROPPED: G_sprint ( self, 2, "The enemy flag is lying about.\n" ); break; default: G_sprint ( self, 2, "\n" ); } }