mirror of
https://github.com/nzp-team/quakec.git
synced 2024-11-24 21:02:14 +00:00
375 lines
7.7 KiB
C++
375 lines
7.7 KiB
C++
/*
|
|
server/rounds.qc
|
|
|
|
wave logic
|
|
|
|
Copyright (C) 2021-2024 NZ:P Team
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to:
|
|
|
|
Free Software Foundation, Inc.
|
|
59 Temple Place - Suite 330
|
|
Boston, MA 02111-1307, USA
|
|
|
|
*/
|
|
void() SUB_UseTargets;
|
|
float() spawn_a_dogA;
|
|
void() zapper_cooldown;
|
|
|
|
void() Spawn_Enemy =
|
|
{
|
|
// temporarily prevent spawning
|
|
if (nuke_powerup_spawndelay > time)
|
|
return;
|
|
|
|
if (roundtype == 1)
|
|
{
|
|
if (spawn_a_zombieA())
|
|
{
|
|
Current_Zombies = Current_Zombies + 1;
|
|
}
|
|
}
|
|
else if (roundtype == 2)
|
|
{
|
|
if (spawn_a_dogA())
|
|
{
|
|
Current_Zombies = Current_Zombies + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
float(float a, float b) qc_max =
|
|
{
|
|
if (a < b)
|
|
return b;
|
|
return a;
|
|
}
|
|
|
|
float() getZombieTotal = {
|
|
if (roundtype == 1) {
|
|
float count, multiplier, plrcnt;
|
|
count = 24;
|
|
plrcnt = player_count + 1;
|
|
|
|
multiplier = qc_max(rounds/5, 1);
|
|
|
|
if (rounds >= 10)
|
|
multiplier *= rounds * 0.15;
|
|
|
|
if (plrcnt == 1)
|
|
count += rint((0.5 * 6) * multiplier);
|
|
else
|
|
count += rint(((plrcnt - 1) * 6) * multiplier);
|
|
|
|
if (rounds < 2)
|
|
count = floor(count * 0.25);
|
|
else if (rounds < 3)
|
|
count = floor(count * 0.30);
|
|
else if (rounds < 4)
|
|
count = floor(count * 0.50);
|
|
else if (rounds < 5)
|
|
count = floor(count * 0.70);
|
|
else if (rounds < 6)
|
|
count = floor(count * 0.90);
|
|
|
|
return count;
|
|
} else { //dogs
|
|
// 2 waves
|
|
if (rounds <= 14)
|
|
return 6 * (player_count + 1);
|
|
|
|
return 8 * (player_count + 1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Rounds_PlayTransition(sound_path)
|
|
// A nice wrapper for sound() that checks if
|
|
// music is playing and proceeds if not.
|
|
//
|
|
void(string sound_path) Rounds_PlayTransition =
|
|
{
|
|
// Don't play any round stuff while there's a song egg happening.
|
|
if (music_override > time)
|
|
return;
|
|
|
|
// Pick a random player because it needs a source.
|
|
entity some_player = find(world, classname, "player");
|
|
sound(some_player, CHAN_AUTO, sound_path, 1, ATTN_NONE);
|
|
}
|
|
|
|
void() updateDogRound =
|
|
{
|
|
float r = random();
|
|
|
|
if (r < 0.33) {
|
|
dogRound = rounds + 5;
|
|
} else if (r < 0.66) {
|
|
dogRound = rounds + 6;
|
|
} else {
|
|
dogRound = rounds + 7;
|
|
}
|
|
}
|
|
|
|
void() PlayerSpawn;
|
|
|
|
void() EndRound =
|
|
{
|
|
entity who = find(world,classname,"spectator");
|
|
while(who != world)
|
|
{
|
|
if(who.isspec)
|
|
{
|
|
self = who;
|
|
PlayerSpawn();
|
|
}
|
|
who = find(who, classname, "spectator");
|
|
}
|
|
|
|
rounds_change = 4;
|
|
SetUpdate(self, UT_ROUNDS_CHANGE, rounds_change, 0, 0);
|
|
if (gotdog && rounds == dogRound) {
|
|
Rounds_PlayTransition("sounds/rounds/droundend.wav");
|
|
dogWave = false;
|
|
} else {
|
|
Rounds_PlayTransition("sounds/rounds/eround.wav");
|
|
}
|
|
round_changetime = time + 10;
|
|
|
|
// No Perks? No Problem & Abstinence Program
|
|
if (rounds >= 10) {
|
|
entity players;
|
|
players = find(world, classname, "player");
|
|
|
|
while(players != world) {
|
|
if (players.ach_tracker_abst == 0) {
|
|
GiveAchievement(8, players);
|
|
}
|
|
if (rounds >= 16) {
|
|
if (players.ach_tracker_npnp == 0) {
|
|
GiveAchievement(5, players);
|
|
}
|
|
}
|
|
players = find(players, classname, "player");
|
|
}
|
|
}
|
|
|
|
// Fire off all trigger_atroundent ents
|
|
entity triggers = find(world, classname, "trigger_atroundend");
|
|
while(triggers != world) {
|
|
if (triggers.health == rounds) {
|
|
entity oldself = self;
|
|
self = triggers;
|
|
SUB_UseTargets();
|
|
self = oldself;
|
|
}
|
|
triggers = find(triggers, classname, "trigger_atroundend");
|
|
}
|
|
}
|
|
|
|
void() NewRound =
|
|
{
|
|
entity tempe;
|
|
round_changetime = 0;
|
|
spawn_time = time + 5;
|
|
sounds_playing = 0;//just in case it ever somehow glitches
|
|
if (delay_at_round > 0.08)
|
|
{
|
|
delay_at_round = delay_at_round*0.95;
|
|
if (delay_at_round < 0.08)
|
|
delay_at_round = 0.08;
|
|
}
|
|
if (rounds != 0)
|
|
{
|
|
if (gotdog && rounds == (dogRound - 1)) {
|
|
Rounds_PlayTransition("sounds/rounds/droundstart.wav");
|
|
dogWave = true;
|
|
dog_round_count++;
|
|
} else {
|
|
Rounds_PlayTransition("sounds/rounds/nround.wav");
|
|
}
|
|
rounds_change = 6;
|
|
SetUpdate(self, UT_ROUNDS_CHANGE, rounds_change, 0, 0);
|
|
blink_return = time + 2;
|
|
}
|
|
|
|
// if we just had a dog round, set the next
|
|
if (gotdog && rounds == dogRound) {
|
|
updateDogRound();
|
|
}
|
|
|
|
rounds = rounds + 1;
|
|
|
|
#ifdef FTE
|
|
|
|
// FTE-Specific - alert CSQC of the round increment for HUD display
|
|
FTE_IncrementRound(rounds);
|
|
|
|
#endif // FTE
|
|
|
|
tempe = find(world, classname, "player");
|
|
while (tempe)
|
|
{
|
|
if(tempe.grenades & 1)
|
|
{
|
|
tempe.primary_grenades = tempe.primary_grenades + 2;
|
|
if (tempe.primary_grenades > 4)
|
|
tempe.primary_grenades = 4;
|
|
}
|
|
|
|
if(tempe.grenades & 2)
|
|
{
|
|
tempe.secondary_grenades = tempe.secondary_grenades + 2;
|
|
if (tempe.secondary_grenades > 2)
|
|
tempe.secondary_grenades = 2;
|
|
}
|
|
|
|
// Set everyone to full health.
|
|
tempe.health = tempe.max_health;
|
|
|
|
// Reset total repaired barricades for this round
|
|
tempe.barricade_reward = 0;
|
|
|
|
tempe = find(tempe, classname, "player");
|
|
}
|
|
|
|
set_z_health();
|
|
|
|
barricade_reward_maximum = 50 * rounds;
|
|
if (barricade_reward_maximum > 500)
|
|
barricade_reward_maximum = 500;
|
|
|
|
Current_Zombies = 0;
|
|
spawn_delay = 0;
|
|
totalpowerups = 0;
|
|
|
|
if (rounds == dogRound && gotdog) {
|
|
roundtype = 2;
|
|
localcmd("fog 200 525 54 55 60\n");
|
|
} else {
|
|
roundtype = 1;
|
|
|
|
if (world.fog) {
|
|
localcmd(strcat("fog ", world.fog));
|
|
} else {
|
|
localcmd("fog 0 0 0 0 0\n");
|
|
}
|
|
}
|
|
|
|
Remaining_Zombies = Total_Zombies = getZombieTotal();
|
|
|
|
switch(rounds) {
|
|
case 5: GiveAchievement(0); break;
|
|
case 10: GiveAchievement(1); break;
|
|
case 15: GiveAchievement(2); break;
|
|
default: break;
|
|
}
|
|
|
|
// Set up delay for zombie spawning
|
|
local float spawndelay;
|
|
|
|
spawndelay = zombie_spawn_delay;
|
|
|
|
if (spawndelay > 0.08) {
|
|
zombie_spawn_delay *= 0.95;
|
|
} else {
|
|
zombie_spawn_delay = 0.08;
|
|
}
|
|
|
|
// 2 seconds by default
|
|
if (rounds == 1)
|
|
zombie_spawn_delay = 2;
|
|
|
|
// Actually start the timer
|
|
zombie_spawn_timer = 2 + time;
|
|
|
|
if (rounds >= 10 && ach_tracker_spin == 0) {
|
|
GiveAchievement(10);
|
|
}
|
|
|
|
// Refresh Electric Traps
|
|
entity zaps = find(world, classname, "zapper_switch");
|
|
while(zaps != world) {
|
|
if (zaps.mode == 1) {
|
|
zaps.think = zapper_cooldown;
|
|
zaps.nextthink = time + 0.1;
|
|
}
|
|
zaps = find(zaps, classname, "zapper_switch");
|
|
}
|
|
}
|
|
|
|
void() Round_Core =
|
|
{
|
|
if (game_over)
|
|
return;
|
|
|
|
if (round_changetime) {
|
|
if (round_changetime <= (time + 2)) {
|
|
if (!rounds)
|
|
rounds_change = 2;
|
|
else
|
|
rounds_change = 5;
|
|
}
|
|
}
|
|
if (blink_return && blink_return < time) {
|
|
if (rounds_change == 6) {
|
|
blink_return = time + 3;
|
|
rounds_change = 7;
|
|
} else {
|
|
blink_return = 0;
|
|
rounds_change = 0;
|
|
}
|
|
}
|
|
|
|
if (round_changetime < time && round_changetime != 0) {
|
|
roundtype = 1;
|
|
NewRound();
|
|
return;
|
|
} else if (round_changetime != 0) return;
|
|
|
|
if (Total_Zombies > Current_Zombies && spawn_time < time) {
|
|
Spawn_Enemy();
|
|
}
|
|
|
|
if (Remaining_Zombies < 1 && !Delay_Time) {
|
|
Delay_Time = time + 1;
|
|
rounds_change = 3;
|
|
} else if (Delay_Time && Delay_Time < time) {
|
|
Delay_Time = 0;
|
|
EndRound();
|
|
}
|
|
|
|
SetUpdate(self, UT_ROUNDS_CHANGE, rounds_change, 0, 0);
|
|
}
|
|
|
|
void() InitRounds =
|
|
{
|
|
roundtype = 1;
|
|
delay_at_round = 2/0.95;
|
|
totalpowerups = 0;
|
|
powerup_activate = 2000;
|
|
powerup_score_threshold = ((player_count + 1) * G_STARTPOINTS) + powerup_activate;
|
|
|
|
// cypress -- fix Soft_Restart spawning multiple
|
|
// pairs of zombie spawn points.
|
|
if (!roundinit)
|
|
spawnAllZombEnts();
|
|
|
|
round_changetime = time + 3.5;
|
|
rounds_change = 1;
|
|
roundinit = 1;
|
|
SetUpdate(self, UT_ROUNDS_CHANGE, rounds_change, 0, 0);
|
|
}
|