quakec/source/server/rounds.qc

350 lines
7.1 KiB
C++
Raw Normal View History

2022-02-08 18:42:28 +00:00
/*
server/rounds.qc
wave logic
2022-04-06 01:46:24 +00:00
Copyright (C) 2021-2022 NZ:P Team
2022-02-08 18:42:28 +00:00
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
*/
float() spawn_a_dogA;
2022-04-06 01:46:24 +00:00
void() zapper_cooldown;
2022-02-08 18:42:28 +00:00
2022-09-03 00:19:25 +00:00
void() Spawn_Enemy =
2022-02-08 18:42:28 +00:00
{
// 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)
2022-09-03 00:19:25 +00:00
count += rint((0.5 * 6) * multiplier);
2022-02-08 18:42:28 +00:00
else
count += rint(((plrcnt - 1) * 6) * multiplier);
2022-02-08 18:42:28 +00:00
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 =
2022-02-08 18:42:28 +00:00
{
// 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);
2022-02-08 18:42:28 +00:00
}
void() updateDogRound =
{
float r = random();
if (r < 0.33) {
dogRound = rounds + 5;
} else if (r < 0.66) {
dogRound = rounds + 6;
} else {
dogRound = rounds + 7;
}
}
2022-12-29 00:34:30 +00:00
void() PlayerSpawn;
2022-02-08 18:42:28 +00:00
void() EndRound =
{
2022-12-29 00:32:21 +00:00
entity who = find(world,classname,"spectator");
while(who != world)
{
if(who.isspec)
{
self = who;
PlayerSpawn();
}
who = find(who, classname, "spectator");
}
2022-02-08 18:42:28 +00:00
rounds_change = 4;
SetUpdate(self, UT_ROUNDS_CHANGE, rounds_change, 0, 0);
if (gotdog && rounds == dogRound) {
Rounds_PlayTransition("sounds/rounds/droundend.wav");
2022-02-08 18:42:28 +00:00
dogWave = false;
} else {
Rounds_PlayTransition("sounds/rounds/eround.wav");
2022-02-08 18:42:28 +00:00
}
2023-11-03 14:58:01 +00:00
round_changetime = time + 10;
2022-02-08 18:42:28 +00:00
// No Perks? No Problem & Abstinence Program
if (rounds >= 10) {
entity players;
players = find(world, classname, "player");
2022-09-03 00:19:25 +00:00
2022-02-08 18:42:28 +00:00
while(players != world) {
if (players.ach_tracker_npnp == 0) {
GiveAchievement(5, players);
}
if (players.ach_tracker_abst == 0) {
GiveAchievement(8, players);
}
players.ach_tracker_npnp = 0;
players = find(players, classname, "player");
}
}
}
void() NewRound =
2022-09-03 00:19:25 +00:00
{
2022-02-08 18:42:28 +00:00
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");
2022-02-08 18:42:28 +00:00
dogWave = true;
2023-11-21 17:37:06 +00:00
dog_round_count++;
2022-02-08 18:42:28 +00:00
} else {
Rounds_PlayTransition("sounds/rounds/nround.wav");
2022-02-08 18:42:28 +00:00
}
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;
NotifyNewRound(rounds);
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;
2022-02-08 18:42:28 +00:00
tempe = find(tempe, classname, "player");
}
set_z_health();
2022-09-03 00:19:25 +00:00
2022-02-08 18:42:28 +00:00
maxreward = 50 * rounds;
if (maxreward > 500)
maxreward = 500;
totalreward = 0;
Current_Zombies = 0;
spawn_delay = 0;
totalpowerups = 0;
2022-09-03 00:19:25 +00:00
2022-02-08 18:42:28 +00:00
if (rounds == dogRound && gotdog) {
roundtype = 2;
localcmd("fog 200 525 54 55 60\n");
2022-02-08 18:42:28 +00:00
} else {
roundtype = 1;
2022-09-03 00:19:25 +00:00
2022-02-08 18:42:28 +00:00
if (world.fog) {
localcmd(strcat("fog ", world.fog));
} else {
localcmd("fog 0 0 0 0 0\n");
2022-02-08 18:42:28 +00:00
}
}
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);
}
2022-04-06 01:46:24 +00:00
// 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");
}
2022-02-08 18:42:28 +00:00
}
2022-02-08 18:42:28 +00:00
void() Round_Core =
{
if (game_over)
return;
if (round_changetime) {
if (round_changetime <= (time + 2)) {
if (!rounds)
rounds_change = 2;
else
rounds_change = 5;
}
2022-02-08 18:42:28 +00:00
}
if (blink_return && blink_return < time) {
if (rounds_change == 6) {
blink_return = time + 3;
rounds_change = 7;
} else {
blink_return = 0;
rounds_change = 0;
}
2022-02-08 18:42:28 +00:00
}
if (round_changetime < time && round_changetime != 0) {
2022-02-08 18:42:28 +00:00
roundtype = 1;
NewRound();
return;
} else if (round_changetime != 0) return;
if (Total_Zombies > Current_Zombies && spawn_time < time) {
2022-02-08 18:42:28 +00:00
Spawn_Enemy();
}
if (Remaining_Zombies < 1 && !Delay_Time) {
2023-11-03 14:58:01 +00:00
Delay_Time = time + 1;
2022-02-08 18:42:28 +00:00
rounds_change = 3;
} else if (Delay_Time && Delay_Time < time) {
2022-02-08 18:42:28 +00:00
Delay_Time = 0;
EndRound();
}
2022-02-08 18:42:28 +00:00
SetUpdate(self, UT_ROUNDS_CHANGE, rounds_change, 0, 0);
}
void() InitRounds =
2022-09-03 00:19:25 +00:00
{
2022-02-08 18:42:28 +00:00
roundtype = 1;
delay_at_round = 2/0.95;
totalpowerups = 0;
powerup_activate = 2000;
powerup_score_threshold = ((player_count + 1) * G_STARTPOINTS) + powerup_activate;
2022-02-08 18:42:28 +00:00
spawnAllZombEnts();
round_changetime = time + 3.5;
rounds_change = 1;
roundinit = 1;
SetUpdate(self, UT_ROUNDS_CHANGE, rounds_change, 0, 0);
}