mirror of
https://github.com/nzp-team/quakec.git
synced 2024-11-24 21:02:14 +00:00
Server: Revamp Power-Ups to use rotation cycle
This commit is contained in:
parent
de3ae91395
commit
3f328c6cd4
4 changed files with 433 additions and 431 deletions
|
@ -173,7 +173,7 @@ void() Dog_Death =
|
|||
if (rounds == dogRound)
|
||||
{
|
||||
if (!Remaining_Zombies)
|
||||
Spawn_Powerup(self.origin + '0 0 12', 1);
|
||||
Spawn_Powerup(self.origin + '0 0 12', PU_MAXAMMO);
|
||||
}
|
||||
|
||||
float r = random();
|
||||
|
|
|
@ -1134,12 +1134,12 @@ void() Zombie_Death =
|
|||
{
|
||||
if (total_powerup_points >= powerup_score_threshold)
|
||||
{
|
||||
Spawn_Powerup(self.origin, 0);
|
||||
Spawn_Powerup(self.origin + '0 0 13', -1);
|
||||
powerup_activate *= 1.14;
|
||||
powerup_score_threshold = total_powerup_points + powerup_activate;
|
||||
}
|
||||
else if (random () <= 0.02)
|
||||
Spawn_Powerup(self.origin, 0);
|
||||
Spawn_Powerup(self.origin + '0 0 13', -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
server/entities/powerups.qc
|
||||
|
||||
powerup logic
|
||||
Power-Up Spawn and Use Logic
|
||||
|
||||
Copyright (C) 2021 NZ:P Team
|
||||
Copyright (C) 2021-2022 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
|
||||
|
@ -25,78 +25,178 @@
|
|||
|
||||
*/
|
||||
|
||||
.float zombie_drop_id;
|
||||
.float flashtime;
|
||||
.float flash_step;
|
||||
#define MAX_POWERUPS 8
|
||||
|
||||
// the powerup's model
|
||||
string(float type) getPowerupModel =
|
||||
#define PU_NUKE 0
|
||||
#define PU_INSTAKILL 1
|
||||
#define PU_DOUBLEPTS 2
|
||||
#define PU_CARPENTER 3
|
||||
#define PU_MAXAMMO 4
|
||||
|
||||
var struct powerup_struct
|
||||
{
|
||||
switch(type) {
|
||||
case 1: return "models/pu/maxammo!.mdl"; break;
|
||||
case 2: return "models/pu/x2!.mdl"; break;
|
||||
case 3: return "models/pu/instakill!.mdl"; break;
|
||||
case 4: return "models/pu/nuke!.mdl"; break;
|
||||
case 5: return "models/pu/carpenter!.mdl"; break;
|
||||
case 6: return "models/pu/perkbottle!.mdl"; break;
|
||||
default: return ""; break;
|
||||
float id;
|
||||
float occupied;
|
||||
float flash_screen;
|
||||
string model_path;
|
||||
string voiceover_path;
|
||||
void() function;
|
||||
float() requirement_function;
|
||||
} powerup_array[MAX_POWERUPS] = {};
|
||||
|
||||
float powerup_count;
|
||||
float powerup_index;
|
||||
|
||||
.float zombie_drop_id;
|
||||
|
||||
//
|
||||
// PU_AddToStruct(id, model_path, voiceover_path)
|
||||
// Adds the Power-Up and info to the powerup struct
|
||||
//
|
||||
void(float id, float flash_screen, string model_path, string voiceover_path, void() function, float() requirement_function)
|
||||
PU_AddToStruct =
|
||||
{
|
||||
if (id > MAX_POWERUPS - 1)
|
||||
return;
|
||||
|
||||
// Precache Model and VO
|
||||
precache_model(model_path);
|
||||
precache_sound(voiceover_path);
|
||||
|
||||
// Populate the Struct at Index
|
||||
powerup_array[powerup_count].id = id;
|
||||
powerup_array[powerup_count].occupied = true;
|
||||
powerup_array[powerup_count].flash_screen = flash_screen;
|
||||
powerup_array[powerup_count].model_path = model_path;
|
||||
powerup_array[powerup_count].voiceover_path = voiceover_path;
|
||||
powerup_array[powerup_count].function = function;
|
||||
powerup_array[powerup_count].requirement_function = requirement_function;
|
||||
|
||||
// Increment Index
|
||||
powerup_count++;
|
||||
};
|
||||
|
||||
//
|
||||
// PU_PopulateArray()
|
||||
// Generates a Power-Up array with the Fisher-Yates shuffle
|
||||
//
|
||||
void() PU_PopulateArray =
|
||||
{
|
||||
float amount = powerup_count;
|
||||
|
||||
while(amount > 0) {
|
||||
float i = floor(random() * amount);
|
||||
amount -= 1;
|
||||
|
||||
powerup_struct temp;
|
||||
temp = powerup_array[i];
|
||||
powerup_array[i] = powerup_array[amount];
|
||||
powerup_array[amount] = temp;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// the powerup's pick up voice clip
|
||||
string(float type) getPowerupVO =
|
||||
//
|
||||
// PU_GetNextPowerUp()
|
||||
// Returns the next valid Power-Up, and refreshes array if needbe.
|
||||
//
|
||||
float() PU_GetNextPowerUp =
|
||||
{
|
||||
switch(type) {
|
||||
case 1: return "sounds/pu/maxammo.wav"; break;
|
||||
case 2: return "sounds/pu/double_points.wav"; break;
|
||||
case 3: return "sounds/pu/insta_kill.wav"; break;
|
||||
case 4: return "sounds/pu/nuke.wav"; break;
|
||||
case 5: return "sounds/pu/carpenter.wav"; break;
|
||||
default: return ""; break;
|
||||
}
|
||||
float id;
|
||||
float found;
|
||||
id = -1;
|
||||
found = false;
|
||||
|
||||
}
|
||||
|
||||
void() maxammo =
|
||||
{
|
||||
entity tempe, temp;
|
||||
|
||||
tempe = find (world, classname, "player");
|
||||
while (tempe)
|
||||
{
|
||||
if (!tempe.downed)
|
||||
{
|
||||
if (tempe.weapon)
|
||||
{
|
||||
tempe.currentammo = getWeaponAmmo(tempe.weapon);
|
||||
if (!tempe.currentmag)
|
||||
{
|
||||
temp = self;
|
||||
self = tempe;
|
||||
W_Reload(S_BOTH);
|
||||
self = temp;
|
||||
}
|
||||
}
|
||||
if (tempe.secondaryweapon)
|
||||
tempe.secondaryammo = getWeaponAmmo(tempe.secondaryweapon);
|
||||
|
||||
tempe.primary_grenades = 4;
|
||||
|
||||
if (tempe.grenades & 2)
|
||||
tempe.secondary_grenades = 2;
|
||||
while(found == false) {
|
||||
// Refresh the Array if we're at the end
|
||||
if (powerup_index >= MAX_POWERUPS - 1) {
|
||||
PU_PopulateArray();
|
||||
powerup_index = 0;
|
||||
}
|
||||
#ifdef PC
|
||||
ScrollText("MAX AMMO!", tempe);
|
||||
#endif
|
||||
#ifdef PSP
|
||||
nzp_maxammo();
|
||||
#endif
|
||||
|
||||
tempe = find (tempe, classname, "player");
|
||||
// Grab a Power-Up
|
||||
powerup_struct pu = powerup_array[powerup_index];
|
||||
powerup_index++;
|
||||
|
||||
// Found a valid Power-Up
|
||||
if (pu.occupied == true) {
|
||||
// Check if we meet the requirements
|
||||
if (pu.requirement_function() == true) {
|
||||
id = pu.id;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void() nuke_finalize =
|
||||
return id;
|
||||
};
|
||||
|
||||
//
|
||||
// PU_ShouldFlashScreen(id)
|
||||
// Returns flash_screen from Power-Up struct.
|
||||
//
|
||||
float(float id) PU_ShouldFlashScreen =
|
||||
{
|
||||
if (id == -1)
|
||||
return false;
|
||||
|
||||
for(float i = 0; i < MAX_POWERUPS - 1; i++) {
|
||||
if (powerup_array[i].id == id)
|
||||
return powerup_array[i].flash_screen;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
//
|
||||
// PU_ModelPath(id)
|
||||
// Returns model_path from Power-Up struct.
|
||||
//
|
||||
string(float id) PU_ModelPath =
|
||||
{
|
||||
if (id == -1)
|
||||
return "";
|
||||
for(float i = 0; i < MAX_POWERUPS - 1; i++) {
|
||||
if (powerup_array[i].id == id)
|
||||
return powerup_array[i].model_path;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
//
|
||||
// PU_VoiceoverPath(id)
|
||||
// Returns model_path from Power-Up struct.
|
||||
//
|
||||
string(float id) PU_VoiceoverPath =
|
||||
{
|
||||
if (id == -1)
|
||||
return "";
|
||||
|
||||
for(float i = 0; i < MAX_POWERUPS - 1; i++) {
|
||||
if (powerup_array[i].id == id)
|
||||
return powerup_array[i].voiceover_path;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
//
|
||||
// PU_LogicFunction(id)
|
||||
// Returns function() from Power-Up struct.
|
||||
//
|
||||
void(float id) PU_LogicFunction =
|
||||
{
|
||||
if (id == -1)
|
||||
return;
|
||||
|
||||
for(float i = 0; i < MAX_POWERUPS - 1; i++) {
|
||||
if (powerup_array[i].id == id)
|
||||
powerup_array[i].function();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// PU_NukeFinalize
|
||||
// Wrap Nuke stuff up.
|
||||
//
|
||||
void() PU_NukeFinalize =
|
||||
{
|
||||
entity players;
|
||||
|
||||
|
@ -116,9 +216,13 @@ void() nuke_finalize =
|
|||
}
|
||||
|
||||
nuke_powerup_active = false;
|
||||
}
|
||||
};
|
||||
|
||||
void() do_nuke_kill =
|
||||
//
|
||||
// PU_NukeKill()
|
||||
// Kills Targets when Nuke is active.
|
||||
//
|
||||
void() PU_NukeKill =
|
||||
{
|
||||
// back up ourselves
|
||||
entity oldself;
|
||||
|
@ -126,7 +230,7 @@ void() do_nuke_kill =
|
|||
|
||||
// switch to goaldummy, is goaldummy world?
|
||||
if (self.goaldummy == world) {
|
||||
nuke_finalize();
|
||||
PU_NukeFinalize();
|
||||
remove(self);
|
||||
return;
|
||||
} else {
|
||||
|
@ -146,9 +250,14 @@ void() do_nuke_kill =
|
|||
self.goaldummy = findfloat(self.goaldummy, iszomb, 1);
|
||||
|
||||
self.nextthink = (rint((random() * 6) + 1)/10) + time; // random number from 0.1 to 0.7
|
||||
}
|
||||
};
|
||||
|
||||
void() nuke =
|
||||
|
||||
//
|
||||
// PU_Nuke()
|
||||
// Nuke Power-Up Function
|
||||
//
|
||||
void() PU_Nuke =
|
||||
{
|
||||
// if there's already one active, just increment the point multiplier
|
||||
if (nuke_powerup_active == true) {
|
||||
|
@ -166,251 +275,236 @@ void() nuke =
|
|||
nuke_watcher = spawn();
|
||||
nuke_watcher.goaldummy = findfloat(world, iszomb, 1);
|
||||
|
||||
nuke_watcher.think = do_nuke_kill;
|
||||
nuke_watcher.think = PU_NukeKill;
|
||||
nuke_watcher.nextthink = (rint((random() * 6) + 1)/10) + time; // random number from 0.1 to 0.7
|
||||
}
|
||||
};
|
||||
|
||||
void() carpenter =
|
||||
//
|
||||
// PU_InstaKill()
|
||||
// Insta-Kill Power-Up Fuction
|
||||
//
|
||||
void() PU_InstaKill =
|
||||
{
|
||||
local entity oldself;
|
||||
local entity who;
|
||||
oldself = self;
|
||||
instakill_finished = time + 30;
|
||||
other.insta_icon = true;
|
||||
};
|
||||
|
||||
who = find(world,classname,"window");
|
||||
while(who != world)
|
||||
{
|
||||
if(who.health < 6 && who.health != -10)//-10 is for boardless windows
|
||||
{
|
||||
self = who;
|
||||
window_carpenter_1 ();
|
||||
who.health = 6;
|
||||
self = oldself;
|
||||
}
|
||||
|
||||
who = find(who,classname,"window");
|
||||
}
|
||||
|
||||
who = find(world,classname,"player");
|
||||
while(who)
|
||||
{
|
||||
addmoney(who, 200, 1);
|
||||
|
||||
who = find(who,classname,"player");
|
||||
}
|
||||
total_windows_down = 0;
|
||||
}
|
||||
|
||||
void(entity who) give_perkdrop_logic =
|
||||
//
|
||||
// PU_DoublePoints()
|
||||
// Double Points Power-Up Function
|
||||
//
|
||||
void() PU_DoublePoints =
|
||||
{
|
||||
// Return here if we already have all of the Perks
|
||||
if ((who.perks & P_REVIVE) && (who.perks & P_JUG) && (who.perks & P_SPEED) && (who.perks & P_DOUBLE) &&
|
||||
(who.perks & P_FLOP) && (who.perks & P_STAMIN) && (who.perks & P_DEAD) && (who.perks & P_MULE)) {
|
||||
return;
|
||||
}
|
||||
x2_finished = time + 30;
|
||||
other.x2_icon = true;
|
||||
};
|
||||
|
||||
local float perk;
|
||||
perk = 0;
|
||||
|
||||
while(perk == 0) {
|
||||
local float num;
|
||||
num = rint((random() * 7)) + 1;
|
||||
|
||||
switch(num) {
|
||||
case 1:
|
||||
if (!(who.perks & P_JUG)) {
|
||||
perk = 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (!(who.perks & P_DOUBLE)) {
|
||||
perk = 2;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (!(who.perks & P_SPEED)) {
|
||||
perk = 4;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (!(who.perks & P_REVIVE)) {
|
||||
perk = 8;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (!(who.perks & P_FLOP)) {
|
||||
perk = 16;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (!(who.perks & P_STAMIN)) {
|
||||
perk = 32;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (!(who.perks & P_DEAD)) {
|
||||
perk = 64;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (!(who.perks & P_MULE)) {
|
||||
perk = 128;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
who.perks = who.perks | perk;
|
||||
}
|
||||
SetPerk(who, who.perks);
|
||||
}
|
||||
|
||||
void() give_perk =
|
||||
//
|
||||
// PU_Carpenter()
|
||||
// Carpenter Power-Up Function
|
||||
//
|
||||
void() PU_Carpenter =
|
||||
{
|
||||
// Individual Power-Up
|
||||
if (self.style == 1) {
|
||||
give_perkdrop_logic(other);
|
||||
}
|
||||
// OUR Power-Up
|
||||
else {
|
||||
local entity who;
|
||||
who = find(world, classname, "player");
|
||||
entity tempe;
|
||||
entity tempe2;
|
||||
tempe2 = self;
|
||||
|
||||
while(who) {
|
||||
give_perkdrop_logic(who);
|
||||
who = find(who, classname, "player");
|
||||
}
|
||||
}
|
||||
}
|
||||
tempe = find(world, classname, "window");
|
||||
|
||||
|
||||
|
||||
|
||||
void() powerup_flash =
|
||||
{
|
||||
if(self.flash_step == 0)
|
||||
{
|
||||
self.flash_step = 1;
|
||||
self.flashtime = time + 3;
|
||||
self.nextthink = time + 0.6;
|
||||
}
|
||||
else if(self.flash_step == 1)
|
||||
{
|
||||
self.nextthink = time + 0.6;
|
||||
|
||||
if(self.flashtime < time)
|
||||
{
|
||||
self.flash_step = 2;
|
||||
self.nextthink = time + 0.3;
|
||||
self.flashtime = time + 3;
|
||||
// Repair Barricades
|
||||
while(tempe != world) {
|
||||
// Target non-full and board-able Barricades
|
||||
if (tempe.health < 6 && tempe.health != -10) {
|
||||
self = tempe;
|
||||
window_carpenter_1();
|
||||
self.health = 6;
|
||||
self = tempe2;
|
||||
}
|
||||
|
||||
}
|
||||
else if(self.flash_step == 2)
|
||||
{
|
||||
self.nextthink = time + 0.3;
|
||||
|
||||
if(self.flashtime < time)
|
||||
{
|
||||
self.flash_step = 3;
|
||||
self.nextthink = time + 0.15;
|
||||
self.flashtime = time + 3;
|
||||
}
|
||||
|
||||
}
|
||||
else if(self.flash_step == 3)
|
||||
{
|
||||
self.nextthink = time + 0.15;
|
||||
if(self.flashtime < time)
|
||||
{
|
||||
// moto - we used to setmodel blank here too, but it caused errors with the sprite.
|
||||
remove(self.owner);
|
||||
remove(self);
|
||||
return;
|
||||
}
|
||||
tempe = find(tempe, classname, "window");
|
||||
}
|
||||
|
||||
if(self.model == "") {
|
||||
setmodel(self, getPowerupModel(self.zombie_drop_id));
|
||||
} else {
|
||||
setmodel(self,"");
|
||||
tempe = find(world, classname, "player");
|
||||
|
||||
// Reward Players with Points
|
||||
while(tempe) {
|
||||
addmoney(tempe, 200, 1);
|
||||
|
||||
tempe = find(tempe, classname, "player");
|
||||
}
|
||||
};
|
||||
|
||||
void() powerup_play_sound =
|
||||
//
|
||||
// PU_CarpenterRequirement()
|
||||
// Requirements for Carpenter Power-Up.
|
||||
//
|
||||
float() PU_CarpenterRequirement =
|
||||
{
|
||||
// play the VO clip if its not the perk bottle
|
||||
if (self.zombie_drop_id != 6)
|
||||
sound(self, CHAN_VOICE, self.powerup_vo, 1, ATTN_NONE);
|
||||
|
||||
// finally, remove the (invisible/inactive) powerup.
|
||||
remove(self);
|
||||
if (total_windows_down >= 5)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void() powerup_touch =
|
||||
//
|
||||
// PU_MaxAmmo()
|
||||
// Max Ammo Power-Up Function
|
||||
//
|
||||
void() PU_MaxAmmo =
|
||||
{
|
||||
local float t;
|
||||
entity tempe;
|
||||
|
||||
t = random();
|
||||
tempe = find(world, classname, "player");
|
||||
|
||||
if(other.classname == "player")
|
||||
while(tempe) {
|
||||
// Fill Primary Weapon
|
||||
if (tempe.weapon) tempe.currentammo = getWeaponAmmo(tempe.weapon);
|
||||
// Fill Secondary Weapon
|
||||
if (tempe.secondaryweapon) tempe.secondaryammo = getWeaponAmmo(tempe.secondaryweapon);
|
||||
// Fill Third Weapon
|
||||
if (tempe.thirdweapon) tempe.thirdammo = getWeaponAmmo(tempe.thirdweapon);
|
||||
// Give Grenades
|
||||
tempe.primary_grenades = 4;
|
||||
// Give Betties
|
||||
if (tempe.grenades & 2) tempe.secondary_grenades = 2;
|
||||
|
||||
// MAX AMMO! text
|
||||
#ifdef PC
|
||||
ScrollText("MAX AMMO!", tempe);
|
||||
#endif
|
||||
#ifdef PSP
|
||||
nzp_maxammo();
|
||||
#endif
|
||||
tempe = find(tempe, classname, "player");
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// PU_NullRequirement()
|
||||
// Power-Up has no requirements. Always return true.
|
||||
//
|
||||
float() PU_NullRequirement =
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
//
|
||||
// PU_Init()
|
||||
// Fill the Power-Up array for the first time and
|
||||
// define used Power-Ups
|
||||
//
|
||||
void() PU_Init =
|
||||
{
|
||||
// Start with 0 Power-Ups accessible
|
||||
powerup_count = 0;
|
||||
|
||||
// Set the Power-Up array IDs to empty
|
||||
for(float i = 0; i < MAX_POWERUPS; i++) {
|
||||
powerup_array[i].id = -1;
|
||||
}
|
||||
|
||||
// Just add all of them for now
|
||||
PU_AddToStruct(PU_NUKE, true, "models/pu/nuke!.mdl", "sounds/pu/nuke.wav", PU_Nuke,
|
||||
PU_NullRequirement );
|
||||
PU_AddToStruct(PU_INSTAKILL, false, "models/pu/instakill!.mdl", "sounds/pu/insta_kill.wav", PU_InstaKill,
|
||||
PU_NullRequirement );
|
||||
PU_AddToStruct(PU_DOUBLEPTS, false, "models/pu/x2!.mdl", "sounds/pu/double_points.wav", PU_DoublePoints,
|
||||
PU_NullRequirement );
|
||||
PU_AddToStruct(PU_CARPENTER, false, "models/pu/carpenter!.mdl", "sounds/pu/carpenter.wav", PU_Carpenter,
|
||||
PU_CarpenterRequirement );
|
||||
PU_AddToStruct(PU_MAXAMMO, false, "models/pu/maxammo!.mdl", "sounds/pu/maxammo.wav", PU_MaxAmmo,
|
||||
PU_NullRequirement );
|
||||
|
||||
// Fill the array
|
||||
PU_PopulateArray();
|
||||
};
|
||||
|
||||
//
|
||||
// PU_Flash()
|
||||
// Flash Power-Up model in and out
|
||||
//
|
||||
void() PU_Flash =
|
||||
{
|
||||
// Toggle the Power-Up model on and off
|
||||
if (self.hitcount % 2) {
|
||||
// Store model
|
||||
if (!self.oldmodel)
|
||||
self.oldmodel = self.model;
|
||||
|
||||
// Disappear
|
||||
setmodel(self, "");
|
||||
}
|
||||
else {
|
||||
// Reappear
|
||||
setmodel(self, self.oldmodel);
|
||||
}
|
||||
|
||||
if (self.hitcount < 15)
|
||||
self.nextthink = time + 0.5;
|
||||
else if (self.hitcount < 25)
|
||||
self.nextthink = time + 0.25;
|
||||
else
|
||||
self.nextthink = time + 0.1;
|
||||
|
||||
self.hitcount++;
|
||||
|
||||
// Too late, delete the Power-Up
|
||||
if (self.hitcount >= 40) {
|
||||
remove(self.owner);
|
||||
remove(self);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// PU_PlayVO()
|
||||
// Play the assigned Voiceover clip before destroying ourself.
|
||||
//
|
||||
void() PU_PlayVO =
|
||||
{
|
||||
sound(self, CHAN_VOICE, self.powerup_vo, 1, ATTN_NONE);
|
||||
remove(self);
|
||||
};
|
||||
|
||||
//
|
||||
// PU_Touch()
|
||||
// Run assigned functions and prep for Deletion
|
||||
//
|
||||
void() PU_Touch =
|
||||
{
|
||||
if (other.classname == "player")
|
||||
{
|
||||
// pickup sound
|
||||
sound(self.owner,CHAN_VOICE,"sounds/pu/pickup.wav",1,ATTN_NONE);
|
||||
// Acquire sound
|
||||
sound(self.owner, CHAN_VOICE, "sounds/pu/pickup.wav", 1, ATTN_NONE);
|
||||
|
||||
// add a slight delay before VO play
|
||||
self.think = powerup_play_sound;
|
||||
// Prepare for VO and destruction
|
||||
self.think = PU_PlayVO;
|
||||
self.nextthink = time + 1;
|
||||
|
||||
// hide powerup until we remove (after sound)
|
||||
// Hide the Power-Up
|
||||
setmodel(self, "");
|
||||
self.effects = 0;
|
||||
Light_None(self);
|
||||
self.touch = SUB_Null;
|
||||
remove(self.owner);
|
||||
|
||||
// slight screen flash
|
||||
stuffcmd(other, "bf\n");
|
||||
// Flash the Screen if permitted
|
||||
if (PU_ShouldFlashScreen(self.walktype) == true)
|
||||
stuffcmd(other, "bf\n");
|
||||
|
||||
// powerup effects
|
||||
switch(self.zombie_drop_id) {
|
||||
// max ammo
|
||||
case 1:
|
||||
maxammo();
|
||||
break;
|
||||
// double points
|
||||
case 2:
|
||||
x2_finished = time + 30;
|
||||
other.x2_icon = true;
|
||||
break;
|
||||
// insta kill
|
||||
case 3:
|
||||
instakill_finished = time + 30;
|
||||
other.insta_icon = true;
|
||||
break;
|
||||
// nuke
|
||||
case 4:
|
||||
nuke();
|
||||
break;
|
||||
// carpenter
|
||||
case 5:
|
||||
carpenter();
|
||||
break;
|
||||
// free perk
|
||||
case 6:
|
||||
give_perk();
|
||||
break;
|
||||
// broken!
|
||||
default:
|
||||
centerprint(other, strcat("INVALID POWER-UP ID: ", ftos(self.zombie_drop_id)));
|
||||
break;
|
||||
}
|
||||
// Run Power-Up function
|
||||
PU_LogicFunction(self.walktype);
|
||||
}
|
||||
};
|
||||
|
||||
void() sparkle_think =
|
||||
//
|
||||
// PU_SparkleThink()
|
||||
// Increment Frames for the Power-Up Sparkle.
|
||||
//
|
||||
void() PU_SparkleThink =
|
||||
{
|
||||
local float f;
|
||||
float f;
|
||||
float r;
|
||||
|
||||
f = self.frame;
|
||||
local float r;
|
||||
|
||||
while(f == self.frame)
|
||||
{
|
||||
r = random();
|
||||
|
@ -419,7 +513,7 @@ void() sparkle_think =
|
|||
}
|
||||
self.frame = f;
|
||||
|
||||
self.think = sparkle_think;
|
||||
self.think = PU_SparkleThink;
|
||||
self.nextthink = time + 0.1;
|
||||
|
||||
if(self.calc_time <= time)
|
||||
|
@ -427,150 +521,65 @@ void() sparkle_think =
|
|||
sound(self,CHAN_VOICE,"sounds/pu/powerup.wav",0.6,ATTN_NORM);
|
||||
self.calc_time = time + 2.998;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// GetPowerupID()
|
||||
// Returns a powerup id, checks if the game allows for
|
||||
// one and if requirements for said powerup are met.
|
||||
// Spawn_Powerup(where, type)
|
||||
// Power-Up spawning function. Use type to force what spawns.
|
||||
//
|
||||
float() GetPowerupID =
|
||||
{
|
||||
float found;
|
||||
float carpenter_able;
|
||||
float perk_able;
|
||||
float id;
|
||||
|
||||
id = carpenter_able = perk_able = 0;
|
||||
|
||||
// Check if we can get a carpenter or a free perk drop
|
||||
if (total_windows_down >= 5)
|
||||
carpenter_able = true;
|
||||
if (rounds >= 15)
|
||||
perk_able = true;
|
||||
|
||||
float total_powerups = 5; // nuke, insta, 2x, maxammo, carpenter, free perk
|
||||
|
||||
// Start ID loop
|
||||
found = false;
|
||||
while(found == false) {
|
||||
float t = random();
|
||||
|
||||
// loop through all IDs
|
||||
for (float i = 0; i < total_powerups + 1; i++) {
|
||||
// check if the ID we got was viable
|
||||
if (t > (i/total_powerups)) {
|
||||
switch(i) {
|
||||
case 1:
|
||||
found = true;
|
||||
id = i;
|
||||
break;
|
||||
case 2:
|
||||
found = true;
|
||||
id = i;
|
||||
break;
|
||||
case 3:
|
||||
found = true;
|
||||
id = i;
|
||||
break;
|
||||
case 4:
|
||||
found = true;
|
||||
id = i;
|
||||
break;
|
||||
case 5:
|
||||
if (carpenter_able) {
|
||||
found = true;
|
||||
id = i;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
/*if (perk_able) {
|
||||
found = true;
|
||||
id = i;
|
||||
}*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
float last_pu;
|
||||
void(vector where, float type) Spawn_Powerup =
|
||||
{
|
||||
entity new_powerup;
|
||||
float id;
|
||||
entity powerup;
|
||||
entity sparkle;
|
||||
|
||||
new_powerup = spawn();
|
||||
new_powerup.origin = where;
|
||||
setorigin(new_powerup, new_powerup.origin);
|
||||
new_powerup.solid = SOLID_TRIGGER;
|
||||
new_powerup.classname = "item_powerup";
|
||||
// Set Up Power-Up
|
||||
powerup = spawn();
|
||||
|
||||
powerup.origin = where;
|
||||
setorigin(powerup, powerup.origin);
|
||||
|
||||
setsize (new_powerup, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
new_powerup.movetype = MOVETYPE_NONE;
|
||||
Light_Green(new_powerup);
|
||||
powerup.solid = SOLID_TRIGGER;
|
||||
powerup.classname = "item_powerup";
|
||||
|
||||
//=================== Sparkle Effects =====================
|
||||
setsize(powerup, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
powerup.movetype = MOVETYPE_NONE;
|
||||
|
||||
entity twlt_Sparkle;
|
||||
twlt_Sparkle = spawn();
|
||||
new_powerup.owner = twlt_Sparkle; //just a reference so power up can delete the sparkle later on
|
||||
Light_Green(powerup);
|
||||
|
||||
// Set Up Sparkle Effect
|
||||
sparkle = spawn();
|
||||
powerup.owner = sparkle;
|
||||
|
||||
sparkle.origin = where;
|
||||
setorigin(sparkle, sparkle.origin);
|
||||
|
||||
setorigin(twlt_Sparkle,where);
|
||||
#ifndef PC
|
||||
setmodel(twlt_Sparkle,"models/sprites/sprkle.spr");
|
||||
setmodel(sparkle,"models/sprites/sprkle.spr");
|
||||
#endif
|
||||
twlt_Sparkle.think = sparkle_think;
|
||||
twlt_Sparkle.nextthink = time + 0.1;
|
||||
sound(twlt_Sparkle,CHAN_VOICE,"sounds/pu/powerup.wav",0.6,ATTN_NORM);
|
||||
|
||||
sound(new_powerup,CHAN_AUTO,"sounds/pu/drop.wav",1,ATTN_NONE);
|
||||
sparkle.think = PU_SparkleThink;
|
||||
sparkle.nextthink = time + 0.1;
|
||||
|
||||
//========================================================
|
||||
// Drop Sounds
|
||||
sound(sparkle, CHAN_VOICE, "sounds/pu/powerup.wav", 0.6, ATTN_NORM);
|
||||
sound(powerup, CHAN_AUTO, "sounds/pu/drop.wav", 1, ATTN_NONE);
|
||||
|
||||
// Specific Power-Ups (for dogs)
|
||||
if (type) {
|
||||
setmodel(new_powerup, getPowerupModel(type));
|
||||
new_powerup.zombie_drop_id = type;
|
||||
new_powerup.powerup_vo = getPowerupVO(type);
|
||||
} else {
|
||||
// Grab a powerup ID
|
||||
id = GetPowerupID();
|
||||
|
||||
// Should perk drops be individual?
|
||||
if (id == 6) {
|
||||
// Yes!
|
||||
if (random() > (1/2)) {
|
||||
// Set Style and make light Blue to symbolize it is an individual drop
|
||||
// TODO: Make a sprite too??
|
||||
new_powerup.style = 1;
|
||||
Light_None(new_powerup);
|
||||
Light_Blue(new_powerup);
|
||||
}
|
||||
// No!
|
||||
else {
|
||||
// failsafe
|
||||
new_powerup.style = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// finally, assign the id and model to our id.
|
||||
setmodel(new_powerup, getPowerupModel(id));
|
||||
new_powerup.zombie_drop_id = id;
|
||||
new_powerup.powerup_vo = getPowerupVO(id);
|
||||
// Check if we were forcefully assigned an ID
|
||||
if (type != -1) {
|
||||
powerup.walktype = type;
|
||||
}
|
||||
// No, so let's grab one from the array.
|
||||
else {
|
||||
powerup.walktype = PU_GetNextPowerUp();
|
||||
}
|
||||
|
||||
last_pu = new_powerup.zombie_drop_id;
|
||||
new_powerup.touch = powerup_touch;
|
||||
// Assign the Power-Up model and sound
|
||||
setmodel(powerup, PU_ModelPath(powerup.walktype));
|
||||
powerup.powerup_vo = PU_VoiceoverPath(powerup.walktype);
|
||||
|
||||
// Finally assign collision function
|
||||
powerup.touch = PU_Touch;
|
||||
|
||||
new_powerup.think = powerup_flash;
|
||||
new_powerup.nextthink = time + 21;
|
||||
totalpowerups++;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
void() LS_Setup;
|
||||
void() PU_Init;
|
||||
void() SUB_Remove = {remove(self);}
|
||||
|
||||
//called when starting server/loading the map
|
||||
|
@ -102,7 +103,6 @@ void() StartFrame =
|
|||
Round_Core();
|
||||
Do_Zombie_AI ();
|
||||
} else {
|
||||
|
||||
entity SpawnedIn;
|
||||
SpawnedIn = find(world, classname, "player");
|
||||
|
||||
|
@ -164,11 +164,6 @@ void() precaches =
|
|||
precache_model ("models/ai/zchead.mdl");
|
||||
|
||||
// powerups
|
||||
precache_model ("models/pu/maxammo!.mdl");
|
||||
precache_model ("models/pu/x2!.mdl");
|
||||
precache_model ("models/pu/instakill!.mdl");
|
||||
precache_model ("models/pu/nuke!.mdl");
|
||||
precache_model ("models/pu/carpenter!.mdl");
|
||||
precache_model ("models/pu/perkbottle!.mdl");
|
||||
|
||||
// start weapons
|
||||
|
@ -227,11 +222,6 @@ void() precaches =
|
|||
|
||||
// power-ups
|
||||
precache_sound ("sounds/pu/pickup.wav");
|
||||
precache_sound ("sounds/pu/carpenter.wav");
|
||||
precache_sound ("sounds/pu/maxammo.wav");
|
||||
precache_sound ("sounds/pu/double_points.wav");
|
||||
precache_sound ("sounds/pu/insta_kill.wav");
|
||||
precache_sound ("sounds/pu/nuke.wav");
|
||||
precache_sound ("sounds/pu/byebye.wav");
|
||||
precache_sound ("sounds/pu/powerup.wav");
|
||||
precache_sound ("sounds/pu/drop.wav");
|
||||
|
@ -310,6 +300,9 @@ void() worldspawn =
|
|||
// Define all of our Light Styles
|
||||
LS_Setup();
|
||||
|
||||
// Init Power-Ups
|
||||
PU_Init();
|
||||
|
||||
#ifdef PC
|
||||
clientstat(STAT_CURRENTMAG, EV_FLOAT, currentmag);
|
||||
clientstat(STAT_CURRENTMAG2, EV_FLOAT, currentmag2);
|
||||
|
|
Loading…
Reference in a new issue