quake-rerelease-qc/quakec_rogue/runes.qc
2022-04-06 14:43:08 -05:00

242 lines
5.7 KiB
C++

/* Copyright (C) 1996-2022 id Software LLC
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 the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See file, 'COPYING', for details.
*/
// Rogue Runes
// Jan'97 by ZOID <zoid@threewave.com>
// Under contract to id software for Rogue Entertainment
.float rune; // what rune does this guy have?
.float runetime; // last time we told him he's already got a rune
.float rune1_last_noise_time;
.float rune2_last_noise_time;
.float rune3_last_noise_time;
.float rune4_last_regen_time;
float runespawn; // have we spawned runes?
entity rune_spawn_spot; // spawn spot for runes
float ITEM_RUNE1 = 1; // Rune of Earth Magic: Resistance
float ITEM_RUNE2 = 2; // Rune of Black Magic: Strength
float ITEM_RUNE3 = 4; // Rune of Hell Magic: Haste
float ITEM_RUNE4 = 8; // Rune of Edler Magic: Regeneration
//prototypes
void() RuneTouch =
{
if (other.classname != "player" || other.health <= 0)
return;
if (other.rune) {
if (other.runetime < time)
centerprint(other, "$qc_already_have_rune");
other.runetime = time + 5;
return;
}
other.rune = other.rune | self.rune;
sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
if (self.rune & ITEM_RUNE1)
centerprint(other, "$qc_rune_resistance");
else if (self.rune & ITEM_RUNE2)
centerprint(other, "$qc_rune_strength");
else if (self.rune & ITEM_RUNE3)
centerprint(other, "$qc_rune_haste");
else if (self.rune & ITEM_RUNE4)
centerprint(other, "$qc_rune_regeneration");
remove(self);
};
entity() RuneSpawnPoint =
{
while (1) {
rune_spawn_spot = find(rune_spawn_spot, classname,
"info_player_deathmatch");
if (rune_spawn_spot != world)
return rune_spawn_spot;
}
};
void() RuneRespawn =
{
local entity spot;
spot = RuneSpawnPoint();
setorigin(self, spot.origin);
self.velocity_z = 300;
self.velocity_x = -300 + (random() * 600);
self.velocity_y = -300 + (random() * 600);
self.nextthink = time + 120;
};
void(float r, entity spot) SpawnRune =
{
local entity item;
if (spot == world)
spot = RuneSpawnPoint();
item = spawn();
setorigin(item, spot.origin);
item.rune = r;
item.velocity_z = 300;
item.velocity_x = -300 + (random() * 600);
item.velocity_y = -300 + (random() * 600);
item.flags = FL_ITEM;
item.solid = SOLID_TRIGGER;
item.movetype = MOVETYPE_TOSS;
if (r & ITEM_RUNE1)
setmodel (item, "progs/end1.mdl");
else if (r & ITEM_RUNE2)
setmodel (item, "progs/end2.mdl");
else if (r & ITEM_RUNE3)
setmodel (item, "progs/end3.mdl");
else if (r & ITEM_RUNE4)
setmodel (item, "progs/end4.mdl");
setsize (item, '-16 -16 0', '16 16 56');
item.touch = RuneTouch;
item.nextthink = time + 120; // remove after 2 minutes
item.think = RuneRespawn;
};
// self is player
void() DropRune =
{
if (self.rune & ITEM_RUNE1)
SpawnRune(ITEM_RUNE1, self);
if (self.rune & ITEM_RUNE2)
SpawnRune(ITEM_RUNE2, self);
if (self.rune & ITEM_RUNE3)
SpawnRune(ITEM_RUNE3, self);
if (self.rune & ITEM_RUNE4)
SpawnRune(ITEM_RUNE4, self);
self.rune = 0;
};
void() DoSpawnRunes =
{
remove(self);
SpawnRune(ITEM_RUNE1, world);
SpawnRune(ITEM_RUNE2, world);
SpawnRune(ITEM_RUNE3, world);
SpawnRune(ITEM_RUNE4, world);
};
void() SpawnRunes =
{
local entity spawner;
if (!deathmatch || !(cvar("gamecfg") & GAMECFG_ENABLE_RUNES) || runespawn)
return;
runespawn = 1;
spawner = spawn();
spawner.think = DoSpawnRunes;
spawner.nextthink = time + 0.1;
};
float(float damage, entity who) RuneApplyEarth =
{
if (who.rune & ITEM_RUNE1) {
if (who.rune1_last_noise_time < time) {
sound (who, CHAN_ITEM, "runes/end1.wav", 1, ATTN_NORM);
// tune as needed
who.rune1_last_noise_time = time + 1.0;
}
return damage/2;
}
return damage;
};
void(entity who) RuneApplyBlackNoise =
{
if (who.rune & ITEM_RUNE2)
if (who.rune2_last_noise_time < time) {
sound (who, CHAN_ITEM, "runes/end2.wav", 1, ATTN_NORM);
// tune as needed
who.rune2_last_noise_time = time + 1.0;
}
};
float(float damage, entity who) RuneApplyBlack =
{
if (who.rune & ITEM_RUNE2)
return damage*2;
return damage;
};
float(float tvalue, entity who) RuneApplyHell =
{
if (who.rune & ITEM_RUNE3) {
if (who.rune3_last_noise_time < time) {
sound (who, CHAN_ITEM, "runes/end3.wav", 1, ATTN_NORM);
// tune as needed
who.rune3_last_noise_time = time + 1.0;
}
return (tvalue * 2) / 3;
}
return tvalue;
};
void(entity who) RuneApplyElder =
{
if (who.rune & ITEM_RUNE4) {
if (who.rune4_last_regen_time < time && who.health < 100) {
sound (who, CHAN_ITEM, "runes/end4.wav", 1, ATTN_NORM);
who.health = who.health + 5;
if (who.health > 100)
who.health = 100;
who.rune4_last_regen_time = time + 1.0;
}
}
};
float(entity who) RuneHasElder =
{
if (who.rune & ITEM_RUNE4)
return TRUE;
return FALSE;
};
void() RunePrecache =
{
if (cvar("deathmatch"))
if (cvar("gamecfg") & GAMECFG_ENABLE_RUNES) {
precache_model("progs/end1.mdl");
precache_model("progs/end2.mdl");
precache_model("progs/end3.mdl");
precache_model("progs/end4.mdl");
precache_sound("runes/end1.wav");
precache_sound("runes/end2.wav");
precache_sound("runes/end3.wav");
precache_sound("runes/end4.wav");
}
};