diff --git a/.gitignore b/.gitignore index a78f0f84b..1def19ca8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,8 @@ docs/lqlogos/logomockup-wip2.ora docs/lqlogos/logomockup-wip2.xcf lq1/maps/.bmodelbspbak.7z lq1/config.cfg -lq1/progs.dat +*/progs.dat +*/qwprogs.dat lq1/gfx/pop.png lq-pl.png lq-pl.xcf diff --git a/build.py b/build.py index 0bd8c55b1..83a1b8be9 100644 --- a/build.py +++ b/build.py @@ -177,6 +177,12 @@ def compile_progs(): stderr=subprocess.STDOUT, check=True, # Fail on non-zero exit code ) + subprocess.run( + ["fteqcc", "qcsrc/progs.src", "-D__LIBREQUAKE__", "-D__QW__", "-O3"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + check=True, # Fail on non-zero exit code + ) except subprocess.CalledProcessError as e: print(f"!!! Command failed:\n{e.stdout.decode('utf-8')}") raise e diff --git a/build_components.json b/build_components.json index fc56dc13e..76c390419 100644 --- a/build_components.json +++ b/build_components.json @@ -15,7 +15,6 @@ "docs/misc-docs/COPYING", "docs/misc-docs/LibreProgsDeluxe.md", "docs/misc-docs/pop.lmp.md" - ] }, "root": { @@ -25,11 +24,11 @@ "gfx.wad", "demo1.dem", "demo2.dem", - "demo3.dem" - ], - "files_pak1": [ - "progs.dat" + "demo3.dem", + "progs.dat", + "qwprogs.dat" ], + "files_pak1": [], "files_unpacked": [] }, "config": { diff --git a/qcsrc/ai.qc b/qcsrc/ai.qc index df942ee63..617b226ee 100644 --- a/qcsrc/ai.qc +++ b/qcsrc/ai.qc @@ -61,24 +61,6 @@ walkmove(angle, speed) primitive is all or nothing entity sight_entity; float sight_entity_time; -//pitch (angles_x) is inverted in quake due to a bug - //use makevectors2 for monsters with nonzero pitch -//anyone encountering this comment with a better understanding should update the comment to be more informative and useful to modders --gnounc -void makevectors2(vector ang) = -{ - ang_x *= -1; - makevectors(ang); -}; - -float(float v) anglemod = -{ - while (v >= 360) - v = v - 360; - while (v < 0) - v = v + 360; - return v; -}; - /* ============================================================================== diff --git a/qcsrc/client.qc b/qcsrc/client.qc index b1ab6af52..851deb45f 100644 --- a/qcsrc/client.qc +++ b/qcsrc/client.qc @@ -33,6 +33,8 @@ float modelindex_eyes, modelindex_player; =============================================================================*/ +string nextmap; + float intermission_running; float intermission_exittime; @@ -99,11 +101,12 @@ void() SetNewParms = void() DecodeLevelParms = { - if (serverflags) + if (serverflags && world.model == "maps/start.bsp") { - if (world.model == "maps/start.bsp") - SetNewParms (); // take away all stuff on starting new episode + SetNewParms (); // take away all stuff on starting new episode } + else if (deathmatch) + SetNewParms (); self.items = parm1; self.health = parm2; @@ -161,14 +164,27 @@ entity() FindIntermission = }; -string nextmap; void() GotoNextMap = { + local string newmap; + if (cvar("samelevel")) // if samelevel is set, stay on same level + { changelevel (mapname); - + } else - changelevel (nextmap); + { + +#ifdef __QW__ // NQ does not support infokeys + newmap = infokey(world, mapname); + if (newmap != "") + changelevel (newmap); + else + changelevel (nextmap); +#else + changelevel (nextmap); +#endif + } }; // cypress (09 mar 2024) -- use struct for epilogue levels. @@ -289,10 +305,6 @@ void() execute_changelevel = else intermission_exittime = time + 2; - WriteByte (MSG_ALL, SVC_CDTRACK); - WriteByte (MSG_ALL, 3); - WriteByte (MSG_ALL, 3); - pos = FindIntermission (); other = find (world, classname, "player"); @@ -311,7 +323,23 @@ void() execute_changelevel = other = find (other, classname, "player"); } +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 3); + + WriteByte (MSG_ALL, SVC_INTERMISSION); + WriteCoord (MSG_ALL, pos.origin_x); + WriteCoord (MSG_ALL, pos.origin_y); + WriteCoord (MSG_ALL, pos.origin_z); + WriteAngle (MSG_ALL, pos.mangle_x); + WriteAngle (MSG_ALL, pos.mangle_y); + WriteAngle (MSG_ALL, pos.mangle_z); +#else + WriteByte (MSG_ALL, SVC_CDTRACK); + WriteByte (MSG_ALL, 3); + WriteByte (MSG_ALL, 3); WriteByte (MSG_ALL, SVC_INTERMISSION); +#endif }; @@ -320,15 +348,26 @@ void() changelevel_touch = if (other.classname != "player") return; +#ifdef __QW__ // noexit cvar is not supported in QW + if ((cvar("samelevel") == 2) || ((cvar("samelevel") == 3) && (mapname != "start"))) + { + T_Damage (other, self, self, 50000); + return; + } +#else if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start"))) { T_Damage (other, self, self, 50000); return; } +#endif - bprint (other.netname); - bprint (LOC_CLIENT_DISCON); - bprint ("\n"); + if (deathmatch || coop) + { + bprint (PRINT_HIGH, other.netname); + bprint (PRINT_HIGH, LOC_CLIENT_EXIT_LEVEL); + bprint (PRINT_HIGH, "\n"); + } nextmap = self.map; @@ -393,8 +432,6 @@ void() respawn = { // make a copy of the dead body for appearances sake CopyToBodyQueue (self); - // set default spawn parms - SetNewParms (); // respawn PutClientInServer (); } @@ -415,11 +452,12 @@ Player entered the suicide command */ void() ClientKill = { - bprint (self.netname); - bprint (LOC_DEATH_SUICIDE); - bprint ("\n"); + bprint (PRINT_MEDIUM, self.netname); + bprint (PRINT_MEDIUM, LOC_DEATH_SUICIDE); + bprint (PRINT_MEDIUM, "\n"); set_suicide_frame (); self.modelindex = modelindex_player; + logfrag (self, self); self.frags = self.frags - 2; // extra penalty respawn (); }; @@ -549,6 +587,7 @@ void() PlayerDie; void() PutClientInServer = { local entity spot; + local float axes_only; self.classname = "player"; self.health = 100; @@ -576,7 +615,7 @@ void() PutClientInServer = self.th_die = PlayerDie; self.deadflag = DEAD_NO; - // paustime is set by teleporters to keep the player from moving a while + // pausetime is set by teleporters to keep the player from moving a while self.pausetime = 0; spot = SelectSpawnPoint (); @@ -596,6 +635,8 @@ void() PutClientInServer = self.view_ofs = '0 0 22'; + self.velocity = '0 0 0'; + player_stand1 (); if (deathmatch || coop) @@ -608,10 +649,105 @@ void() PutClientInServer = stuffcmd(self, "-attack\n"); // Supa, prevent shooting after respawning in MP -// centerprint(self, getMapname(mapname)); //gnounc --thought it would be fun. I was at odds about adding an unexpected feature. I may remove it later - //BAM removed it later. --gnounc +#ifdef __QW__ // NQ does not support infokeys + axes_only = stof(infokey(world, "axe")); +#endif + + // Deathmatch 4 starting items + if (deathmatch_supermode()) + { + self.items = self.items - (self.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + IT_ARMOR3; + self.armorvalue = 200; + self.armortype = 0.8; + self.health = 250; + self.items = self.items | IT_INVULNERABILITY; + self.invincible_time = 1; + self.invincible_finished = time + 3; + } + + // Deathmatch 5 starting items + if (deathmatch_supermode2()) + { + self.items = self.items - (self.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + IT_ARMOR3; + self.armorvalue = 200; + self.armortype = 0.8; + self.health = 200; + self.items = self.items | IT_INVULNERABILITY; + self.invincible_time = 1; + self.invincible_finished = time + 3; + } + + if (deathmatch_no_shotgun()) + { + self.items = self.items - (self.items & IT_SHOTGUN); + self.ammo_shells = 0; + } + + if (deathmatch_starting_nailgun()) + { + self.items = self.items | IT_NAILGUN; + self.ammo_nails = 80; + self.weapon = IT_NAILGUN; + } + if (deathmatch_starting_super_shotgun()) + { + self.items = self.items | IT_SUPER_SHOTGUN; + self.ammo_shells = 30; + self.weapon = IT_SUPER_SHOTGUN; + } + if (deathmatch_starting_super_nailgun()) + { + self.items = self.items | IT_SUPER_NAILGUN; + self.ammo_nails = 80; + self.weapon = IT_SUPER_NAILGUN; + } + if (deathmatch_starting_grenade_launcher()) + { + self.items = self.items | IT_GRENADE_LAUNCHER; + self.ammo_rockets = 10; + self.weapon = IT_GRENADE_LAUNCHER; + } + if (deathmatch_starting_lightning_gun()) + { + self.items = self.items | IT_LIGHTNING; + self.ammo_cells = 30; + self.weapon = IT_LIGHTNING; + } + if (deathmatch_starting_rocket_launcher()) + { + self.items = self.items | IT_ROCKET_LAUNCHER; + self.ammo_rockets = 10; + self.weapon = IT_ROCKET_LAUNCHER; + } + if (deathmatch_unlimited_ammo()) + { + self.ammo_nails = 255; + self.ammo_shells = 255; + self.ammo_rockets = 255; + self.ammo_cells = 255; + } + // Axes only + if (deathmatch_axe_only()) + { + self.ammo_nails = 0; + self.ammo_shells = 0; + self.ammo_rockets = 0; + self.ammo_cells = 0; + self.items = self.items - (self.items & ( + IT_SHOTGUN | + IT_SUPER_SHOTGUN | + IT_NAILGUN | + IT_SUPER_NAILGUN | + IT_GRENADE_LAUNCHER | + IT_ROCKET_LAUNCHER | + IT_LIGHTNING + )); + self.weapon = IT_AXE; + } + + W_SetCurrentAmmo (); }; @@ -753,15 +889,9 @@ Exit deathmatch games upon conditions ============*/ void() CheckRules = { - local float timelimit; - local float fraglimit; - if (gameover) // someone else quit the game already return; - timelimit = cvar("timelimit") * 60; - fraglimit = cvar("fraglimit"); - if (timelimit && time >= timelimit) { NextLevel (); @@ -828,6 +958,8 @@ void() PlayerJump = if (self.waterlevel >= 2) { + +#ifndef __QW__ // QW handles this movement code in the engine for client-side prediction if (self.watertype == CONTENT_WATER) self.velocity_z = 100; @@ -836,6 +968,7 @@ void() PlayerJump = else self.velocity_z = 50; +#endif // play swimming sound if (self.swim_flag < time) @@ -860,12 +993,17 @@ void() PlayerJump = self.flags = self.flags - (self.flags & FL_JUMPRELEASED); - self.flags = self.flags - FL_ONGROUND; // don't stairwalk + self.button2 = 0; // player jumping sound sound (self, CHAN_AUTO, "player/plyrjmp8.wav", 1, ATTN_NORM); + +#ifndef __QW__ // QW handles this movement code in the engine for client-side prediction + self.flags = self.flags - FL_ONGROUND; // don't stairwalk self.velocity_z = self.velocity_z + 270; +#endif + }; @@ -963,8 +1101,10 @@ void() WaterMove = self.dmgtime = 0; } +#ifndef __QW__ // QW handles this movement code in the engine for client-side prediction if (! (self.flags & FL_WATERJUMP) ) self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity; +#endif }; void() CheckWaterJump = @@ -1079,8 +1219,8 @@ void() CheckPowerups = { if (self.invisible_time == 1) { - sprint (self, LOC_ITEM_FADE_SHADRING); - sprint (self, "\n"); + sprint (self, PRINT_HIGH, LOC_ITEM_FADE_SHADRING); + sprint (self, PRINT_HIGH, "\n"); stuffcmd (self, "bf\n"); sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM); self.invisible_time = time + 1; @@ -1116,8 +1256,8 @@ void() CheckPowerups = { if (self.invincible_time == 1) { - sprint (self, LOC_ITEM_FADE_PENTPROT); - sprint (self, "\n"); + sprint (self, PRINT_HIGH, LOC_ITEM_FADE_PENTPROT); + sprint (self, PRINT_HIGH, "\n"); stuffcmd (self, "bf\n"); sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM); self.invincible_time = time + 1; @@ -1137,10 +1277,19 @@ void() CheckPowerups = self.invincible_finished = 0; } if (self.invincible_finished > time) + { self.effects = self.effects | EF_DIMLIGHT; - +#ifdef __QW__ // EF_RED is not supported in NQ + self.effects = self.effects | EF_RED; +#endif + } else + { self.effects = self.effects - (self.effects & EF_DIMLIGHT); +#ifdef __QW__ // EF_RED is not supported in NQ + self.effects = self.effects - (self.effects & EF_RED); +#endif + } } // super damage @@ -1152,8 +1301,11 @@ void() CheckPowerups = { if (self.super_time == 1) { - sprint (self, LOC_ITEM_FADE_QUADDMG); - sprint (self, "\n"); + if (deathmatch_supermode()) + sprint (self, PRINT_HIGH, LOC_ITEM_FADE_OCTDMG); + else + sprint (self, PRINT_HIGH, LOC_ITEM_FADE_QUADDMG); + sprint (self, PRINT_HIGH, "\n"); stuffcmd (self, "bf\n"); sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM); self.super_time = time + 1; @@ -1169,14 +1321,31 @@ void() CheckPowerups = if (self.super_damage_finished < time) { // just stopped self.items = self.items - IT_QUAD; + if (deathmatch_supermode()) + { + self.ammo_cells = 255; + self.armorvalue = 1; + self.armortype = 0.8; + self.health = 100; + } self.super_damage_finished = 0; self.super_time = 0; } if (self.super_damage_finished > time) + { self.effects = self.effects | EF_DIMLIGHT; +#ifdef __QW__ // EF_BLUE is not supported in NQ + self.effects = self.effects | EF_BLUE; +#endif + } else + { self.effects = self.effects - (self.effects & EF_DIMLIGHT); +#ifdef __QW__ // EF_BLUE is not supported in NQ + self.effects = self.effects - (self.effects & EF_BLUE); +#endif + } } // suit @@ -1189,8 +1358,8 @@ void() CheckPowerups = { if (self.rad_time == 1) { - sprint (self, LOC_ITEM_FADE_BIOSUIT); - sprint (self, "\n"); + sprint (self, PRINT_HIGH, LOC_ITEM_FADE_BIOSUIT); + sprint (self, PRINT_HIGH, "\n"); stuffcmd (self, "bf\n"); sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM); self.rad_time = time + 1; @@ -1227,8 +1396,6 @@ void() PlayerPostThink = if (self.deadflag) return; - W_WeaponFrame (); // do weapon stuff - // check to see if player landed and play landing sound if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) && (self.health > 0)) { @@ -1248,10 +1415,16 @@ void() PlayerPostThink = self.jump_flag = 0; } +#ifdef __QW__ // Honestly not sure why this branch is necessary. Possibly related to movement physics differences. + self.jump_flag = self.velocity_z; +#else if (!(self.flags & FL_ONGROUND)) self.jump_flag = self.velocity_z; +#endif CheckPowerups (); + + W_WeaponFrame (); // do weapon stuff }; @@ -1262,9 +1435,9 @@ called when a player connects to a server ============*/ void() ClientConnect = { - bprint (self.netname); - bprint (LOC_CLIENT_JOIN); - bprint ("\n"); + bprint (PRINT_HIGH, self.netname); + bprint (PRINT_HIGH, LOC_CLIENT_JOIN); + bprint (PRINT_HIGH, "\n"); // a client connecting during an intermission can cause problems if (intermission_running) @@ -1286,11 +1459,11 @@ void() ClientDisconnect = // since they aren't *really* leaving // let everyone else know - bprint (self.netname); - bprint (LOC_CLIENT_DISCON_DM_A); - bprint (ftos(self.frags)); - bprint (LOC_CLIENT_DISCON_DM_B); - bprint ("\n"); + bprint (PRINT_HIGH, self.netname); + bprint (PRINT_HIGH, LOC_CLIENT_DISCON_A); + bprint (PRINT_HIGH, ftos(self.frags)); + bprint (PRINT_HIGH, LOC_CLIENT_DISCON_B); + bprint (PRINT_HIGH, "\n"); sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE); set_suicide_frame (); }; @@ -1302,48 +1475,68 @@ called when a player dies ============*/ void(entity targ, entity attacker) ClientObituary = { - local float rnum; + local float rnum; + local float attacker_weapon; -#ifdef __LIBREQUAKE__ - - local float rnum2; + local string deathstring, deathstring2; -#endif // __LIBREQUAKE__ + local float on_team; - local string deathstring, deathstring2; - deathstring = deathstring2 = string_null; - // From GPL QW source - local float attackerteam, targteam; // gb +#ifdef __QW__ // QW handles teams differently + local string attackerteam, targteam; +#else + local float attackerteam, targteam; +#endif +#ifdef __QW__ // QW handles teams differently + attackerteam = infokey(attacker, "team"); + targteam = infokey(targ, "team"); + on_team = attackerteam != ""; +#else // gb attackerteam = attacker.team; targteam = targ.team; + on_team = attackerteam != 0; +#endif + + deathstring = deathstring2 = string_null; rnum = random(); + if (targ.deathtype == "selfwater") + { + bprint (PRINT_MEDIUM, targ.netname); + bprint (PRINT_MEDIUM, LOC_DEATH_DISCHARGE_SELF); + bprint (PRINT_MEDIUM, "\n"); + targ.frags = targ.frags - 1; + return; + } + if (targ.classname == "player") { - if (attacker.classname == "teledeath") + if (attacker.classname == "teledeath" || attacker.classname == "teledeath3") { - bprint (targ.netname); - bprint (LOC_DEATH_TELEFRAG); - bprint (attacker.owner.netname); - bprint ("\n"); + bprint (PRINT_MEDIUM, targ.netname); + bprint (PRINT_MEDIUM, LOC_DEATH_TELEFRAG); + bprint (PRINT_MEDIUM, attacker.owner.netname); + bprint (PRINT_MEDIUM, "\n"); attacker.owner.frags = attacker.owner.frags + 1; + logfrag (attacker.owner, targ); return; } if (attacker.classname == "teledeath2") { - bprint (LOC_DEATH_DEFLECT_A); - bprint (targ.netname); - bprint (LOC_DEATH_DEFLECT_B); - bprint (attacker.enemy.netname); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_DEFLECT_A); + bprint (PRINT_MEDIUM, targ.netname); + bprint (PRINT_MEDIUM, LOC_DEATH_DEFLECT_B); + bprint (PRINT_MEDIUM, attacker.owner.netname); + bprint (PRINT_MEDIUM, "\n"); - targ.frags = targ.frags - 1; + attacker.owner.frags = attacker.owner.frags + 1; + logfrag (attacker.owner, targ); return; } @@ -1352,53 +1545,95 @@ void(entity targ, entity attacker) ClientObituary = { // Custom death messages for trigger_hurt if (attacker.dmg == 666000) { - bprint(targ.netname); + bprint(PRINT_MEDIUM, targ.netname); #ifdef __LIBREQUAKE__ if (random() < 0.01) - bprint(LOC_DEATH_FALL_2); + bprint(PRINT_MEDIUM, LOC_DEATH_FALL2); else - bprint(LOC_DEATH_FALL_1); + bprint(PRINT_MEDIUM, LOC_DEATH_FALL1); #else - bprint(LOC_DEATH_FALL); + bprint(PRINT_MEDIUM, LOC_DEATH_FALL); #endif // __LIBREQUAKE__ - bprint("\n"); + bprint(PRINT_MEDIUM, "\n"); return; } -#ifdef __LIBREQUAKE__ - if (attacker.dmg == 666001) { - bprint(targ.netname); + bprint(PRINT_MEDIUM, targ.netname); + +#ifdef __LIBREQUAKE__ if (random() < 0.01) - bprint(LOC_DEATH_SPACE_2); + bprint(PRINT_MEDIUM, LOC_DEATH_SPACE2); else - bprint(LOC_DEATH_SPACE_1); + bprint(PRINT_MEDIUM, LOC_DEATH_SPACE1); + +#else + + bprint(PRINT_MEDIUM, LOC_DEATH_FALL); - bprint("\n"); +#endif // __LIBREQUAKE__ + + bprint(PRINT_MEDIUM, "\n"); return; } if (attacker.dmg == 666002) { - bprint(targ.netname); + bprint(PRINT_MEDIUM, targ.netname); + +#ifdef __LIBREQUAKE__ if (random() < 0.01) - bprint(LOC_DEATH_VOID_2); + bprint(PRINT_MEDIUM, LOC_DEATH_VOID2); else - bprint(LOC_DEATH_VOID_1); + bprint(PRINT_MEDIUM, LOC_DEATH_VOID1); - bprint("\n"); - return; - } +#else + + bprint(PRINT_MEDIUM, LOC_DEATH_FALL); #endif // __LIBREQUAKE__ + bprint(PRINT_MEDIUM, "\n"); + return; + } + } + + if (targ.deathtype == "squish") + { + if (teamplay && targteam == attackerteam && on_team && targ != attacker) + { + logfrag (attacker, attacker); + attacker.frags = attacker.frags - 1; + bprint (PRINT_MEDIUM, attacker.netname); + bprint (PRINT_MEDIUM, LOC_TEAMKILL_SQUISH); + bprint (PRINT_MEDIUM, "\n"); + return; + } + else if (attacker.classname == "player" && attacker != targ) + { + bprint (PRINT_MEDIUM, targ.netname); + bprint (PRINT_MEDIUM, LOC_DEATH_SQUISH2); + bprint (PRINT_MEDIUM, attacker.netname); + bprint (PRINT_MEDIUM, "\n"); + logfrag (attacker, targ); + attacker.frags = attacker.frags + 1; + return; + } + else + { + logfrag (targ, targ); + targ.frags = targ.frags - 1; // killed self + bprint (PRINT_MEDIUM, targ.netname); + bprint (PRINT_MEDIUM, " was squished\n"); + return; + } } if (attacker.classname == "player") @@ -1406,64 +1641,41 @@ void(entity targ, entity attacker) ClientObituary = if (targ == attacker) { // killed self + logfrag (attacker, attacker); attacker.frags = attacker.frags - 1; - bprint (targ.netname); - - if (targ.weapon == 64 && targ.waterlevel > 1) + bprint (PRINT_MEDIUM, targ.netname); + + if (targ.deathtype == "grenade") + { + bprint (PRINT_MEDIUM, LOC_DEATH_SELF_GRENADE); + bprint (PRINT_MEDIUM, "\n"); + } + else if (targ.deathtype == "rocket") + { + bprint (PRINT_MEDIUM, LOC_DEATH_SELF_ROCKET); + bprint (PRINT_MEDIUM, "\n"); + } + else if (targ.deathtype == "discharge") { - -#ifdef __LIBREQUAKE__ - if (targ.watertype == CONTENT_SLIME) - bprint (LOC_DEATH_DISCHARGE_SLIME); + bprint (PRINT_MEDIUM, LOC_DEATH_DISCHARGE_SLIME); else if (targ.watertype == CONTENT_LAVA) - bprint (LOC_DEATH_DISCHARGE_LAVA); + bprint (PRINT_MEDIUM, LOC_DEATH_DISCHARGE_LAVA); else + bprint (PRINT_MEDIUM, LOC_DEATH_DISCHARGE_WATER); -#endif // __LIBREQUAKE__ - - bprint (LOC_DEATH_DISCHARGE_WATER); - - bprint ("\n"); + bprint (PRINT_MEDIUM, "\n"); return; } - if (targ.weapon == 16) { - bprint (LOC_DEATH_SELF_GRENADE); - bprint ("\n"); - } - -#ifdef __LIBREQUAKE__ - - else if (targ.weapon == 32) { - bprint (LOC_DEATH_SELF_ROCKET); - bprint ("\n"); - } - else { - bprint (LOC_DEATH_SELF_OTHER); - bprint ("\n"); - } - -#else - - else if (rnum) { - bprint(LOC_DEATH_SUICIDE_WEAPON_1); - bprint ("\n"); - } else { - bprint(LOC_DEATH_SUICIDE_WEAPON_2); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_SELF_OTHER); + bprint (PRINT_MEDIUM, "\n"); } - -#endif // __LIBREQUAKE__ - return; } -#ifdef __LIBREQUAKE__ - - else if ( (teamplay == 2) && (targteam == attackerteam) && - (attackerteam != 0) ) // gb + else if ( (teamplay) && (targteam == attackerteam) && on_team ) // gb { if (rnum < 0.25) deathstring = LOC_TEAMKILL_1; @@ -1477,26 +1689,29 @@ void(entity targ, entity attacker) ClientObituary = else deathstring = LOC_TEAMKILL_4; - bprint (attacker.netname); - bprint (deathstring); - bprint ("\n"); + bprint (PRINT_MEDIUM, attacker.netname); + bprint (PRINT_MEDIUM, deathstring); + bprint (PRINT_MEDIUM, "\n"); attacker.frags = attacker.frags - 1; + //ZOID 12-13-96: killing a teammate logs as suicide + logfrag (attacker, attacker); return; } -#endif // __LIBREQUAKE__ - else { + logfrag (attacker, targ); attacker.frags = attacker.frags + 1; - rnum = attacker.weapon; + attacker_weapon = attacker.weapon; - if (rnum == IT_AXE) + // Axe + if (targ.deathtype == "axe") { + deathstring = LOC_DEATH_AXE_1A; + deathstring2 = LOC_DEATH_AXE_1B; #ifdef __LIBREQUAKE__ - if (attacker.super_damage_finished > 0) { deathstring = LOC_DEATH_AXE_QA; deathstring2 = LOC_DEATH_AXE_QB; @@ -1505,25 +1720,16 @@ void(entity targ, entity attacker) ClientObituary = deathstring = LOC_DEATH_AXE_2A; deathstring2 = LOC_DEATH_AXE_2B; } - else { - deathstring = LOC_DEATH_AXE_1A; - deathstring2 = LOC_DEATH_AXE_1B; - } - -#else - - deathstring = LOC_DEATH_AXE_A; - deathstring2 = LOC_DEATH_AXE_B; - -#endif // __LIBREQUAKE__ - +#endif } - if (rnum == IT_SHOTGUN) + // Shotgun + else if (targ.deathtype == "shotgun") { + deathstring = LOC_DEATH_SHOTGUN_1A; + deathstring2 = LOC_DEATH_SHOTGUN_1B; #ifdef __LIBREQUAKE__ - if (attacker.super_damage_finished > 0) { deathstring = LOC_DEATH_SHOTGUN_QA; deathstring2 = LOC_DEATH_SHOTGUN_QB; @@ -1532,25 +1738,16 @@ void(entity targ, entity attacker) ClientObituary = deathstring = LOC_DEATH_SHOTGUN_2A; deathstring2 = LOC_DEATH_SHOTGUN_2B; } - else { - deathstring = LOC_DEATH_SHOTGUN_1A; - deathstring2 = LOC_DEATH_SHOTGUN_1B; - } - -#else - - deathstring = LOC_DEATH_SHOTGUN_A; - deathstring2 = LOC_DEATH_SHOTGUN_B; - -#endif // __LIBREQUAKE__ - +#endif } - if (rnum == IT_SUPER_SHOTGUN) + // Super Shotgun + else if (targ.deathtype == "supershotgun") { + deathstring = LOC_DEATH_SUPER_SHOTGUN_1A; + deathstring2 = LOC_DEATH_SUPER_SHOTGUN_1B; #ifdef __LIBREQUAKE__ - if (attacker.super_damage_finished > 0) { deathstring = LOC_DEATH_SUPER_SHOTGUN_QA; deathstring2 = LOC_DEATH_SUPER_SHOTGUN_QB; @@ -1559,25 +1756,16 @@ void(entity targ, entity attacker) ClientObituary = deathstring = LOC_DEATH_SUPER_SHOTGUN_2A; deathstring2 = LOC_DEATH_SUPER_SHOTGUN_2B; } - else { - deathstring = LOC_DEATH_SUPER_SHOTGUN_1A; - deathstring2 = LOC_DEATH_SUPER_SHOTGUN_1B; - } - -#else - - deathstring = LOC_DEATH_SUPER_SHOTGUN_A; - deathstring2 = LOC_DEATH_SUPER_SHOTGUN_B; - -#endif // __LIBREQUAKE__ - +#endif } - if (rnum == IT_NAILGUN) + // Nailgun + else if (targ.deathtype == "nail") { + deathstring = LOC_DEATH_NAILGUN_1A; + deathstring2 = LOC_DEATH_NAILGUN_1B; #ifdef __LIBREQUAKE__ - if (attacker.super_damage_finished > 0) { deathstring = LOC_DEATH_NAILGUN_QA; deathstring2 = LOC_DEATH_NAILGUN_QB; @@ -1586,25 +1774,16 @@ void(entity targ, entity attacker) ClientObituary = deathstring = LOC_DEATH_NAILGUN_2A; deathstring2 = LOC_DEATH_NAILGUN_2B; } - else { - deathstring = LOC_DEATH_NAILGUN_1A; - deathstring2 = LOC_DEATH_NAILGUN_1B; - } - -#else - - deathstring = LOC_DEATH_NAILGUN_A; - deathstring2 = LOC_DEATH_NAILGUN_B; - -#endif // __LIBREQUAKE__ - +#endif } - if (rnum == IT_SUPER_NAILGUN) + // Super Nailgun + else if (targ.deathtype == "supernail") { + deathstring = LOC_DEATH_SUPER_NAILGUN_1A; + deathstring2 = LOC_DEATH_SUPER_NAILGUN_1B; #ifdef __LIBREQUAKE__ - if (attacker.super_damage_finished > 0) { deathstring = LOC_DEATH_SUPER_NAILGUN_QA; deathstring2 = LOC_DEATH_SUPER_NAILGUN_QB; @@ -1613,31 +1792,21 @@ void(entity targ, entity attacker) ClientObituary = deathstring = LOC_DEATH_SUPER_NAILGUN_2A; deathstring2 = LOC_DEATH_SUPER_NAILGUN_2B; } - else { - deathstring = LOC_DEATH_SUPER_NAILGUN_1A; - deathstring2 = LOC_DEATH_SUPER_NAILGUN_1B; - } - -#else - - deathstring = LOC_DEATH_SUPER_NAILGUN_A; - deathstring2 = LOC_DEATH_SUPER_NAILGUN_B; - -#endif // __LIBREQUAKE__ - +#endif } - if (rnum == IT_GRENADE_LAUNCHER) + // Grenade Launcher + else if (targ.deathtype == "grenade") { + deathstring = LOC_DEATH_GRENADE_LAUNCHER_1A; + deathstring2 = LOC_DEATH_GRENADE_LAUNCHER_1B; #ifdef __LIBREQUAKE__ - if (attacker.super_damage_finished > 0) { deathstring = LOC_DEATH_GRENADE_LAUNCHER_QA; deathstring2 = LOC_DEATH_GRENADE_LAUNCHER_QB; } - else if (targ.health < -40) - { + else if (targ.health < -40) { deathstring = LOC_DEATH_GRENADE_LAUNCHER_GA; deathstring2 = LOC_DEATH_GRENADE_LAUNCHER_GB; } @@ -1645,91 +1814,71 @@ void(entity targ, entity attacker) ClientObituary = deathstring = LOC_DEATH_GRENADE_LAUNCHER_2A; deathstring2 = LOC_DEATH_GRENADE_LAUNCHER_2B; } - else { - deathstring = LOC_DEATH_GRENADE_LAUNCHER_1A; - deathstring2 = LOC_DEATH_GRENADE_LAUNCHER_1B; - } - #else - if (targ.health < -40) { - deathstring = LOC_DEATH_GRENADE_LAUNCHER_2A; - deathstring2 = LOC_DEATH_GRENADE_LAUNCHER_2B; - } - else { - deathstring = LOC_DEATH_GRENADE_LAUNCHER_1A; - deathstring2 = LOC_DEATH_GRENADE_LAUNCHER_1B; + deathstring = LOC_DEATH_GRENADE_LAUNCHER_GA; + deathstring2 = LOC_DEATH_GRENADE_LAUNCHER_GB; } - -#endif // __LIBREQUAKE__ - +#endif } - if (rnum == IT_ROCKET_LAUNCHER) + // Rocket Launcher + else if (targ.deathtype == "rocket") { + deathstring = LOC_DEATH_ROCKET_LAUNCHER_1A; + deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_1B; #ifdef __LIBREQUAKE__ - if (attacker.super_damage_finished > 0) { - rnum2 = random(); - if (rnum2 < 0.33) { - deathstring = LOC_DEATH_ROCKET_LAUNCHER_Q1A; - deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_Q1B; - } - else if (rnum2 < 0.66) { - deathstring = LOC_DEATH_ROCKET_LAUNCHER_Q2A; - deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_Q2B; - } - else { - deathstring = LOC_DEATH_ROCKET_LAUNCHER_Q3A; - deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_Q3B; - } + deathstring = LOC_DEATH_ROCKET_LAUNCHER_Q1A; + deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_Q1B; } - else if (targ.health < -40) - { + else if (targ.health < -40) { deathstring = LOC_DEATH_ROCKET_LAUNCHER_GA; - deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_GA; + deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_GB; } else if (random() < 0.01) { deathstring = LOC_DEATH_ROCKET_LAUNCHER_2A; deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_2B; } - else { - deathstring = LOC_DEATH_ROCKET_LAUNCHER_1A; - deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_1B; - } - #else - if (targ.health < -40) { - deathstring = LOC_DEATH_ROCKET_LAUNCHER_2A; - deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_2B; - } - else { - deathstring = LOC_DEATH_ROCKET_LAUNCHER_1A; - deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_1B; + if (attacker.super_damage_finished > 0) { + rnum = random(); + if (rnum < 0.3) { + deathstring = LOC_DEATH_ROCKET_LAUNCHER_Q1A; + deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_Q1B; + } + else if (rnum < 0.6) { + deathstring = LOC_DEATH_ROCKET_LAUNCHER_Q2A; + deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_Q2B; + } + else { + // This one flips the order of attacker and target + bprint (PRINT_MEDIUM, attacker.netname); + bprint (PRINT_MEDIUM, LOC_DEATH_ROCKET_LAUNCHER_Q3A); + bprint (PRINT_MEDIUM, targ.netname); + bprint (PRINT_MEDIUM, LOC_DEATH_ROCKET_LAUNCHER_Q3B); + bprint (PRINT_MEDIUM, "\n"); + return; + } + } + else + { + deathstring = LOC_DEATH_ROCKET_LAUNCHER_GA; + deathstring2 = LOC_DEATH_ROCKET_LAUNCHER_GB; + } } - -#endif // __LIBREQUAKE__ - +#endif } - if (rnum == IT_LIGHTNING) - { + // Lightning Gun + else if (targ.deathtype == "lightning") { + deathstring = LOC_DEATH_LIGHTNING_1A; + deathstring2 = LOC_DEATH_LIGHTNING_1B; #ifdef __LIBREQUAKE__ - - if (attacker.waterlevel > 1) { - if (random() < 0.5) { - deathstring = LOC_DEATH_LIGHTNING_D1A; - deathstring2 = LOC_DEATH_LIGHTNING_D1B; - } - else { - deathstring = LOC_DEATH_LIGHTNING_D2A; - deathstring2 = LOC_DEATH_LIGHTNING_D2B; - } - } - else if (attacker.super_damage_finished > 0) { + if (attacker.super_damage_finished > 0) { deathstring = LOC_DEATH_LIGHTNING_QA; deathstring2 = LOC_DEATH_LIGHTNING_QB; } @@ -1737,41 +1886,39 @@ void(entity targ, entity attacker) ClientObituary = deathstring = LOC_DEATH_LIGHTNING_2A; deathstring2 = LOC_DEATH_LIGHTNING_2B; } - else { - deathstring = LOC_DEATH_LIGHTNING_1A; - deathstring2 = LOC_DEATH_LIGHTNING_1B; - } - -#else - - deathstring = LOC_DEATH_LIGHTNING_A; - - if (attacker.waterlevel > 1) - deathstring2 = LOC_DEATH_LIGHTNING_UNDERWATER; - else - deathstring2 = LOC_DEATH_LIGHTNING_ONGROUND; +#endif + } -#endif // __LIBREQUAKE__ + // Lightning Gun Discharge + else if (targ.deathtype == "discharge") { + deathstring = LOC_DEATH_LIGHTNING_DA; + deathstring2 = LOC_DEATH_LIGHTNING_DB; + } + // Unknown Cause + else { + deathstring = LOC_DEATH_KILL; + deathstring2 = LOC_DEATH_KILL; } - bprint (targ.netname); - bprint (deathstring); - bprint (attacker.netname); - bprint (deathstring2); - bprint ("\n"); + bprint (PRINT_MEDIUM, targ.netname); + bprint (PRINT_MEDIUM, deathstring); + bprint (PRINT_MEDIUM, attacker.netname); + bprint (PRINT_MEDIUM, deathstring2); + bprint (PRINT_MEDIUM, "\n"); } return; } else { + logfrag (targ, targ); targ.frags = targ.frags - 1; // killed self - bprint (targ.netname); + bprint (PRINT_MEDIUM, targ.netname); if (attacker.solid == SOLID_BSP && attacker != world) { - bprint (LOC_DEATH_SQUISH); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_SQUISH); + bprint (PRINT_MEDIUM, "\n"); return; } @@ -1782,17 +1929,17 @@ void(entity targ, entity attacker) ClientObituary = #ifdef __LIBREQUAKE__ if (random() < 0.01) - bprint(LOC_DEATH_FALL_2); + bprint(PRINT_MEDIUM, LOC_DEATH_FALL2); else - bprint(LOC_DEATH_FALL_1); + bprint(PRINT_MEDIUM, LOC_DEATH_FALL1); #else - bprint(LOC_DEATH_FALL); + bprint(PRINT_MEDIUM, LOC_DEATH_FALL); #endif // __LIBREQUAKE__ - bprint("\n"); + bprint(PRINT_MEDIUM, "\n"); return; } @@ -1800,45 +1947,26 @@ void(entity targ, entity attacker) ClientObituary = { rnum = random(); -#ifdef __LIBREQUAKE__ - - if (rnum < 0.33) { - bprint (LOC_DEATH_DROWN1); - bprint ("\n"); - } - else if (rnum < 0.66) { - bprint (LOC_DEATH_DROWN2); - bprint ("\n"); - } - else { - bprint (LOC_DEATH_DROWN3); - bprint ("\n"); - } - -#else - if (rnum < 0.5) { - bprint (LOC_DEATH_DROWN1); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_DROWN1); + bprint (PRINT_MEDIUM, "\n"); } else { - bprint (LOC_DEATH_DROWN2); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_DROWN2); + bprint (PRINT_MEDIUM, "\n"); } -#endif // __LIBREQUAKE__ - return; } if (targ.deathtype == "slime") { if (random() < 0.5) { - bprint (LOC_DEATH_SLIME1); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_SLIME1); + bprint (PRINT_MEDIUM, "\n"); } else { - bprint (LOC_DEATH_SLIME2); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_SLIME2); + bprint (PRINT_MEDIUM, "\n"); } return; } @@ -1847,18 +1975,18 @@ void(entity targ, entity attacker) ClientObituary = { if (targ.health < -15) { - bprint (LOC_DEATH_LAVA3); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_LAVA3); + bprint (PRINT_MEDIUM, "\n"); return; } if (random() < 0.5) { - bprint (LOC_DEATH_LAVA1); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_LAVA1); + bprint (PRINT_MEDIUM, "\n"); } else { - bprint (LOC_DEATH_LAVA2); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_LAVA2); + bprint (PRINT_MEDIUM, "\n"); } return; } @@ -1867,13 +1995,13 @@ void(entity targ, entity attacker) ClientObituary = // yes, a null-check makes sense here //SavageX if(attacker.killstring != string_null) {//gnounc - bprint (attacker.killstring); - bprint ("\n"); // Added since killstrings in LOC don't have \n // ZungryWare + bprint (PRINT_MEDIUM, attacker.killstring); + bprint (PRINT_MEDIUM, "\n"); // Added since killstrings in LOC don't have \n // ZungryWare return; } - bprint (LOC_DEATH_OTHER); - bprint ("\n"); + bprint (PRINT_MEDIUM, LOC_DEATH_OTHER); + bprint (PRINT_MEDIUM, "\n"); } } }; diff --git a/qcsrc/combat.qc b/qcsrc/combat.qc index 28ddead20..9fc3d2f98 100644 --- a/qcsrc/combat.qc +++ b/qcsrc/combat.qc @@ -110,6 +110,7 @@ void(entity targ, entity attacker) Killed = self.takedamage = DAMAGE_NO; self.touch = __NULL__; + self.effects = 0; monster_death_use(); self.th_die (); @@ -130,7 +131,18 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= local entity oldself; local float save; local float take; - local string temp_deathtype; + local string temp_deathtype; + local string s; + local float on_team; + local float rj; + +#ifdef __QW__ // QW handles teams differently + local string attackerteam; + local string targteam; +#else + local float attackerteam; + local float targteam; +#endif if (!targ.takedamage) return; @@ -146,8 +158,11 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= damage_attacker = attacker; // check for quad damage powerup on the attacker - if (attacker.super_damage_finished > time) - damage = damage * 4; + if (attacker.super_damage_finished > time && inflictor.classname != "door") + if (deathmatch_supermode()) + damage = damage * 8; + else + damage = damage * 4; // save damage based on the target's armor level save = ceil(targ.armortype*damage); @@ -172,12 +187,18 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= targ.dmg_inflictor = inflictor; } + damage_inflictor = inflictor; + // figure momentum add if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) ) { dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5; dir = normalize(dir); targ.velocity = targ.velocity + dir*damage*8; + + rj = deathmatch_rocket_jump_multiplier(); + if ( (rj > 1) & ((attacker.classname == "player") & (targ.classname == "player")) & ( attacker.netname == targ.netname)) + targ.velocity = targ.velocity + dir * damage * rj; } // check for godmode or invincibility @@ -196,9 +217,27 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= } // team play damage avoidance - if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) ) +#ifdef __QW__ // QW handles teams differently + attackerteam = infokey(attacker, "team"); + targteam = infokey(targ, "team"); + on_team = attackerteam != ""; +#else + attackerteam = attacker.team; + targteam = targ.team; + on_team = attackerteam != 0; +#endif + + if ((teamplay == 1) && (targteam == attackerteam) && + (attacker.classname == "player") && on_team && + inflictor.classname !="door") + return; + + if ((teamplay == 3) && (targteam == attackerteam) && + (attacker.classname == "player") && on_team && + (targ != attacker) && inflictor.classname !="door") return; + // do the damage targ.health = targ.health - take; @@ -243,7 +282,7 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= /*============ T_RadiusDamage ============*/ -void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage = +void(entity inflictor, entity attacker, float damage, entity ignore, string dtype) T_RadiusDamage = { local float points; local entity head; @@ -271,11 +310,11 @@ void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDam if (points > 0) { if (CanDamage (head, inflictor)) - { // shambler takes half damage from all explosions - + { + head.deathtype = dtype; + // shambler takes half damage from all explosions if (head.classname == "monster_shambler") T_Damage (head, inflictor, attacker, points*0.5); - else T_Damage (head, inflictor, attacker, points); } diff --git a/qcsrc/deathmatch_settings.qc b/qcsrc/deathmatch_settings.qc new file mode 100644 index 000000000..8a792f654 --- /dev/null +++ b/qcsrc/deathmatch_settings.qc @@ -0,0 +1,506 @@ +// +// deathmatch_settings.qc -- Centralized location for defining which deathmatch +// settings are in which modes +// + +// Weapons stay when picked up +#define deathmatch_weapon_stay() \ + (deathmatch >= 2) + +// Items respawn after a timer +#define deathmatch_item_respawn() \ + (deathmatch && (deathmatch != 2)) + +// Ammo pickups take twice as long to respawn +#define deathmatch_slow_ammo() \ + (deathmatch == 1) + +// When picking up a backpack that contains a Rocket or Grenade Launcher, set the +// player's rocket count to 5 if they have less than 5 +#define deathmatch_backpack_min_rockets() \ + (deathmatch >= 3) + +// All of the special rules that apply in deathmatch 4 +#define deathmatch_supermode() \ + (deathmatch == 4) + +// All of the special rules that apply in deathmatch 5 +#define deathmatch_supermode2() \ + (deathmatch == 5) + +// Increases the axe's damage from 20 to 75 +float() deathmatch_buffed_axe = +{ + if (deathmatch_supermode() || deathmatch_supermode2()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "buffed_axe")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Restricts players to axes only +float() deathmatch_axe_only = +{ +#ifdef __QW__ // NQ does not support infokeys + // Legacy support for "axe" infokey that only works on deathmatch 4 + if (deathmatch_supermode() && stof(infokey(world, "axe")) != 0) + return TRUE; + + if (deathmatch && stof(infokey(world, "have_axe_only")) != 0) + return TRUE; +#endif + return FALSE; +} + +// Shotgun is removed from players' starting items +float() deathmatch_no_shotgun = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_shotgun")) != 0) + return TRUE; +#endif + return FALSE; +} + +// Super Shotgun is removed from players' starting items +float() deathmatch_no_super_shotgun = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_super_shotgun")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Nailgun is removed from players' starting items +float() deathmatch_no_nailgun = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_nailgun")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Super Nailgun is removed from players' starting items +float() deathmatch_no_super_nailgun = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_super_nailgun")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Grenade Launcher is removed from players' starting items +float() deathmatch_no_grenade_launcher = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_grenade_launcher")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Rocket Launcher is removed from players' starting items +float() deathmatch_no_rocket_launcher = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_rocket_launcher")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Lightning Gun is removed from players' starting items +float() deathmatch_no_lightning_gun = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_lightning_gun")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Players start with the Super Shotgun +float() deathmatch_starting_super_shotgun = +{ + if (deathmatch_no_super_shotgun()) + return FALSE; + + if (deathmatch_supermode() || deathmatch_supermode2()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "have_super_shotgun")) != 0) + return TRUE; +#endif + return FALSE; +} + +// Players start with the Super Nailgun +float() deathmatch_starting_nailgun = +{ + if (deathmatch_no_nailgun()) + return FALSE; + + if (deathmatch_supermode() || deathmatch_supermode2()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "have_nailgun")) != 0) + return TRUE; +#endif + return FALSE; +} + +// Players start with the Super Nailgun +float() deathmatch_starting_super_nailgun = +{ + if (deathmatch_no_super_nailgun()) + return FALSE; + + if (deathmatch_supermode() || deathmatch_supermode2()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "have_super_nailgun")) != 0) + return TRUE; +#endif + return FALSE; +} + +// Players start with the Grenade Launcher +float() deathmatch_starting_grenade_launcher = +{ + if (deathmatch_no_grenade_launcher()) + return FALSE; + + if (deathmatch_supermode2()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "have_grenade_launcher")) != 0) + return TRUE; +#endif + return FALSE; +} + +// Players start with the Rocket Launcher +float() deathmatch_starting_rocket_launcher = +{ + if (deathmatch_no_rocket_launcher()) + return FALSE; + + if (deathmatch_supermode() || deathmatch_supermode2()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "have_rocket_launcher")) != 0) + return TRUE; +#endif + return FALSE; +} + +// Players start with the Lightning Gun +float() deathmatch_starting_lightning_gun = +{ + if (deathmatch_no_lightning_gun()) + return FALSE; + + if (deathmatch_supermode() || deathmatch_supermode2()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "have_lightning_gun")) != 0) + return TRUE; +#endif + return FALSE; +} + +// Players have unlimited ammo +float() deathmatch_unlimited_ammo = +{ + if (deathmatch_supermode()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "have_unlimited_ammo")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Super Shotgun is removed on map load +float() deathmatch_no_super_shotgun_on_map = +{ + if (deathmatch_no_super_shotgun()) + return TRUE; + + if (deathmatch_starting_super_shotgun()) + return TRUE; + + return FALSE; +}; + +// Nailgun is removed from players' starting items +float() deathmatch_no_nailgun_on_map = +{ + if (deathmatch_no_nailgun()) + return TRUE; + + if (deathmatch_starting_nailgun()) + return TRUE; + + return FALSE; +}; + +// Super Nailgun is removed from players' starting items +float() deathmatch_no_super_nailgun_on_map = +{ + if (deathmatch_no_super_nailgun()) + return TRUE; + + if (deathmatch_starting_super_nailgun()) + return TRUE; + + return FALSE; +}; + +// Grenade Launcher is removed from players' starting items +float() deathmatch_no_grenade_launcher_on_map = +{ + if (deathmatch_no_grenade_launcher()) + return TRUE; + + if (deathmatch_starting_grenade_launcher()) + return TRUE; + + return FALSE; +}; + +// Rocket Launcher is removed from players' starting items +float() deathmatch_no_rocket_launcher_on_map = +{ + if (deathmatch_no_rocket_launcher()) + return TRUE; + + if (deathmatch_starting_rocket_launcher()) + return TRUE; + + return FALSE; +}; + +// Lightning Gun is removed from players' starting items +float() deathmatch_no_lightning_gun_on_map = +{ + if (deathmatch_no_lightning_gun()) + return TRUE; + + if (deathmatch_starting_lightning_gun()) + return TRUE; + + return FALSE; +}; + +// Weapons are removed on map load +float() deathmatch_no_weapons_on_map = +{ + if (deathmatch_supermode() || deathmatch_supermode2() || deathmatch_axe_only()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_weapons")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Ammo pickups are removed on map load +float() deathmatch_no_ammo_pickups = +{ + if (deathmatch_unlimited_ammo() || deathmatch_axe_only()) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_ammo")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Shell pickups are removed on map load +float() deathmatch_no_shell_pickups = +{ + if (deathmatch_no_ammo_pickups()) + return TRUE; + + if (deathmatch_no_shotgun() && deathmatch_no_super_shotgun()) + return TRUE; + + if (deathmatch_no_weapons_on_map() && (!deathmatch_starting_super_shotgun())) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_ammo_shells")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Nail pickups are removed on map load +float() deathmatch_no_nail_pickups = +{ + if (deathmatch_no_ammo_pickups()) + return TRUE; + + if (deathmatch_no_nailgun() && deathmatch_no_super_nailgun()) + return TRUE; + + if (deathmatch_no_weapons_on_map() && (!deathmatch_starting_nailgun()) && (!deathmatch_starting_super_nailgun())) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_ammo_nails")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Rocket pickups are removed on map load +float() deathmatch_no_rocket_pickups = +{ + if (deathmatch_no_ammo_pickups()) + return TRUE; + + if (deathmatch_no_grenade_launcher() && deathmatch_no_rocket_launcher()) + return TRUE; + + if (deathmatch_no_weapons_on_map() && (!deathmatch_starting_grenade_launcher()) && (!deathmatch_starting_rocket_launcher())) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_ammo_rockets")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Cell pickups are removed on map load +float() deathmatch_no_cell_pickups = +{ + if (deathmatch_no_ammo_pickups()) + return TRUE; + + if (deathmatch_no_lightning_gun()) + return TRUE; + + if (deathmatch_no_weapons_on_map() && (!deathmatch_starting_lightning_gun())) + return TRUE; + +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_ammo_cells")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Powerups are removed on map load +float() deathmatch_no_powerups = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_powerups")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Armor pickups are removed on map load +float() deathmatch_no_armor = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_armor")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Health pickups are removed on map load +float() deathmatch_no_health = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_health")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Mega-health pickups are removed on map load +float() deathmatch_no_mega_health = +{ +#ifdef __QW__ // NQ does not support infokeys + if (deathmatch && stof(infokey(world, "disable_mega_health")) != 0) + return TRUE; +#endif + + return FALSE; +}; + +// Quad is dropped on death +float() deathmatch_drop_quad = +{ + if (!deathmatch) + return FALSE; + +#ifdef __QW__ // NQ does not support infokeys + return stof(infokey(world,"dq")) != 0; +#else + return TRUE; +#endif +}; + +// Ring is dropped on death +float() deathmatch_drop_ring = +{ + if (!deathmatch) + return FALSE; + +#ifdef __QW__ // NQ does not support infokeys + return stof(infokey(world,"dr")) != 0; +#else + return TRUE; +#endif +}; + +// Multiplier for explosion force from rocket and grenade jumps +float() deathmatch_rocket_jump_multiplier = +{ + if (!deathmatch) + return 0; + +#ifdef __QW__ // NQ does not support infokeys + return stof(infokey(world,"rj")); +#else + return 0; +#endif +}; diff --git a/qcsrc/defs.qc b/qcsrc/defs.qc index 3275afbaf..7dd514faf 100644 --- a/qcsrc/defs.qc +++ b/qcsrc/defs.qc @@ -32,6 +32,12 @@ entity world; float time; float frametime; +#ifdef __QW__ // NQ defines this outside of C-referenced vars +entity newmis; // if this is set, the entity that just + // run created a new missile that should + // be simulated immediately +#endif + float force_retouch; // force all entities to touch triggers // next frame. this is needed because // non-moving things don't normally scan @@ -42,9 +48,11 @@ float force_retouch; // force all entities to touch triggers // to guarantee everything is touched string mapname; +#ifndef __QW__ // QW defines these outside of C-referenced vars float deathmatch; float coop; float teamplay; +#endif float serverflags; // propagated from level to level, used to // keep track of completed episodes @@ -120,6 +128,11 @@ void end_sys_globals; // flag for structure dumping .vector absmin, absmax; // *** origin + mins / maxs .float ltime; // local time for entity + +#ifdef __QW__ // Unused, as far as I can tell, but needed to keep the C struct intact +.float lastruntime; +#endif + .float movetype; .float solid; @@ -129,7 +142,9 @@ void end_sys_globals; // flag for structure dumping .vector angles; .vector avelocity; +#ifndef __QW__ // Differences in engine protocols .vector punchangle; // temp angle adjust from damage or recoil +#endif .string classname; // spawn function .string model; @@ -174,8 +189,10 @@ void end_sys_globals; // flag for structure dumping .float fixangle; .vector v_angle; // view / targeting angle for players -.float idealpitch; // calculated pitch angle for lookup up slopes +#ifndef __QW__ // Unused, as far as I can tell, but needed to keep the C struct intact +.float idealpitch; // calculated pitch angle for lookup up slopes +#endif .string netname; @@ -240,190 +257,254 @@ void end_sys_fields; // flag for structure dumping // constants // -float FALSE = 0; -float TRUE = 1; +#define FALSE 0 +#define TRUE 1 // edict.flags -float FL_FLY = 1; -float FL_SWIM = 2; -float FL_CLIENT = 8; // set for all client edicts -float FL_INWATER = 16; // for enter / leave water splash -float FL_MONSTER = 32; -float FL_GODMODE = 64; // player cheat -float FL_NOTARGET = 128; // player cheat -float FL_ITEM = 256; // extra wide size for bonus items -float FL_ONGROUND = 512; // standing on something -float FL_PARTIALGROUND = 1024; // not all corners are valid -float FL_WATERJUMP = 2048; // player jumping out of water -float FL_JUMPRELEASED = 4096; // for jump debouncing +#define FL_FLY 1 +#define FL_SWIM 2 +#define FL_CLIENT 8 // set for all client edicts +#define FL_INWATER 16 // for enter / leave water splash +#define FL_MONSTER 32 +#define FL_GODMODE 64 // player cheat +#define FL_NOTARGET 128 // player cheat +#define FL_ITEM 256 // extra wide size for bonus items +#define FL_ONGROUND 512 // standing on something +#define FL_PARTIALGROUND 1024 // not all corners are valid +#define FL_WATERJUMP 2048 // player jumping out of water +#define FL_JUMPRELEASED 4096 // for jump debouncing // edict.movetype values -float MOVETYPE_NONE = 0; // never moves -//float MOVETYPE_ANGLENOCLIP = 1; -//float MOVETYPE_ANGLECLIP = 2; -float MOVETYPE_WALK = 3; // players only -float MOVETYPE_STEP = 4; // discrete, not real time unless fall -float MOVETYPE_FLY = 5; -float MOVETYPE_TOSS = 6; // gravity -float MOVETYPE_PUSH = 7; // no clip to world, push and crush -float MOVETYPE_NOCLIP = 8; -float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters -float MOVETYPE_BOUNCE = 10; -float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size +#define MOVETYPE_NONE 0 // never moves +//#define MOVETYPE_ANGLENOCLIP 1 +//#define MOVETYPE_ANGLECLIP 2 +#define MOVETYPE_WALK 3 // players only +#define MOVETYPE_STEP 4 // discrete, not real time unless fall +#define MOVETYPE_FLY 5 +#define MOVETYPE_TOSS 6 // gravity +#define MOVETYPE_PUSH 7 // no clip to world, push and crush +#define MOVETYPE_NOCLIP 8 +#define MOVETYPE_FLYMISSILE 9 // fly with extra size against monsters +#define MOVETYPE_BOUNCE 10 +#define MOVETYPE_BOUNCEMISSILE 11 // bounce with extra size // edict.solid values -float SOLID_NOT = 0; // no interaction with other objects -float SOLID_TRIGGER = 1; // touch on edge, but not blocking -float SOLID_BBOX = 2; // touch on edge, block -float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground -float SOLID_BSP = 4; // bsp clip, touch on edge, block +#define SOLID_NOT 0 // no interaction with other objects +#define SOLID_TRIGGER 1 // touch on edge, but not blocking +#define SOLID_BBOX 2 // touch on edge, block +#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground +#define SOLID_BSP 4 // bsp clip, touch on edge, block // range values -float RANGE_MELEE = 0; -float RANGE_NEAR = 1; -float RANGE_MID = 2; -float RANGE_FAR = 3; +#define RANGE_MELEE 0 +#define RANGE_NEAR 1 +#define RANGE_MID 2 +#define RANGE_FAR 3 // deadflag values -float DEAD_NO = 0; -float DEAD_DYING = 1; -float DEAD_DEAD = 2; -float DEAD_RESPAWNABLE = 3; +#define DEAD_NO 0 +#define DEAD_DYING 1 +#define DEAD_DEAD 2 +#define DEAD_RESPAWNABLE 3 // takedamage values -float DAMAGE_NO = 0; -float DAMAGE_YES = 1; -float DAMAGE_AIM = 2; +#define DAMAGE_NO 0 +#define DAMAGE_YES 1 +#define DAMAGE_AIM 2 // items -float IT_AXE = 4096; -float IT_SHOTGUN = 1; -float IT_SUPER_SHOTGUN = 2; -float IT_NAILGUN = 4; -float IT_SUPER_NAILGUN = 8; -float IT_GRENADE_LAUNCHER = 16; -float IT_ROCKET_LAUNCHER = 32; -float IT_LIGHTNING = 64; -float IT_EXTRA_WEAPON = 128; - -float IT_SHELLS = 256; -float IT_NAILS = 512; -float IT_ROCKETS = 1024; -float IT_CELLS = 2048; - -float IT_ARMOR1 = 8192; -float IT_ARMOR2 = 16384; -float IT_ARMOR3 = 32768; -float IT_SUPERHEALTH = 65536; - -float IT_KEY1 = 131072; -float IT_KEY2 = 262144; - -float IT_INVISIBILITY = 524288; -float IT_INVULNERABILITY = 1048576; -float IT_SUIT = 2097152; -float IT_QUAD = 4194304; +#define IT_AXE 4096 +#define IT_SHOTGUN 1 +#define IT_SUPER_SHOTGUN 2 +#define IT_NAILGUN 4 +#define IT_SUPER_NAILGUN 8 +#define IT_GRENADE_LAUNCHER 16 +#define IT_ROCKET_LAUNCHER 32 +#define IT_LIGHTNING 64 +#define IT_EXTRA_WEAPON 128 + +#define IT_SHELLS 256 +#define IT_NAILS 512 +#define IT_ROCKETS 1024 +#define IT_CELLS 2048 + +#define IT_ARMOR1 8192 +#define IT_ARMOR2 16384 +#define IT_ARMOR3 32768 +#define IT_SUPERHEALTH 65536 + +#define IT_KEY1 131072 +#define IT_KEY2 262144 + +#define IT_INVISIBILITY 524288 +#define IT_INVULNERABILITY 1048576 +#define IT_SUIT 2097152 +#define IT_QUAD 4194304 // point content values -float CONTENT_EMPTY = -1; -float CONTENT_SOLID = -2; -float CONTENT_WATER = -3; -float CONTENT_SLIME = -4; -float CONTENT_LAVA = -5; -float CONTENT_SKY = -6; +#define CONTENT_EMPTY -1 +#define CONTENT_SOLID -2 +#define CONTENT_WATER -3 +#define CONTENT_SLIME -4 +#define CONTENT_LAVA -5 +#define CONTENT_SKY -6 -float STATE_TOP = 0; -float STATE_BOTTOM = 1; -float STATE_UP = 2; -float STATE_DOWN = 3; +#define STATE_TOP 0 +#define STATE_BOTTOM 1 +#define STATE_UP 2 +#define STATE_DOWN 3 -vector VEC_ORIGIN = '0 0 0'; -vector VEC_HULL_MIN = '-16 -16 -24'; -vector VEC_HULL_MAX = '16 16 32'; +#define VEC_ORIGIN '0 0 0' +#define VEC_HULL_MIN '-16 -16 -24' +#define VEC_HULL_MAX '16 16 32' -vector VEC_HULL2_MIN = '-32 -32 -24'; -vector VEC_HULL2_MAX = '32 32 64'; +#define VEC_HULL2_MIN '-32 -32 -24' +#define VEC_HULL2_MAX '32 32 64' // protocol bytes -float SVC_TEMPENTITY = 23; -float SVC_KILLEDMONSTER = 27; -float SVC_FOUNDSECRET = 28; -float SVC_INTERMISSION = 30; -float SVC_FINALE = 31; -float SVC_CDTRACK = 32; -float SVC_SELLSCREEN = 33; -float SVC_CUTSCENE = 34; - - -float TE_SPIKE = 0; -float TE_SUPERSPIKE = 1; -float TE_GUNSHOT = 2; -float TE_EXPLOSION = 3; -float TE_TAREXPLOSION = 4; -float TE_LIGHTNING1 = 5; -float TE_LIGHTNING2 = 6; -float TE_WIZSPIKE = 7; -float TE_KNIGHTSPIKE = 8; -float TE_LIGHTNING3 = 9; -float TE_LAVASPLASH = 10; -float TE_TELEPORT = 11; +#define SVC_TEMPENTITY 23 +#define SVC_KILLEDMONSTER 27 +#define SVC_FOUNDSECRET 28 +#define SVC_INTERMISSION 30 +#define SVC_FINALE 31 +#define SVC_CDTRACK 32 +#define SVC_SELLSCREEN 33 +#ifdef __QW__ // Differences in engine protocols +#define SVC_SMALLKICK 34 +#define SVC_BIGKICK 35 +#define SVC_MUZZLEFLASH 39 +#else +#define SVC_CUTSCENE 34 +#endif + + +#define TE_SPIKE 0 +#define TE_SUPERSPIKE 1 +#define TE_GUNSHOT 2 +#define TE_EXPLOSION 3 +#define TE_TAREXPLOSION 4 +#define TE_LIGHTNING1 5 +#define TE_LIGHTNING2 6 +#define TE_WIZSPIKE 7 +#define TE_KNIGHTSPIKE 8 +#define TE_LIGHTNING3 9 +#define TE_LAVASPLASH 10 +#define TE_TELEPORT 11 +#ifdef __QW__ // Differences in engine protocols +#define TE_BLOOD 12 +#define TE_LIGHTNINGBLOOD 13 +#endif // sound channels // channel 0 never willingly overrides // other channels (1-7) allways override a playing sound on that channel -float CHAN_AUTO = 0; -float CHAN_WEAPON = 1; -float CHAN_VOICE = 2; -float CHAN_ITEM = 3; -float CHAN_BODY = 4; - -float ATTN_NONE = 0; -float ATTN_NORM = 1; -float ATTN_IDLE = 2; -float ATTN_STATIC = 3; +#define CHAN_AUTO 0 +#define CHAN_WEAPON 1 +#define CHAN_VOICE 2 +#define CHAN_ITEM 3 +#define CHAN_BODY 4 +#ifdef __QW__ // NetQuake doesn't support CHAN_NO_PHS_ADD. Set it to 0 so it will have no effect when combined with another channel. +#define CHAN_NO_PHS_ADD 8 +#else +#define CHAN_NO_PHS_ADD 0 +#endif + +#define ATTN_NONE 0 +#define ATTN_NORM 1 +#define ATTN_IDLE 2 +#define ATTN_STATIC 3 // update types -float UPDATE_GENERAL = 0; -float UPDATE_STATIC = 1; -float UPDATE_BINARY = 2; -float UPDATE_TEMP = 3; +#define UPDATE_GENERAL 0 +#define UPDATE_STATIC 1 +#define UPDATE_BINARY 2 +#define UPDATE_TEMP 3 // entity effects -float EF_BRIGHTFIELD = 1; -float EF_MUZZLEFLASH = 2; -float EF_BRIGHTLIGHT = 4; -float EF_DIMLIGHT = 8; - +#ifdef __QW__ // Engines support different entity effects +#define EF_BRIGHTLIGHT 4 +#define EF_DIMLIGHT 8 +#define EF_FLAG1 16 +#define EF_FLAG2 32 +#define EF_BLUE 64 // Blue Globe effect for Quad +#define EF_RED 128 +#else +#define EF_BRIGHTFIELD 1 +#define EF_MUZZLEFLASH 2 +#define EF_BRIGHTLIGHT 4 +#define EF_DIMLIGHT 8 +#endif // messages -float MSG_BROADCAST = 0; // unreliable to all -float MSG_ONE = 1; // reliable to one (msg_entity) -float MSG_ALL = 2; // reliable to all -float MSG_INIT = 3; // write to the init string +#define MSG_BROADCAST 0 // unreliable to all +#define MSG_ONE 1 // reliable to one (msg_entity) +#define MSG_ALL 2 // reliable to all +#define MSG_INIT 3 // write to the init string + +#ifdef __QW__ // Multicast is QW only +#define MSG_MULTICAST 4 // for multicast() call +#endif + + +// message levels +#define PRINT_LOW 0 // pickup messages +#define PRINT_MEDIUM 1 // death messages +#define PRINT_HIGH 2 // critical messages +#define PRINT_CHAT 3 // also goes to chat console + +#ifdef __QW__ // Multicast is QW only +// multicast sets +#define MULTICAST_ALL 0 // every client +#define MULTICAST_PHS 1 // within hearing +#define MULTICAST_PVS 2 // within sight +#define MULTICAST_ALL_R 3 // every client, reliable +#define MULTICAST_PHS_R 4 // within hearing, reliable +#define MULTICAST_PVS_R 5 // within sight, reliable +#endif + +#define AS_STRAIGHT 1 +#define AS_SLIDING 2 +#define AS_MELEE 3 +#define AS_MISSILE 4 //================================================ // // globals // +#ifndef __QW__ // Used for monster code; not needed in QW float movedist; +#endif float gameover; // set when a rule exits string string_null; // null string, nothing should be held here +#ifndef __QW__ // QW defines this inside of C-referenced vars entity newmis; // launch_spike sets this after spawning it +#endif entity activator; // the entity that activated a trigger or brush entity damage_attacker; // set by T_Damage +entity damage_inflictor; float framecount; +// +// cvars checked each frame +// float skill; +float timelimit; +float fraglimit; +#ifdef __QW__ // NQ defines this inside of C-referenced vars +float deathmatch; +float coop; +float teamplay; +#endif //================================================ @@ -465,16 +546,16 @@ float skill; .float search_time; .float attack_state; -float AS_STRAIGHT = 1; -float AS_SLIDING = 2; -float AS_MELEE = 3; -float AS_MISSILE = 4; - // // player only fields // +.float voided; .float walkframe; +// Zoid Additions +.float maxspeed; // Used to set Maxspeed on a player +.float gravity; // Gravity Multiplier (0 to 1.0) + .float attack_finished; .float pain_finished; @@ -572,7 +653,7 @@ float AS_MISSILE = 4; //pitch (angles_x) is inverted in quake due to a bug //use makevectors2 for monsters with nonzero pitch //anyone encountering this comment with a better understanding should update the comment to be more informative and useful to modders --gnounc -void makevectors2(vector ang); +void(vector ang) makevectors2; //=========================================================================== @@ -610,8 +691,17 @@ string(string s) precache_sound = #19; string(string s) precache_model = #20; void(entity client, string s)stuffcmd = #21; entity(vector org, float rad) findradius = #22; -void(string s) bprint = #23; -void(entity client, string s) sprint = #24; + +#ifdef __QW__ // QW supports print levels for console prints. NQ doesn't, so we just have it ignore the print level. +void(float level, string s) bprint = #23; +void(entity client, float level, string s) sprint = #24; +#else +void(string s) bprint_e = #23; +void(entity client, string s) sprint_e = #24; +void(float level, string s) bprint = { bprint_e(s); }; +void(entity client, float level, string s) sprint = { sprint_e(client, s); }; +#endif + void(string s) dprint = #25; string(float f) ftos = #26; string(vector v) vtos = #27; @@ -635,7 +725,11 @@ vector(entity e, float speed) aim = #44; // returns the shooting vector float(string s) cvar = #45; // return cvar.value void(string s) localcmd = #46; // put string into local que entity(entity e) nextent = #47; // for looping through all ents + +#ifndef __QW__ // Differences in engine protocols void(vector o, vector d, float color, float count) particle = #48;// start a particle effect +#endif + void() ChangeYaw = #49; // turn towards self.ideal_yaw // at self.yaw_speed // #50 was removed @@ -690,6 +784,22 @@ void(entity e) setspawnparms = #78; // set parm1... to the // values at level start // for coop respawn +#ifdef __QW__ // logfrag is supported in QW, but not NQ. We just have NQ define it as an empty function. +void(entity killer, entity killee) logfrag = #79; // add to stats +#else +void(entity killer, entity killee) logfrag = {}; // add to stats +#endif + +#ifdef __QW__ // NQ does not support infokeys or stof +string(entity e, string key) infokey = #80; // get a key value (world = serverinfo) +float(string s) stof = #81; // convert string to float +#endif + +#ifdef __QW__ // NQ does not support multicast +void(vector where, float set) multicast = #82; // sends the temp message to a set + // of clients, possibly in PVS or PHS +#endif + //============================================================================ // @@ -698,9 +808,11 @@ void(entity e) setspawnparms = #78; // set parm1... to the void(vector tdest, float tspeed, void() func) SUB_CalcMove; void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt; void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove; -void() SUB_CalcMoveDone; +void() SUB_CalcMoveDone; void() SUB_CalcAngleMoveDone; +void() SUB_Null; void() SUB_UseTargets; +void() SUB_Remove; // // combat.qc diff --git a/qcsrc/doors.qc b/qcsrc/doors.qc index cc64d7832..24e6f555f 100644 --- a/qcsrc/doors.qc +++ b/qcsrc/doors.qc @@ -45,7 +45,8 @@ void() door_go_up; void() door_blocked = { - T_Damage (other, self, self, self.dmg); + other.deathtype = "squish"; + T_Damage (other, self, self.goalentity, self.dmg); // if a door has a negative wait, it would never come back if blocked, // so let it just squash the object to death real fast @@ -62,7 +63,7 @@ void() door_blocked = void() door_hit_top = { - sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM); self.state = STATE_TOP; if (self.spawnflags & DOOR_TOGGLE) @@ -74,7 +75,7 @@ void() door_hit_top = void() door_hit_bottom = { - sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM); self.state = STATE_BOTTOM; }; @@ -154,6 +155,7 @@ void() door_fire = starte = self; do { + self.goalentity = activator; // Who fired us door_go_up (); self = self.enemy; } while ( (self != starte) && (self != world) ); @@ -718,7 +720,7 @@ void () fd_secret_done = self.th_pain = (void(entity attacker, float damage)) fd_secret_use; self.th_die = fd_secret_use;//copypasta'd directly from gpl'd qw source on github. -- secret door kill crash fix } - sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM); + sound(self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise3, 1, ATTN_NORM); }; void () secret_blocked = @@ -727,6 +729,7 @@ void () secret_blocked = return; self.attack_finished = time + 0.5; + other.deathtype = "squish"; T_Damage (other, self, self, self.dmg); }; diff --git a/qcsrc/items.qc b/qcsrc/items.qc index 634c62d57..15ab1ac40 100644 --- a/qcsrc/items.qc +++ b/qcsrc/items.qc @@ -43,6 +43,140 @@ void() noclass = }; +// ================ +// Dropped powerups +// ================ + +void() q_touch = +{ +local entity stemp; +local float best; +local string s; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + self.mdl = self.model; + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | IT_QUAD; + self.model = string_null; + if (deathmatch == 4) + { + other.armortype = 0; + other.armorvalue = 0 * 0.01; + other.ammo_cells = 0; + } + +// do the apropriate action + other.super_time = 1; + other.super_damage_finished = self.cnt; + + s=ftos(rint(other.super_damage_finished - time)); + + bprint (PRINT_LOW, other.netname); + if (deathmatch == 4) + bprint (PRINT_LOW, " recovered an OctaPower with "); + else + bprint (PRINT_LOW, " recovered a Quad with "); + bprint (PRINT_LOW, s); + bprint (PRINT_LOW, " seconds remaining!\n"); + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void(float timeleft) DropQuad = +{ + local entity item; + + item = spawn(); + item.origin = self.origin; + + item.velocity_z = 300; + item.velocity_x = -100 + (random() * 200); + item.velocity_y = -100 + (random() * 200); + + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + item.noise = "items/damage.wav"; + setmodel (item, "progs/quaddama.mdl"); + setsize (item, '-16 -16 -24', '16 16 32'); + item.cnt = time + timeleft; + item.touch = q_touch; + item.nextthink = time + timeleft; // remove it with the time left on it + item.think = SUB_Remove; + +#ifdef __QW__ // EF_BLUE is not supported in NQ + item.effects = EF_BLUE; +#endif +}; + + +void() r_touch; + +void() r_touch = +{ +local entity stemp; +local float best; +local string s; + + if (other.classname != "player") + return; + if (other.health <= 0) + return; + + self.mdl = self.model; + + sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + self.solid = SOLID_NOT; + other.items = other.items | IT_INVISIBILITY; + self.model = string_null; + +// do the apropriate action + other.invisible_time = 1; + other.invisible_finished = self.cnt; + s=ftos(rint(other.invisible_finished - time)); + bprint (PRINT_LOW, other.netname); + bprint (PRINT_LOW, " recovered a Ring with "); + bprint (PRINT_LOW, s); + bprint (PRINT_LOW, " seconds remaining!\n"); + + + activator = other; + SUB_UseTargets(); // fire all targets / killtargets +}; + + +void(float timeleft) DropRing = +{ + local entity item; + + item = spawn(); + item.origin = self.origin; + + item.velocity_z = 300; + item.velocity_x = -100 + (random() * 200); + item.velocity_y = -100 + (random() * 200); + + item.flags = FL_ITEM; + item.solid = SOLID_TRIGGER; + item.movetype = MOVETYPE_TOSS; + item.noise = "items/inv1.wav"; + setmodel (item, "progs/invisibl.mdl"); + setsize (item, '-16 -16 -24', '16 16 32'); + item.cnt = time + timeleft; + item.touch = r_touch; + item.nextthink = time + timeleft; // remove after 30 seconds + item.think = SUB_Remove; +}; /*============ PlaceItem @@ -132,7 +266,8 @@ void() item_megahealth_rot; void() item_health = { - self.touch = health_touch; + if (deathmatch_no_health()) + return; if (self.spawnflags & H_ROTTEN) { @@ -147,6 +282,9 @@ void() item_health = else if (self.spawnflags & H_MEGA) { + if (deathmatch_no_mega_health()) + return; + precache_model("maps/b_bh100.bsp"); precache_sound("items/r_item2.wav"); setmodel(self, "maps/b_bh100.bsp"); @@ -165,6 +303,7 @@ void() item_health = self.healtype = 1; } + self.touch = health_touch; setsize (self, '0 0 0', '32 32 56'); StartItem (); }; @@ -173,6 +312,10 @@ void() health_touch = { local string s; + if (deathmatch_supermode()) + if (other.invincible_time > 0) + return; + if (other.classname != "player") return; @@ -190,11 +333,11 @@ void() health_touch = return; } - sprint(other, LOC_ITEM_PICKUP_HEALTH); + sprint(other, PRINT_LOW, LOC_ITEM_PICKUP_HEALTH); s = ftos(self.healamount); - sprint(other, s); - sprint(other, LOC_ITEM_TYPE_HEALTH); - sprint(other, "\n"); + sprint(other, PRINT_LOW, s); + sprint(other, PRINT_LOW, LOC_ITEM_TYPE_HEALTH); + sprint(other, PRINT_LOW, "\n"); // health touch sound sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM); @@ -205,17 +348,17 @@ void() health_touch = self.solid = SOLID_NOT; // Megahealth = rot down the player's super health - if (self.healtype == 2) + if (self.healtype == 2 && !deathmatch_supermode()) { other.items = other.items | IT_SUPERHEALTH; + self.owner = other; self.nextthink = time + 5; self.think = item_megahealth_rot; - self.owner = other; } else { - if (deathmatch && deathmatch != 2) // deathmatch 2 is the silly old rules + if (deathmatch_item_respawn()) // deathmatch 2 is the silly old rules { self.nextthink = time + 20; self.think = SUB_regen; @@ -242,7 +385,7 @@ void() item_megahealth_rot = // just blindly subtract the flag off other.items = other.items - (other.items & IT_SUPERHEALTH); - if (deathmatch && deathmatch != 2) // deathmatch 2 is silly old rules + if (deathmatch_item_respawn()) // deathmatch 2 is silly old rules { self.nextthink = time + 20; self.think = SUB_regen; @@ -268,6 +411,10 @@ void() armor_touch = if (other.classname != "player") return; + + if (deathmatch_supermode()) + if (other.invincible_time > 0) + return; // cypress (07 feb 2024) -- adopted switch switch(self.classname) { @@ -300,15 +447,15 @@ void() armor_touch = self.solid = SOLID_NOT; self.model = string_null; - if (deathmatch && deathmatch != 2) + if (deathmatch_item_respawn()) self.nextthink = time + 20; self.think = SUB_regen; - sprint(other, LOC_ITEM_PICKUP_NORMAL); - sprint(other, ftos(value)); - sprint(other, LOC_ITEM_TYPE_ARMOR); - sprint(other, "\n"); + sprint(other, PRINT_LOW, LOC_ITEM_PICKUP_NORMAL); + sprint(other, PRINT_LOW, ftos(value)); + sprint(other, PRINT_LOW, LOC_ITEM_TYPE_ARMOR); + sprint(other, PRINT_LOW, "\n"); // armor touch sound sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); @@ -327,6 +474,9 @@ void() armor_touch = void() item_armor1 = { + if (deathmatch_no_armor()) + return; + self.touch = armor_touch; precache_model ("progs/armor.mdl"); setmodel (self, "progs/armor.mdl"); @@ -343,6 +493,9 @@ void() item_armor1 = void() item_armor2 = { + if (deathmatch_no_armor()) + return; + self.touch = armor_touch; precache_model ("progs/armor.mdl"); setmodel (self, "progs/armor.mdl"); @@ -359,6 +512,9 @@ void() item_armor2 = void() item_armorInv = { + if (deathmatch_no_armor()) + return; + self.touch = armor_touch; precache_model ("progs/armor.mdl"); setmodel (self, "progs/armor.mdl"); @@ -377,17 +533,27 @@ WEAPONS void() bound_other_ammo = { - if (other.ammo_shells > 100) - other.ammo_shells = 100; + if (deathmatch_unlimited_ammo()) + { + other.ammo_shells = 255; + other.ammo_nails = 255; + other.ammo_rockets = 255; + other.ammo_cells = 255; + } + else + { + if (other.ammo_shells > 100) + other.ammo_shells = 100; - if (other.ammo_nails > 200) - other.ammo_nails = 200; + if (other.ammo_nails > 200) + other.ammo_nails = 200; - if (other.ammo_rockets > 100) - other.ammo_rockets = 100; + if (other.ammo_rockets > 100) + other.ammo_rockets = 100; - if (other.ammo_cells > 100) - other.ammo_cells = 100; + if (other.ammo_cells > 100) + other.ammo_cells = 100; + } }; @@ -478,9 +644,8 @@ void() weapon_touch = best = W_BestWeapon(); self = stemp; - if (deathmatch > 1 || coop) + if (deathmatch_weapon_stay() || coop) leave = 1; - else leave = 0; @@ -547,10 +712,10 @@ void() weapon_touch = else objerror ("weapon_touch: unknown classname"); - sprint (other, LOC_ITEM_PICKUP_NORMAL); - sprint (other, "the "); - sprint (other, self.netname); - sprint (other, "\n"); + sprint (other, PRINT_LOW, LOC_ITEM_PICKUP_NORMAL); + sprint (other, PRINT_LOW, "the "); + sprint (other, PRINT_LOW, self.netname); + sprint (other, PRINT_LOW, "\n"); // weapon touch sound sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM); stuffcmd (other, "bf\n"); @@ -581,7 +746,7 @@ void() weapon_touch = self.model = string_null; self.solid = SOLID_NOT; - if (deathmatch == 1) + if (deathmatch && !deathmatch_weapon_stay()) self.nextthink = time + 30; self.think = SUB_regen; @@ -599,6 +764,9 @@ void() weapon_touch = void() weapon_supershotgun = { + if (deathmatch_no_weapons_on_map() || deathmatch_no_super_shotgun_on_map()) + return; + precache_model ("progs/g_shot.mdl"); setmodel (self, "progs/g_shot.mdl"); self.weapon = IT_SUPER_SHOTGUN; @@ -616,6 +784,9 @@ void() weapon_supershotgun = void() weapon_nailgun = { + if (deathmatch_no_weapons_on_map() || deathmatch_no_nailgun_on_map()) + return; + precache_model ("progs/g_nail.mdl"); setmodel (self, "progs/g_nail.mdl"); self.weapon = IT_NAILGUN; @@ -633,6 +804,9 @@ void() weapon_nailgun = void() weapon_supernailgun = { + if (deathmatch_no_weapons_on_map() || deathmatch_no_super_nailgun_on_map()) + return; + precache_model ("progs/g_nail2.mdl"); setmodel (self, "progs/g_nail2.mdl"); self.weapon = IT_SUPER_NAILGUN; @@ -650,6 +824,9 @@ void() weapon_supernailgun = void() weapon_grenadelauncher = { + if (deathmatch_no_weapons_on_map() || deathmatch_no_grenade_launcher_on_map()) + return; + precache_model ("progs/g_rock.mdl"); setmodel (self, "progs/g_rock.mdl"); self.weapon = IT_GRENADE_LAUNCHER; @@ -667,6 +844,9 @@ void() weapon_grenadelauncher = void() weapon_rocketlauncher = { + if (deathmatch_no_weapons_on_map() || deathmatch_no_rocket_launcher_on_map()) + return; + precache_model ("progs/g_rock2.mdl"); setmodel (self, "progs/g_rock2.mdl"); self.weapon = IT_ROCKET_LAUNCHER; @@ -685,6 +865,9 @@ void() weapon_rocketlauncher = void() weapon_lightning = { + if (deathmatch_no_weapons_on_map() || deathmatch_no_lightning_gun_on_map()) + return; + precache_model ("progs/g_light.mdl"); setmodel (self, "progs/g_light.mdl"); self.weapon = IT_LIGHTNING; @@ -759,11 +942,11 @@ void() ammo_touch = bound_other_ammo (); // Print message - sprint (other, LOC_ITEM_PICKUP_NORMAL); - sprint (other, ftos(self.aflag)); - sprint (other, " "); - sprint (other, self.netname); - sprint (other, "\n"); + sprint (other, PRINT_LOW, LOC_ITEM_PICKUP_NORMAL); + sprint (other, PRINT_LOW, ftos(self.aflag)); + sprint (other, PRINT_LOW, " "); + sprint (other, PRINT_LOW, self.netname); + sprint (other, PRINT_LOW, "\n"); // ammo touch sound sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); @@ -789,10 +972,14 @@ void() ammo_touch = self.model = string_null; self.solid = SOLID_NOT; - if (deathmatch && deathmatch != 2) - self.nextthink = time + 30; - - self.think = SUB_regen; + if (deathmatch_item_respawn()) + { + self.think = SUB_regen; + if (deathmatch_slow_ammo()) + self.nextthink = time + 30; + else + self.nextthink = time + 15; + } activator = other; SUB_UseTargets(); // fire all targets / killtargets @@ -811,6 +998,9 @@ float WEAPON_BIG2 = 1; void() item_shells = { + if (deathmatch_no_shell_pickups()) + return; + self.touch = ammo_touch; if (self.spawnflags & WEAPON_BIG2) @@ -841,6 +1031,9 @@ void() item_shells = void() item_spikes = { + if (deathmatch_no_nail_pickups()) + return; + self.touch = ammo_touch; if (self.spawnflags & WEAPON_BIG2) @@ -871,6 +1064,9 @@ void() item_spikes = void() item_rockets = { + if (deathmatch_no_rocket_pickups()) + return; + self.touch = ammo_touch; if (self.spawnflags & WEAPON_BIG2) @@ -902,6 +1098,9 @@ void() item_rockets = void() item_cells = { + if (deathmatch_no_cell_pickups()) + return; + self.touch = ammo_touch; if (self.spawnflags & WEAPON_BIG2) @@ -1018,9 +1217,9 @@ void() key_touch = if (other.items & self.items) return; - sprint (other, LOC_ITEM_PICKUP_NORMAL); - sprint (other, self.netname); - sprint (other,"\n"); + sprint (other, PRINT_LOW, LOC_ITEM_PICKUP_NORMAL); + sprint (other, PRINT_LOW, self.netname); + sprint (other, PRINT_LOW, "\n"); sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); stuffcmd (other, "bf\n"); @@ -1181,9 +1380,9 @@ void() sigil_touch = msg = string_null; if (msg != string_null) { - bprint (other.netname); - bprint (msg); - bprint ("\n"); + bprint (PRINT_HIGH, other.netname); + bprint (PRINT_HIGH, msg); + bprint (PRINT_HIGH, "\n"); centerprint2 (other, LOC_RUNE_LQ_YOU, msg); } @@ -1266,9 +1465,9 @@ void() powerup_touch = if (other.health <= 0) return; - sprint (other, LOC_ITEM_PICKUP_NORMAL); - sprint (other, self.netname); - sprint (other,"\n"); + sprint (other, PRINT_LOW, LOC_ITEM_PICKUP_NORMAL); + sprint (other, PRINT_LOW, self.netname); + sprint (other, PRINT_LOW, "\n"); if (deathmatch) { @@ -1309,6 +1508,12 @@ void() powerup_touch = if (self.classname == "item_artifact_super_damage") { + if (deathmatch_supermode()) + { + other.armortype = 0; + other.armorvalue = 0; + other.ammo_cells = 0; + } other.super_time = 1; other.super_damage_finished = time + 30; } @@ -1327,9 +1532,8 @@ Player is invulnerable for 30 seconds */ void() item_artifact_invulnerability = { - if (deathmatch == 4) { + if (deathmatch_no_powerups()) return; - } self.touch = powerup_touch; @@ -1340,6 +1544,11 @@ void() item_artifact_invulnerability = self.noise = "items/protect.wav"; setmodel (self, "progs/invulner.mdl"); self.netname = LOC_ITEM_NAME_PENTPROT; + +#ifdef __QW__ // EF_RED is not supported in NQ + self.effects = self.effects | EF_RED; +#endif + self.items = IT_INVULNERABILITY; setsize (self, '-16 -16 -24', '16 16 32'); StartItem (); @@ -1375,9 +1584,8 @@ Player is invisible for 30 seconds */ void() item_artifact_invisibility = { - if (deathmatch == 4) { + if (deathmatch_no_powerups()) return; - } self.touch = powerup_touch; @@ -1402,9 +1610,8 @@ The next attack from the player will do 4x damage */ void() item_artifact_super_damage = { - if (deathmatch == 4) { + if (deathmatch_no_powerups()) return; - } self.touch = powerup_touch; @@ -1412,7 +1619,16 @@ void() item_artifact_super_damage = precache_sound ("items/damage.wav"); self.noise = "items/damage.wav"; setmodel (self, "progs/quaddama.mdl"); - self.netname = LOC_ITEM_NAME_QUADDMG; + + if (deathmatch_supermode()) + self.netname = LOC_ITEM_NAME_OCTDMG; + else + self.netname = LOC_ITEM_NAME_QUADDMG; + +#ifdef __QW__ // EF_BLUE is not supported in NQ + self.effects = self.effects | EF_BLUE; +#endif + self.items = IT_QUAD; setsize (self, '-16 -16 -24', '16 16 32'); StartItem (); @@ -1437,6 +1653,10 @@ void() BackpackTouch = local entity stemp; local float acount; + if (deathmatch_supermode()) + if (other.invincible_time > 0) + return; + if (other.classname != "player") return; @@ -1444,14 +1664,53 @@ void() BackpackTouch = return; acount = 0; - sprint (other, LOC_ITEM_PICKUP_NORMAL);//Netquake does not support print_low + sprint (other, PRINT_LOW, LOC_ITEM_PICKUP_NORMAL); + + // Deathmatch 4 functionality + if (deathmatch_supermode()) + { + other.health = other.health + 10; + sprint (other, PRINT_LOW, "10"); + sprint (other, PRINT_LOW, LOC_ITEM_PICKUP_ADD_HEALTH); + sprint (other, PRINT_LOW, "\n"); + if ((other.health > 250) && (other.health < 300)) + sound (other, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM); + else + sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + remove(self); + + if (other.health > 299) + { + if (other.invincible_time != 1) + { + other.invincible_time = 1; + other.invincible_finished = time + 30; + other.items = other.items | IT_INVULNERABILITY; + + other.super_time = 1; + other.super_damage_finished = time + 30; + other.items = other.items | IT_QUAD; + + other.ammo_cells = 0; + + sound (other, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM); + stuffcmd (other, "bf\n"); + bprint (PRINT_HIGH, other.netname); + bprint (PRINT_HIGH, LOC_BONUS_POWERS); + bprint (PRINT_HIGH, "\n"); + } + } + self = other; + return; + } if (self.items) { if ((other.items & self.items) == 0) { acount = 1; - sprint (other, self.netname); + sprint (other, PRINT_LOW, self.netname); } } @@ -1479,52 +1738,56 @@ void() BackpackTouch = if (self.ammo_shells) { if (acount) - sprint(other, ", "); + sprint(other, PRINT_LOW, ", "); acount = 1; s = ftos(self.ammo_shells); - sprint (other, s); - sprint (other, " "); - sprint (other, LOC_WEAPON_AMMO_SHELLS); + sprint (other, PRINT_LOW, s); + sprint (other, PRINT_LOW, " "); + sprint (other, PRINT_LOW, LOC_WEAPON_AMMO_SHELLS); } if (self.ammo_nails) { if (acount) - sprint(other, ", "); + sprint(other, PRINT_LOW, ", "); acount = 1; s = ftos(self.ammo_nails); - sprint (other, s); - sprint (other, " "); - sprint (other, LOC_WEAPON_AMMO_NAILS); + sprint (other, PRINT_LOW, s); + sprint (other, PRINT_LOW, " "); + sprint (other, PRINT_LOW, LOC_WEAPON_AMMO_NAILS); } if (self.ammo_rockets) { if (acount) - sprint(other, ", "); + sprint(other, PRINT_LOW, ", "); acount = 1; s = ftos(self.ammo_rockets); - sprint (other, s); - sprint (other, " "); - sprint (other, LOC_WEAPON_AMMO_ROCKETS); + sprint (other, PRINT_LOW, s); + sprint (other, PRINT_LOW, " "); + sprint (other, PRINT_LOW, LOC_WEAPON_AMMO_ROCKETS); } if (self.ammo_cells) { if (acount) - sprint(other, ", "); + sprint(other, PRINT_LOW, ", "); acount = 1; s = ftos(self.ammo_cells); - sprint (other, s); - sprint (other, " "); - sprint (other, LOC_WEAPON_AMMO_CELLS); + sprint (other, PRINT_LOW, s); + sprint (other, PRINT_LOW, " "); + sprint (other, PRINT_LOW, LOC_WEAPON_AMMO_CELLS); } - // sprint (other, LOC_ITEM_FROM_BACKPACK); - sprint (other, "\n"); + // sprint (other, PRINT_LOW, LOC_ITEM_FROM_BACKPACK); + sprint (other, PRINT_LOW, "\n"); + + // If backpack has a grenade or rocket launcher in it, fill it with at least five rockets + if ( deathmatch_backpack_min_rockets() && ( (WeaponCode(new)==6) || (WeaponCode(new)==7) ) && (other.ammo_rockets < 5) ) + other.ammo_rockets = 5; // backpack touch sound sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM); @@ -1568,8 +1831,24 @@ void() DropBackpack = item.items = self.weapon; - //gnounc - item.netname = LOC_ITEM_NAME_BACKPACK; + if (item.items == IT_AXE) + item.netname = LOC_WEAPON_NAME_AXE; + else if (item.items == IT_SHOTGUN) + item.netname = LOC_WEAPON_NAME_SHOTGUN; + else if (item.items == IT_SUPER_SHOTGUN) + item.netname = LOC_WEAPON_NAME_SUPER_SHOTGUN; + else if (item.items == IT_NAILGUN) + item.netname = LOC_WEAPON_NAME_NAILGUN; + else if (item.items == IT_SUPER_NAILGUN) + item.netname = LOC_WEAPON_NAME_SUPER_NAILGUN; + else if (item.items == IT_GRENADE_LAUNCHER) + item.netname = LOC_WEAPON_NAME_GRENADE_LAUNCH; + else if (item.items == IT_ROCKET_LAUNCHER) + item.netname = LOC_WEAPON_NAME_ROCKET_LAUNCH; + else if (item.items == IT_LIGHTNING) + item.netname = LOC_WEAPON_NAME_THUNDERBOLT; + else + item.netname = LOC_ITEM_NAME_BACKPACK; item.ammo_shells = self.ammo_shells; item.ammo_nails = self.ammo_nails; diff --git a/qcsrc/localized_text.qc b/qcsrc/localized_text.qc index ca59e30c1..25bfd1334 100644 --- a/qcsrc/localized_text.qc +++ b/qcsrc/localized_text.qc @@ -1,23 +1,23 @@ /* - Copyright (C) 1996-1997 Id Software, Inc. - Copyright (C) 2023 ZungryWare - Copyright (C) 2024 Ivy Bowling + Copyright (C) 1996-1997 Id Software, Inc. + Copyright (C) 2023 ZungryWare + Copyright (C) 2024 Ivy Bowling - 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 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. + 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 + 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. + See file, 'COPYING', for details. */ // @@ -29,31 +29,31 @@ EPISODE EPILOGUE STRINGS - These strings in-engine have a 40 character limit before - truncation. + These strings in-engine have a 40 character limit before + truncation. ==============================================================================*/ #ifdef __LIBREQUAKE__ -#define LOC_EPILOGUE_0 "\nAs the ethereal essence of your very\nbeing drifts through time and space,\nyou experience relentless calm and\nserene determination. You embrace the\nliminal, formless nature of your\nexistence within the amorphous expanse\nbetween realities.\n\nSuspended between the veils of life\nand death, among the realm of celestial\ndissolution, you wait to be called upon\nagain. To regain your corporeal form\nand step into the crucible of fate.\nTo finish your task and keep at bay the\nonslaught of cosmic horrors.\n" -#define LOC_EPILOGUE_1 "EPISODE 1 COMPLETION TEXT GOES HERE" -#define LOC_EPILOGUE_1_FREEWARE "EPISODE 1 COMPLETION TEXT GOES HERE" -#define LOC_EPILOGUE_2 "EPISODE 2 COMPLETION TEXT GOES HERE" -#define LOC_EPILOGUE_3 "EPISODE 3 COMPLETION TEXT GOES HERE" -#define LOC_EPILOGUE_4 "EPISODE 4 COMPLETION TEXT GOES HERE" -#define LOC_EPILOGUE_RUNES "ALL RUNES TEXT GOES HERE" -#define LOC_EPILOGUE_FINALE "GAME COMPLETION TEXT GOES HERE" +#define LOC_EPILOGUE_0 "\nAs the ethereal essence of your very\nbeing drifts through time and space,\nyou experience relentless calm and\nserene determination. You embrace the\nliminal, formless nature of your\nexistence within the amorphous expanse\nbetween realities.\n\nSuspended between the veils of life\nand death, among the realm of celestial\ndissolution, you wait to be called upon\nagain. To regain your corporeal form\nand step into the crucible of fate.\nTo finish your task and keep at bay the\nonslaught of cosmic horrors.\n" +#define LOC_EPILOGUE_1 "EPISODE 1 COMPLETION TEXT GOES HERE" +#define LOC_EPILOGUE_1_FREEWARE "EPISODE 1 COMPLETION TEXT GOES HERE" +#define LOC_EPILOGUE_2 "EPISODE 2 COMPLETION TEXT GOES HERE" +#define LOC_EPILOGUE_3 "EPISODE 3 COMPLETION TEXT GOES HERE" +#define LOC_EPILOGUE_4 "EPISODE 4 COMPLETION TEXT GOES HERE" +#define LOC_EPILOGUE_RUNES "ALL RUNES TEXT GOES HERE" +#define LOC_EPILOGUE_FINALE "GAME COMPLETION TEXT GOES HERE" #else -#define LOC_EPILOGUE_1 "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task. A Rune of magic\npower lies at the end of each haunted\nland of Quake. Go forth, seek the\ntotality of the four Runes!" -#define LOC_EPILOGUE_1_FREEWARE "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task in the other three\nhaunted lands of Quake. Or are you? If\nyou don't register Quake, you'll never\nknow what awaits you in the Realm of\nBlack Magic, the Netherworld, and the\nElder World!" -#define LOC_EPILOGUE_2 "The Rune of Black Magic throbs evilly in\nyour hand and whispers dark thoughts\ninto your brain. You learn the inmost\nlore of the Hell-Mother; Shub-Niggurath!\nYou now know that she is behind all the\nterrible plotting which has led to so\nmuch death and horror. But she is not\ninviolate! Armed with this Rune, you\nrealize that once all four Runes are\ncombined, the gate to Shub-Niggurath's\nPit will open, and you can face the\nWitch-Goddess herself in her frightful\notherworld cathedral." -#define LOC_EPILOGUE_3 "The charred viscera of diabolic horrors\nbubble viscously as you seize the Rune\nof Hell Magic. Its heat scorches your\nhand, and its terrible secrets blight\nyour mind. Gathering the shreds of your\ncourage, you shake the devil's shackles\nfrom your soul, and become ever more\nhard and determined to destroy the\nhideous creatures whose mere existence\nthreatens the souls and psyches of all\nthe population of Earth." -#define LOC_EPILOGUE_4 "Despite the awful might of the Elder\nWorld, you have achieved the Rune of\nElder Magic, capstone of all types of\narcane wisdom. Beyond good and evil,\nbeyond life and death, the Rune\npulsates, heavy with import. Patient and\npotent, the Elder Being Shub-Niggurath\nweaves her dire plans to clear off all\nlife from the Earth, and bring her own\nfoul offspring to our world! For all the\ndwellers in these nightmare dimensions\nare her descendants! Once all Runes of\nmagic power are united, the energy\nbehind them will blast open the Gateway\nto Shub-Niggurath, and you can travel\nthere to foil the Hell-Mother's plots\nin person." -#define LOC_EPILOGUE_RUNES "Now, you have all four Runes. You sense\ntremendous invisible forces moving to\nunseal ancient barriers. Shub-Niggurath\nhad hoped to use the Runes Herself to\nclear off the Earth, but now instead,\nyou will use them to enter her home and\nconfront her as an avatar of avenging\nEarth-life. If you defeat her, you will\nbe remembered forever as the savior of\nthe planet. If she conquers, it will be\nas if you had never been born." -#define LOC_EPILOGUE_FINALE "Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you." +#define LOC_EPILOGUE_1 "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task. A Rune of magic\npower lies at the end of each haunted\nland of Quake. Go forth, seek the\ntotality of the four Runes!" +#define LOC_EPILOGUE_1_FREEWARE "As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task in the other three\nhaunted lands of Quake. Or are you? If\nyou don't register Quake, you'll never\nknow what awaits you in the Realm of\nBlack Magic, the Netherworld, and the\nElder World!" +#define LOC_EPILOGUE_2 "The Rune of Black Magic throbs evilly in\nyour hand and whispers dark thoughts\ninto your brain. You learn the inmost\nlore of the Hell-Mother; Shub-Niggurath!\nYou now know that she is behind all the\nterrible plotting which has led to so\nmuch death and horror. But she is not\ninviolate! Armed with this Rune, you\nrealize that once all four Runes are\ncombined, the gate to Shub-Niggurath's\nPit will open, and you can face the\nWitch-Goddess herself in her frightful\notherworld cathedral." +#define LOC_EPILOGUE_3 "The charred viscera of diabolic horrors\nbubble viscously as you seize the Rune\nof Hell Magic. Its heat scorches your\nhand, and its terrible secrets blight\nyour mind. Gathering the shreds of your\ncourage, you shake the devil's shackles\nfrom your soul, and become ever more\nhard and determined to destroy the\nhideous creatures whose mere existence\nthreatens the souls and psyches of all\nthe population of Earth." +#define LOC_EPILOGUE_4 "Despite the awful might of the Elder\nWorld, you have achieved the Rune of\nElder Magic, capstone of all types of\narcane wisdom. Beyond good and evil,\nbeyond life and death, the Rune\npulsates, heavy with import. Patient and\npotent, the Elder Being Shub-Niggurath\nweaves her dire plans to clear off all\nlife from the Earth, and bring her own\nfoul offspring to our world! For all the\ndwellers in these nightmare dimensions\nare her descendants! Once all Runes of\nmagic power are united, the energy\nbehind them will blast open the Gateway\nto Shub-Niggurath, and you can travel\nthere to foil the Hell-Mother's plots\nin person." +#define LOC_EPILOGUE_RUNES "Now, you have all four Runes. You sense\ntremendous invisible forces moving to\nunseal ancient barriers. Shub-Niggurath\nhad hoped to use the Runes Herself to\nclear off the Earth, but now instead,\nyou will use them to enter her home and\nconfront her as an avatar of avenging\nEarth-life. If you defeat her, you will\nbe remembered forever as the savior of\nthe planet. If she conquers, it will be\nas if you had never been born." +#define LOC_EPILOGUE_FINALE "Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you." #endif // __LIBREQUAKE__ @@ -65,17 +65,17 @@ #ifdef __LIBREQUAKE__ -#define LOC_CLIENT_JOIN " joined the game" -#define LOC_CLIENT_DISCON " exited the level" -#define LOC_CLIENT_DISCON_DM_A " left the game with " -#define LOC_CLIENT_DISCON_DM_B " frags" +#define LOC_CLIENT_JOIN " joined the server" +#define LOC_CLIENT_EXIT_LEVEL " exited the level" +#define LOC_CLIENT_DISCON_A " left the server the game with " +#define LOC_CLIENT_DISCON_B " frags" #else -#define LOC_CLIENT_JOIN " entered the game" -#define LOC_CLIENT_DISCON " exited the level" -#define LOC_CLIENT_DISCON_DM_A " left the game with " -#define LOC_CLIENT_DISCON_DM_B " frags" +#define LOC_CLIENT_JOIN " entered the game" +#define LOC_CLIENT_EXIT_LEVEL " exited the level" +#define LOC_CLIENT_DISCON_A " left the game with " +#define LOC_CLIENT_DISCON_B " frags" #endif // __LIBREQUAKE__ @@ -87,13 +87,13 @@ #ifdef __LIBREQUAKE__ -#define LOC_WEAPON_INVALID "Invalid weapon" -#define LOC_WEAPON_NOAMMO "Out of ammo" +#define LOC_WEAPON_INVALID "Invalid weapon" +#define LOC_WEAPON_NOAMMO "Out of ammo" #else -#define LOC_WEAPON_INVALID "no weapon." -#define LOC_WEAPON_NOAMMO "not enough ammo." +#define LOC_WEAPON_INVALID "no weapon." +#define LOC_WEAPON_NOAMMO "not enough ammo." #endif // __LIBREQUAKE__ @@ -103,39 +103,56 @@ ==============================================================================*/ -#define LOC_ITEM_PICKUP_NORMAL "You got " -#define LOC_ITEM_PICKUP_HEALTH "You receieve " +#define LOC_ITEM_PICKUP_NORMAL "You got " +#define LOC_ITEM_PICKUP_HEALTH "You receieve " +#define LOC_ITEM_PICKUP_ADD_HEALTH " additional health" -#define LOC_ITEM_FROM_BACKPACK " from a backpack" // Unused.. +#define LOC_ITEM_FROM_BACKPACK " from a backpack" // Unused.. -#define LOC_ITEM_TYPE_HEALTH " health" -#define LOC_ITEM_TYPE_ARMOR " armor" +#define LOC_ITEM_TYPE_HEALTH " health" +#define LOC_ITEM_TYPE_ARMOR " armor" #ifdef __LIBREQUAKE__ -#define LOC_ITEM_NAME_QUADDMG "the Crusher Sigil" -#define LOC_ITEM_NAME_PENTPROT "Lucifier's Protection" -#define LOC_ITEM_NAME_SHADRING "the Eye of Enigma" -#define LOC_ITEM_NAME_BIOSUIT "the Diving Suit" -#define LOC_ITEM_NAME_BACKPACK "Backpack" +#define LOC_ITEM_NAME_QUADDMG "the Crusher Sigil" +#define LOC_ITEM_NAME_OCTDMG "the Demolisher Sigil" +#define LOC_ITEM_NAME_PENTPROT "Lucifier's Protection" +#define LOC_ITEM_NAME_SHADRING "the Eye of Enigma" +#define LOC_ITEM_NAME_BIOSUIT "the Diving Suit" +#define LOC_ITEM_NAME_BACKPACK "Backpack" -#define LOC_ITEM_FADE_QUADDMG "Your Crusher Sigil is fading..." -#define LOC_ITEM_FADE_PENTPROT "Lucifier's Protection is fading..." -#define LOC_ITEM_FADE_SHADRING "The Eye of Enigma is fading..." -#define LOC_ITEM_FADE_BIOSUIT "Air in Diving Suit is running out..." +#define LOC_ITEM_FADE_QUADDMG "Your Crusher Sigil is fading..." +#define LOC_ITEM_FADE_OCTDMG "Your Demolisher Sigil is fading..." +#define LOC_ITEM_FADE_PENTPROT "Lucifier's Protection is fading..." +#define LOC_ITEM_FADE_SHADRING "The Eye of Enigma is fading..." +#define LOC_ITEM_FADE_BIOSUIT "Air in Diving Suit is running out..." + +#define LOC_BONUS_POWERS " is coming for you all!!!" + +#define LOC_ITEM_LOST_A " lost " +#define LOC_ITEM_LOST_B " with " +#define LOC_ITEM_LOST_C " seconds left" #else -#define LOC_ITEM_NAME_QUADDMG "Quad Damage" -#define LOC_ITEM_NAME_PENTPROT "Pentagram of Protection" -#define LOC_ITEM_NAME_SHADRING "Ring of Shadows" -#define LOC_ITEM_NAME_BIOSUIT "Biosuit" -#define LOC_ITEM_NAME_BACKPACK "Backpack" +#define LOC_ITEM_NAME_QUADDMG "Quad Damage" +#define LOC_ITEM_NAME_OCTDMG "OctaPower" +#define LOC_ITEM_NAME_PENTPROT "Pentagram of Protection" +#define LOC_ITEM_NAME_SHADRING "Ring of Shadows" +#define LOC_ITEM_NAME_BIOSUIT "Biosuit" +#define LOC_ITEM_NAME_BACKPACK "Backpack" + +#define LOC_ITEM_FADE_QUADDMG "Quad Damage is wearing off" +#define LOC_ITEM_FADE_OCTDMG "OctaPower is wearing off" +#define LOC_ITEM_FADE_PENTPROT "Protection is almost burned out" +#define LOC_ITEM_FADE_SHADRING "Ring of Shadows magic is fading" +#define LOC_ITEM_FADE_BIOSUIT "Air supply in Biosuit expiring" + +#define LOC_BONUS_POWERS " attains bonus powers!!!" -#define LOC_ITEM_FADE_QUADDMG "Quad Damage is wearing off" -#define LOC_ITEM_FADE_PENTPROT "Protection is almost burned out" -#define LOC_ITEM_FADE_SHADRING "Ring of Shadows magic is fading" -#define LOC_ITEM_FADE_BIOSUIT "Air supply in Biosuit expiring" +#define LOC_ITEM_LOST_A " lost a " +#define LOC_ITEM_LOST_B " with " +#define LOC_ITEM_LOST_C " seconds remaining" #endif // __LIBREQUAKE__ @@ -147,32 +164,32 @@ #ifdef __LIBREQUAKE__ -#define LOC_WEAPON_NAME_AXE "Axe" // Unused.. -#define LOC_WEAPON_NAME_SHOTGUN "Shotgun" // Unused.. +#define LOC_WEAPON_NAME_AXE "Axe" // Unused.. +#define LOC_WEAPON_NAME_SHOTGUN "Shotgun" // Unused.. #define LOC_WEAPON_NAME_SUPER_SHOTGUN "Double-Barreled Shotgun" -#define LOC_WEAPON_NAME_NAILGUN "Nailgun" +#define LOC_WEAPON_NAME_NAILGUN "Nailgun" #define LOC_WEAPON_NAME_SUPER_NAILGUN "Super Nailgun" #define LOC_WEAPON_NAME_GRENADE_LAUNCH "Grenade Launcher" #define LOC_WEAPON_NAME_ROCKET_LAUNCH "Rocket Launcher" -#define LOC_WEAPON_NAME_THUNDERBOLT "Lightning Gun" +#define LOC_WEAPON_NAME_THUNDERBOLT "Lightning Gun" #else -#define LOC_WEAPON_NAME_AXE "Axe" // Unused.. -#define LOC_WEAPON_NAME_SHOTGUN "Shotgun" // Unused.. +#define LOC_WEAPON_NAME_AXE "Axe" // Unused.. +#define LOC_WEAPON_NAME_SHOTGUN "Shotgun" // Unused.. #define LOC_WEAPON_NAME_SUPER_SHOTGUN "Double-barrelled Shotgun" -#define LOC_WEAPON_NAME_NAILGUN "nailgun" +#define LOC_WEAPON_NAME_NAILGUN "nailgun" #define LOC_WEAPON_NAME_SUPER_NAILGUN "Super Nailgun" #define LOC_WEAPON_NAME_GRENADE_LAUNCH "Grenade Launcher" #define LOC_WEAPON_NAME_ROCKET_LAUNCH "Rocket Launcher" -#define LOC_WEAPON_NAME_THUNDERBOLT "Thunderbolt" +#define LOC_WEAPON_NAME_THUNDERBOLT "Thunderbolt" #endif // __LIBREQUAKE__ -#define LOC_WEAPON_AMMO_SHELLS "shells" -#define LOC_WEAPON_AMMO_NAILS "nails" -#define LOC_WEAPON_AMMO_ROCKETS "rockets" -#define LOC_WEAPON_AMMO_CELLS "cells" +#define LOC_WEAPON_AMMO_SHELLS "shells" +#define LOC_WEAPON_AMMO_NAILS "nails" +#define LOC_WEAPON_AMMO_ROCKETS "rockets" +#define LOC_WEAPON_AMMO_CELLS "cells" /*============================================================================== @@ -182,23 +199,23 @@ #ifdef __LIBREQUAKE__ -#define LOC_KEY_NAME_SILVER "Silver Key" -#define LOC_KEY_NAME_SILVER_RUNE "Silver Key" -#define LOC_KEY_NAME_SILVER_CARD "Silver Keycard" -#define LOC_KEY_NAME_GOLD "Gold Key" -#define LOC_KEY_NAME_GOLD_RUNE "Gold Key" -#define LOC_KEY_NAME_GOLD_CARD "Gold Keycard" -#define LOC_KEY_NEED "You need " +#define LOC_KEY_NAME_SILVER "Silver Key" +#define LOC_KEY_NAME_SILVER_RUNE "Silver Key" +#define LOC_KEY_NAME_SILVER_CARD "Silver Keycard" +#define LOC_KEY_NAME_GOLD "Gold Key" +#define LOC_KEY_NAME_GOLD_RUNE "Gold Key" +#define LOC_KEY_NAME_GOLD_CARD "Gold Keycard" +#define LOC_KEY_NEED "You need " #else -#define LOC_KEY_NAME_SILVER "silver key" -#define LOC_KEY_NAME_SILVER_RUNE "silver runekey" -#define LOC_KEY_NAME_SILVER_CARD "silver keycard" -#define LOC_KEY_NAME_GOLD "gold key" -#define LOC_KEY_NAME_GOLD_RUNE "gold runekey" -#define LOC_KEY_NAME_GOLD_CARD "gold keycard" -#define LOC_KEY_NEED "You need " +#define LOC_KEY_NAME_SILVER "silver key" +#define LOC_KEY_NAME_SILVER_RUNE "silver runekey" +#define LOC_KEY_NAME_SILVER_CARD "silver keycard" +#define LOC_KEY_NAME_GOLD "gold key" +#define LOC_KEY_NAME_GOLD_RUNE "gold runekey" +#define LOC_KEY_NAME_GOLD_CARD "gold keycard" +#define LOC_KEY_NEED "You need " #endif // __LIBREQUAKE__ @@ -208,18 +225,18 @@ ==============================================================================*/ -#define LOC_COUNTER_COUNT_1A "Only " -#define LOC_COUNTER_COUNT_1B " more to go..." -#define LOC_COUNTER_COUNT_2 "There are more to go..." -#define LOC_COUNTER_COMPLETE "Sequence completed!" +#define LOC_COUNTER_COUNT_1A "Only " +#define LOC_COUNTER_COUNT_1B " more to go..." +#define LOC_COUNTER_COUNT_2 "There are more to go..." +#define LOC_COUNTER_COMPLETE "Sequence completed!" #ifdef __LIBREQUAKE__ -#define LOC_SECRET "You found a secret!" +#define LOC_SECRET "You found a secret!" #else -#define LOC_SECRET "You found a secret area!" +#define LOC_SECRET "You found a secret area!" #endif // __LIBREQUAKE__ @@ -229,15 +246,15 @@ ==============================================================================*/ -#define LOC_RUNE_GET "You got the rune!" +#define LOC_RUNE_GET "You got the rune!" #ifdef __LIBREQUAKE__ -#define LOC_RUNE_LQ_YOU "You" -#define LOC_RUNE_LQ_BLOOD " got the Rune of Blood!" -#define LOC_RUNE_LQ_BONE " got the Rune of Bone!" -#define LOC_RUNE_LQ_MIND " got the Rune of Mind!" -#define LOC_RUNE_LQ_SOUL " got the Rune of Soul!" +#define LOC_RUNE_LQ_YOU "You" +#define LOC_RUNE_LQ_BLOOD " got the Rune of Blood!" +#define LOC_RUNE_LQ_BONE " got the Rune of Bone!" +#define LOC_RUNE_LQ_MIND " got the Rune of Mind!" +#define LOC_RUNE_LQ_SOUL " got the Rune of Soul!" #endif // __LIBREQUAKE__ @@ -249,39 +266,39 @@ #ifdef __LIBREQUAKE__ -#define LOC_DEATH_ARMY " was shot by a Chosen" -#define LOC_DEATH_ENFORCER " was mowed down by a Cyberhunter" -#define LOC_DEATH_DOG " was gored by a Gore Hound" -#define LOC_DEATH_OGRE " was demolished by a Deep One" -#define LOC_DEATH_DEMON1 " was disemboweled by a Moon Rat" -#define LOC_DEATH_WIZARD " was poisoned by a Messenger" -#define LOC_DEATH_ZOMBIE " was pelted by a Deathless Cultist" -#define LOC_DEATH_KNIGHT " was stabbed by a Carcosan Knight" -#define LOC_DEATH_HELL_KNIGHT " was gutted by a Biohell Warrior" -#define LOC_DEATH_FISH " was nibbled by a Spine Eel" -#define LOC_DEATH_SHAMBLER " was shredded by a Hollow" -#define LOC_DEATH_SHALRATH " was blasted by a Servant of Nyarlathotep" -#define LOC_DEATH_TARBABY " was swarmed by a Bog Face" -#define LOC_DEATH_BOSS " was blasted by Cthulhi" -#define LOC_DEATH_OLDONE " became one with Shoggoth" +#define LOC_DEATH_ARMY " was shot by a Chosen" +#define LOC_DEATH_ENFORCER " was mowed down by a Cyberhunter" +#define LOC_DEATH_DOG " was gored by a Gore Hound" +#define LOC_DEATH_OGRE " was demolished by a Deep One" +#define LOC_DEATH_DEMON1 " was disemboweled by a Moon Rat" +#define LOC_DEATH_WIZARD " was shot by a Messenger" +#define LOC_DEATH_ZOMBIE " was pelted by a Deathless Cultist" +#define LOC_DEATH_KNIGHT " was stabbed by a Carcosan Knight" +#define LOC_DEATH_HELL_KNIGHT " was gutted by a Biohell Warrior" +#define LOC_DEATH_FISH " was nibbled by a Spine Eel" +#define LOC_DEATH_SHAMBLER " was shredded by a Hollow" +#define LOC_DEATH_SHALRATH " was blasted by a Servant of Nyarlathotep" +#define LOC_DEATH_TARBABY " was swarmed by a Bog Face" +#define LOC_DEATH_BOSS " was obliterated by Cthulhi" +#define LOC_DEATH_OLDONE " became one with Shoggoth" #else -#define LOC_DEATH_ARMY " was shot by a Grunt" -#define LOC_DEATH_ENFORCER " was blasted by an Enforcer" -#define LOC_DEATH_DOG " was mauled by a Rottweiler" -#define LOC_DEATH_OGRE " was destroyed by an Ogre" -#define LOC_DEATH_DEMON1 " was eviscerated by a Fiend" -#define LOC_DEATH_WIZARD " was scragged by a Scrag" -#define LOC_DEATH_ZOMBIE " joins the Zombies" -#define LOC_DEATH_KNIGHT " was slashed by a Knight" -#define LOC_DEATH_HELL_KNIGHT " was slain by a Death Knight" -#define LOC_DEATH_FISH " was fed to the Rotfish" -#define LOC_DEATH_SHAMBLER " was smashed by a Shambler" -#define LOC_DEATH_SHALRATH " was exploded by a Vore" -#define LOC_DEATH_TARBABY " was slimed by a Spawn" -#define LOC_DEATH_BOSS " was blasted by Cthulhi" -#define LOC_DEATH_OLDONE " became one with Shub-Niggurath" +#define LOC_DEATH_ARMY " was shot by a Grunt" +#define LOC_DEATH_ENFORCER " was blasted by an Enforcer" +#define LOC_DEATH_DOG " was mauled by a Rottweiler" +#define LOC_DEATH_OGRE " was destroyed by an Ogre" +#define LOC_DEATH_DEMON1 " was eviscerated by a Fiend" +#define LOC_DEATH_WIZARD " was scragged by a Scrag" +#define LOC_DEATH_ZOMBIE " joins the Zombies" +#define LOC_DEATH_KNIGHT " was slashed by a Knight" +#define LOC_DEATH_HELL_KNIGHT " was slain by a Death Knight" +#define LOC_DEATH_FISH " was fed to the Rotfish" +#define LOC_DEATH_SHAMBLER " was smashed by a Shambler" +#define LOC_DEATH_SHALRATH " was exploded by a Vore" +#define LOC_DEATH_TARBABY " was slimed by a Spawn" +#define LOC_DEATH_BOSS " was blasted by Cthulhi" +#define LOC_DEATH_OLDONE " became one with Shub-Niggurath" #endif // __LIBREQUAKE__ @@ -293,59 +310,62 @@ #ifdef __LIBREQUAKE__ -#define LOC_DEATH_EXPLO_BOX " was sent sky high" -#define LOC_DEATH_SQUISH " was crushed" -#define LOC_DEATH_SQUISH2 " was crushed by " -#define LOC_DEATH_TRAP_SPIKE " was perforated" -#define LOC_DEATH_TRAP_LASER " was lasered" -#define LOC_DEATH_FIREBALL " was hit by a lavaball" -#define LOC_DEATH_LEAVE " tried to escape" -#define LOC_DEATH_DROWN1 " forgot how to swim" -#define LOC_DEATH_DROWN2 " drowned" -#define LOC_DEATH_DROWN3 " ran out of air" -#define LOC_DEATH_SLIME1 " dissolved in acid" -#define LOC_DEATH_SLIME2 " was disincorporated" -#define LOC_DEATH_LAVA1 " fell into lava" -#define LOC_DEATH_LAVA2 " combusted" -#define LOC_DEATH_LAVA3 " dove headfirst into hot lava" -#define LOC_DEATH_FALL_1 " fell off a cliff" -#define LOC_DEATH_FALL_2 " took a long walk off a short pier" -#define LOC_DEATH_SPACE_1 " fell into space" -#define LOC_DEATH_SPACE_2 "'s screams went unheard" -#define LOC_DEATH_VOID_1 " fell into the void" -#define LOC_DEATH_VOID_2 " fell out of existence" -#define LOC_DEATH_DISCHARGE_WATER " took a toaster bath" -#define LOC_DEATH_DISCHARGE_SLIME " took a toaster bath" -#define LOC_DEATH_DISCHARGE_LAVA " took a toaster bath" -#define LOC_DEATH_SELF_GRENADE " didn't launch the grenade far enough" -#define LOC_DEATH_SELF_ROCKET " played with explosives" -#define LOC_DEATH_SELF_OTHER " died" -#define LOC_DEATH_SUICIDE " committed suicide" -#define LOC_DEATH_OTHER " died" +#define LOC_DEATH_EXPLO_BOX " was sent sky high" +#define LOC_DEATH_SQUISH " was crushed" +#define LOC_DEATH_SQUISH2 " was crushed by " +#define LOC_DEATH_TRAP_SPIKE " was perforated" +#define LOC_DEATH_TRAP_LASER " was lasered" +#define LOC_DEATH_FIREBALL " was hit by a lavaball" +#define LOC_DEATH_LEAVE " tried to escape" +#define LOC_DEATH_DROWN1 " forgot how to swim" +#define LOC_DEATH_DROWN2 " ran out of air" +#define LOC_DEATH_SLIME1 " dissolved in acid" +#define LOC_DEATH_SLIME2 " was disincorporated" +#define LOC_DEATH_LAVA1 " fell into lava" +#define LOC_DEATH_LAVA2 " combusted" +#define LOC_DEATH_LAVA3 " dove headfirst into hot lava" +#define LOC_DEATH_FALL1 " fell off a cliff" +#define LOC_DEATH_FALL2 " took a long walk off a short pier" +#define LOC_DEATH_SPACE1 " fell into space" +#define LOC_DEATH_SPACE2 "'s screams went unheard" +#define LOC_DEATH_VOID1 " fell into the void" +#define LOC_DEATH_VOID2 " fell out of existence" +#define LOC_DEATH_DISCHARGE_WATER " took a toaster bath" +#define LOC_DEATH_DISCHARGE_SLIME " took a toaster bath" +#define LOC_DEATH_DISCHARGE_LAVA " took a toaster bath" +#define LOC_DEATH_DISCHARGE_SELF "'s Lightning Gun Malfunctioned" +#define LOC_DEATH_SELF_GRENADE " didn't launch the grenade far enough" +#define LOC_DEATH_SELF_ROCKET " played with explosives" +#define LOC_DEATH_SELF_OTHER " misfired" +#define LOC_DEATH_SUICIDE " committed suicide" +#define LOC_DEATH_OTHER " died" #else -#define LOC_DEATH_EXPLO_BOX " blew up" -#define LOC_DEATH_SQUISH " was squished" -#define LOC_DEATH_SQUISH2 " was squished by " -#define LOC_DEATH_TRAP_SPIKE " was spiked" -#define LOC_DEATH_TRAP_LASER " was spiked" -#define LOC_DEATH_FIREBALL " ate a lavaball" -#define LOC_DEATH_LEAVE " tried to leave" -#define LOC_DEATH_DROWN1 " sleeps with the fishes" -#define LOC_DEATH_DROWN2 " sucks it down" -#define LOC_DEATH_SLIME1 " gulped a load of slime" -#define LOC_DEATH_SLIME2 " can't exist on slime alone" -#define LOC_DEATH_LAVA1 " turned into hot slag" -#define LOC_DEATH_LAVA2 " visits the Volcano God" -#define LOC_DEATH_LAVA3 " burst into flames" -#define LOC_DEATH_FALL " fell to his death" -#define LOC_DEATH_DISCHARGE_WATER " discharges into the water." -#define LOC_DEATH_SUICIDE_WEAPON_1 " becomes bored with life" -#define LOC_DEATH_SUICIDE_WEAPON_2 " checks if his weapon is loaded" -#define LOC_DEATH_SELF_GRENADE " tries to put the pin back in" -#define LOC_DEATH_SUICIDE " suicides" -#define LOC_DEATH_OTHER " died" +#define LOC_DEATH_EXPLO_BOX " blew up" +#define LOC_DEATH_SQUISH " was squished" +#define LOC_DEATH_SQUISH2 " was squished by " +#define LOC_DEATH_TRAP_SPIKE " was spiked" +#define LOC_DEATH_TRAP_LASER " was spiked" +#define LOC_DEATH_FIREBALL " ate a lavaball" +#define LOC_DEATH_LEAVE " tried to leave" +#define LOC_DEATH_DROWN1 " sleeps with the fishes" +#define LOC_DEATH_DROWN2 " sucks it down" +#define LOC_DEATH_SLIME1 " gulped a load of slime" +#define LOC_DEATH_SLIME2 " can't exist on slime alone" +#define LOC_DEATH_LAVA1 " turned into hot slag" +#define LOC_DEATH_LAVA2 " visits the Volcano God" +#define LOC_DEATH_LAVA3 " burst into flames" +#define LOC_DEATH_FALL " fell to his death" +#define LOC_DEATH_DISCHARGE_WATER " discharges into the water" +#define LOC_DEATH_DISCHARGE_SLIME " discharges into the slime" +#define LOC_DEATH_DISCHARGE_LAVA " discharges into the lava" +#define LOC_DEATH_DISCHARGE_SELF " electrocutes himself" +#define LOC_DEATH_SELF_GRENADE " tries to put the pin back in" +#define LOC_DEATH_SELF_ROCKET " becomes bored with life" +#define LOC_DEATH_SELF_OTHER " checks if his weapon is loaded" +#define LOC_DEATH_SUICIDE " suicides" +#define LOC_DEATH_OTHER " died" #endif // __LIBREQUAKE__ @@ -365,40 +385,40 @@ #ifdef __LIBREQUAKE__ -#define LOC_DEATH_AXE_1A " was hacked to death by " -#define LOC_DEATH_AXE_1B "" -#define LOC_DEATH_AXE_2A " was chopped to bits by " -#define LOC_DEATH_AXE_2B "" -#define LOC_DEATH_AXE_QA "'s bucket was kicked by " -#define LOC_DEATH_AXE_QB "" - -#define LOC_DEATH_SHOTGUN_1A " sucked on " -#define LOC_DEATH_SHOTGUN_1B "'s muffler" -#define LOC_DEATH_SHOTGUN_2A " nibbled on " -#define LOC_DEATH_SHOTGUN_2B "'s muffler" -#define LOC_DEATH_SHOTGUN_QA " was put six feet under by " -#define LOC_DEATH_SHOTGUN_QB "" - -#define LOC_DEATH_SUPER_SHOTGUN_1A " was blasted by " -#define LOC_DEATH_SUPER_SHOTGUN_1B "" -#define LOC_DEATH_SUPER_SHOTGUN_2A " was shredded by " -#define LOC_DEATH_SUPER_SHOTGUN_2B "" -#define LOC_DEATH_SUPER_SHOTGUN_QA " was sent home in a box by " -#define LOC_DEATH_SUPER_SHOTGUN_QB "" - -#define LOC_DEATH_NAILGUN_1A " was pierced by " -#define LOC_DEATH_NAILGUN_1B "" -#define LOC_DEATH_NAILGUN_2A " was filled with holes by " -#define LOC_DEATH_NAILGUN_2B "" -#define LOC_DEATH_NAILGUN_QA "'s mortal coil was shuffled off by " -#define LOC_DEATH_NAILGUN_QB "" - -#define LOC_DEATH_SUPER_NAILGUN_1A " was perforated by " -#define LOC_DEATH_SUPER_NAILGUN_1B "" -#define LOC_DEATH_SUPER_NAILGUN_2A " was given speed holes by " -#define LOC_DEATH_SUPER_NAILGUN_2B "" -#define LOC_DEATH_SUPER_NAILGUN_QA "'s chips were cashed by " -#define LOC_DEATH_SUPER_NAILGUN_QB "" +#define LOC_DEATH_AXE_1A " was hacked to death by " +#define LOC_DEATH_AXE_1B "" +#define LOC_DEATH_AXE_2A " was chopped to bits by " +#define LOC_DEATH_AXE_2B "" +#define LOC_DEATH_AXE_QA "'s bucket was kicked by " +#define LOC_DEATH_AXE_QB "" + +#define LOC_DEATH_SHOTGUN_1A " sucked on " +#define LOC_DEATH_SHOTGUN_1B "'s muffler" +#define LOC_DEATH_SHOTGUN_2A " nibbled on " +#define LOC_DEATH_SHOTGUN_2B "'s muffler" +#define LOC_DEATH_SHOTGUN_QA " was put six feet under by " +#define LOC_DEATH_SHOTGUN_QB "" + +#define LOC_DEATH_SUPER_SHOTGUN_1A " was blasted by " +#define LOC_DEATH_SUPER_SHOTGUN_1B "" +#define LOC_DEATH_SUPER_SHOTGUN_2A " was shredded by " +#define LOC_DEATH_SUPER_SHOTGUN_2B "" +#define LOC_DEATH_SUPER_SHOTGUN_QA " was sent home in a box by " +#define LOC_DEATH_SUPER_SHOTGUN_QB "" + +#define LOC_DEATH_NAILGUN_1A " was pierced by " +#define LOC_DEATH_NAILGUN_1B "" +#define LOC_DEATH_NAILGUN_2A " was filled with holes by " +#define LOC_DEATH_NAILGUN_2B "" +#define LOC_DEATH_NAILGUN_QA "'s mortal coil was shuffled off by " +#define LOC_DEATH_NAILGUN_QB "" + +#define LOC_DEATH_SUPER_NAILGUN_1A " was perforated by " +#define LOC_DEATH_SUPER_NAILGUN_1B "" +#define LOC_DEATH_SUPER_NAILGUN_2A " was given speed holes by " +#define LOC_DEATH_SUPER_NAILGUN_2B "" +#define LOC_DEATH_SUPER_NAILGUN_QA "'s chips were cashed by " +#define LOC_DEATH_SUPER_NAILGUN_QB "" #define LOC_DEATH_GRENADE_LAUNCHER_1A " tripped over " #define LOC_DEATH_GRENADE_LAUNCHER_1B "'s grenade" @@ -411,80 +431,87 @@ #define LOC_DEATH_ROCKET_LAUNCHER_1A " was blasted by " #define LOC_DEATH_ROCKET_LAUNCHER_1B "'s rocket" -#define LOC_DEATH_ROCKET_LAUNCHER_2A " was shredded by " +#define LOC_DEATH_ROCKET_LAUNCHER_2A " was fulminated by " #define LOC_DEATH_ROCKET_LAUNCHER_2B "'s rocket" #define LOC_DEATH_ROCKET_LAUNCHER_GA " was gibbed by " #define LOC_DEATH_ROCKET_LAUNCHER_GB "'s rocket" -#define LOC_DEATH_ROCKET_LAUNCHER_Q1A " was sent beyond the veil by " -#define LOC_DEATH_ROCKET_LAUNCHER_Q1B "" -#define LOC_DEATH_ROCKET_LAUNCHER_Q2A " was sent beyond the veil by " -#define LOC_DEATH_ROCKET_LAUNCHER_Q2B "" -#define LOC_DEATH_ROCKET_LAUNCHER_Q3A " was sent beyond the veil by " -#define LOC_DEATH_ROCKET_LAUNCHER_Q3B "" - -#define LOC_DEATH_LIGHTNING_1A " was electrocuted by " -#define LOC_DEATH_LIGHTNING_1B "" -#define LOC_DEATH_LIGHTNING_2A " was given electroshock therapy by " -#define LOC_DEATH_LIGHTNING_2B "" -#define LOC_DEATH_LIGHTNING_QA " rode " -#define LOC_DEATH_LIGHTNING_QB "'s white horse" -#define LOC_DEATH_LIGHTNING_D1A " was given a toaster bath by " -#define LOC_DEATH_LIGHTNING_D1B "" -#define LOC_DEATH_LIGHTNING_D2A " was given a toaster bath by " -#define LOC_DEATH_LIGHTNING_D2B "" - -#define LOC_DEATH_TELEFRAG " was telefragged by " - -#define LOC_DEATH_DEFLECT_A "Lucifer's Protection deflects " -#define LOC_DEATH_DEFLECT_B "'s telefrag on " - -#define LOC_TEAMKILL_1 " killed a teammate" -#define LOC_TEAMKILL_2 " friendly-fired" -#define LOC_TEAMKILL_3 " needs an eye exam" -#define LOC_TEAMKILL_4 " betrayed their friend" -#define LOC_TEAMKILL_5 " crushed a teammate" +#define LOC_DEATH_ROCKET_LAUNCHER_Q1A " rode " +#define LOC_DEATH_ROCKET_LAUNCHER_Q1B "'s pale horse" + +#define LOC_DEATH_LIGHTNING_1A " was electrocuted by " +#define LOC_DEATH_LIGHTNING_1B "" +#define LOC_DEATH_LIGHTNING_2A " was given shock treatment by " +#define LOC_DEATH_LIGHTNING_2B "" +#define LOC_DEATH_LIGHTNING_QA " was sent beyond the veil by " +#define LOC_DEATH_LIGHTNING_QB "" +#define LOC_DEATH_LIGHTNING_DA " was given a toaster bath by " +#define LOC_DEATH_LIGHTNING_DB "" + +#define LOC_DEATH_TELEFRAG " was telefragged by " + +#define LOC_DEATH_DEFLECT_A "Lucifer's Protection deflected " +#define LOC_DEATH_DEFLECT_B "'s telefrag on " + +#define LOC_TEAMKILL_1 " killed a teammate" +#define LOC_TEAMKILL_2 " friendly-fired" +#define LOC_TEAMKILL_3 " needs an eye exam" +#define LOC_TEAMKILL_4 " betrayed their friend" +#define LOC_TEAMKILL_SQUISH " crushed a teammate" + +#define LOC_DEATH_KILL " killed " #else -#define LOC_DEATH_AXE_A " was ax-murdered by " -#define LOC_DEATH_AXE_B "" +#define LOC_DEATH_AXE_1A " was ax-murdered by " +#define LOC_DEATH_AXE_1B "" -#define LOC_DEATH_SHOTGUN_A " chewed on " -#define LOC_DEATH_SHOTGUN_B "'s boomstick" +#define LOC_DEATH_SHOTGUN_1A " chewed on " +#define LOC_DEATH_SHOTGUN_1B "'s boomstick" -#define LOC_DEATH_SUPER_SHOTGUN_A " ate 2 loads of " -#define LOC_DEATH_SUPER_SHOTGUN_B "'s buckshot" +#define LOC_DEATH_SUPER_SHOTGUN_1A " ate 2 loads of " +#define LOC_DEATH_SUPER_SHOTGUN_1B "'s buckshot" +#define LOC_DEATH_SUPER_SHOTGUN_QA " ate 8 loads of " +#define LOC_DEATH_SUPER_SHOTGUN_QB "'s buckshot" -#define LOC_DEATH_NAILGUN_A " was nailed by " -#define LOC_DEATH_NAILGUN_B "" +#define LOC_DEATH_NAILGUN_1A " was nailed by " +#define LOC_DEATH_NAILGUN_1B "" -#define LOC_DEATH_SUPER_NAILGUN_A " was punctured by " -#define LOC_DEATH_SUPER_NAILGUN_B "" +#define LOC_DEATH_SUPER_NAILGUN_1A " was punctured by " +#define LOC_DEATH_SUPER_NAILGUN_1B "" #define LOC_DEATH_GRENADE_LAUNCHER_1A " eats " #define LOC_DEATH_GRENADE_LAUNCHER_1B "'s pineapple" -#define LOC_DEATH_GRENADE_LAUNCHER_2A " was gibbed by " -#define LOC_DEATH_GRENADE_LAUNCHER_2B "'s grenade" +#define LOC_DEATH_GRENADE_LAUNCHER_GA " was gibbed by " +#define LOC_DEATH_GRENADE_LAUNCHER_GB "'s grenade" + +#define LOC_DEATH_ROCKET_LAUNCHER_1A " rides " +#define LOC_DEATH_ROCKET_LAUNCHER_1B "'s rocket" +#define LOC_DEATH_ROCKET_LAUNCHER_GA " was gibbed by " +#define LOC_DEATH_ROCKET_LAUNCHER_GB "'s rocket" +#define LOC_DEATH_ROCKET_LAUNCHER_Q1A " was brutalized by " +#define LOC_DEATH_ROCKET_LAUNCHER_Q1B "'s quad rocket" +#define LOC_DEATH_ROCKET_LAUNCHER_Q2A " was smeared by " +#define LOC_DEATH_ROCKET_LAUNCHER_Q2B "'s quad rocket" +#define LOC_DEATH_ROCKET_LAUNCHER_Q3A " rips " +#define LOC_DEATH_ROCKET_LAUNCHER_Q3B " a new one" -#define LOC_DEATH_ROCKET_LAUNCHER_1A " rides " -#define LOC_DEATH_ROCKET_LAUNCHER_1B "'s rocket" -#define LOC_DEATH_ROCKET_LAUNCHER_2A " was gibbed by " -#define LOC_DEATH_ROCKET_LAUNCHER_2B "'s rocket" +#define LOC_DEATH_LIGHTNING_1A " accepts " +#define LOC_DEATH_LIGHTNING_1B "'s shaft" +#define LOC_DEATH_LIGHTNING_DA " accepts " +#define LOC_DEATH_LIGHTNING_DB "'s discharge" -#define LOC_DEATH_LIGHTNING_A " accepts " -#define LOC_DEATH_LIGHTNING_UNDERWATER "'s discharge" -#define LOC_DEATH_LIGHTNING_ONGROUND "'s shaft" +#define LOC_DEATH_TELEFRAG " was telefragged by " -#define LOC_DEATH_TELEFRAG " was telefragged by " +#define LOC_DEATH_DEFLECT_A "Satan's power deflects " +#define LOC_DEATH_DEFLECT_B "'s telefrag on " -#define LOC_DEATH_DEFLECT_A "Satan's power deflects " -#define LOC_DEATH_DEFLECT_B "'s telefrag on " +#define LOC_TEAMKILL_1 " mows down a teammate" +#define LOC_TEAMKILL_2 " checks his glasses" +#define LOC_TEAMKILL_3 " gets a frag for the other team" +#define LOC_TEAMKILL_4 " loses another friend" +#define LOC_TEAMKILL_SQUISH " squished a teammate" -// #define LOC_TEAMKILL_1 " killed a teammate" -// #define LOC_TEAMKILL_2 " friendly-fired" -// #define LOC_TEAMKILL_3 " needs an eye exam" -// #define LOC_TEAMKILL_4 " betrayed their friend" -// #define LOC_TEAMKILL_5 " crushed a teammate" +#define LOC_DEATH_KILL " killed " #endif // __LIBREQUAKE__ @@ -496,7 +523,7 @@ ==============================================================================*/ -#define LOC_LQ_ISDEVELOPER "You must be a developer!" +#define LOC_LQ_ISDEVELOPER "You must be a developer!" /*============================================================================== @@ -504,11 +531,11 @@ ==============================================================================*/ -#define LOC_LQ_CAMERAS_MAX "You have too many cameras!" -#define LOC_LQ_CAMERA_SPAWN_A "Camera placed successfully, " -#define LOC_LQ_CAMERA_SPAWN_B " remaining" -#define LOC_LQ_CAMERA_TIME_A "Time between cameras changed to " -#define LOC_LQ_CAMERA_TIME_B " seconds" -#define LOC_LQ_CAMERA_NONE "Oh noes! No camera found! :(" +#define LOC_LQ_CAMERAS_MAX "You have too many cameras!" +#define LOC_LQ_CAMERA_SPAWN_A "Camera placed successfully, " +#define LOC_LQ_CAMERA_SPAWN_B " remaining" +#define LOC_LQ_CAMERA_TIME_A "Time between cameras changed to " +#define LOC_LQ_CAMERA_TIME_B " seconds" +#define LOC_LQ_CAMERA_NONE "Oh noes! No camera found! :(" #endif // __LIBREQUAKE__ \ No newline at end of file diff --git a/qcsrc/lq1/cutscene_camera.qc b/qcsrc/lq1/cutscene_camera.qc index ce75789ce..39b1b66bc 100644 --- a/qcsrc/lq1/cutscene_camera.qc +++ b/qcsrc/lq1/cutscene_camera.qc @@ -34,14 +34,14 @@ LQ_SpawnCamera void() LQ_SpawnCamera = { if (!cvar("developer")) { - bprint(LOC_LQ_ISDEVELOPER); - bprint("\n"); + bprint(PRINT_HIGH, LOC_LQ_ISDEVELOPER); + bprint(PRINT_HIGH, "\n"); return; } if (cameras_in_world >= LQ_MAXCAMERAS) { - bprint(LOC_LQ_CAMERAS_MAX); - bprint("\n"); + bprint(PRINT_HIGH, LOC_LQ_CAMERAS_MAX); + bprint(PRINT_HIGH, "\n"); return; } @@ -62,10 +62,10 @@ void() LQ_SpawnCamera = cameras_in_world++; - bprint(LOC_LQ_CAMERA_SPAWN_A); - bprint(ftos(LQ_MAXCAMERAS - cameras_in_world)); - bprint(LOC_LQ_CAMERA_SPAWN_B); - bprint("\n"); + bprint(PRINT_HIGH, LOC_LQ_CAMERA_SPAWN_A); + bprint(PRINT_HIGH, ftos(LQ_MAXCAMERAS - cameras_in_world)); + bprint(PRINT_HIGH, LOC_LQ_CAMERA_SPAWN_B); + bprint(PRINT_HIGH, "\n"); }; /* @@ -77,8 +77,8 @@ LQ_AppendCameraTime void(float time_addition) LQ_AppendCameraTime = { if (!cvar("developer")) { - bprint(LOC_LQ_ISDEVELOPER); - bprint("\n"); + bprint(PRINT_HIGH, LOC_LQ_ISDEVELOPER); + bprint(PRINT_HIGH, "\n"); return; } @@ -87,10 +87,10 @@ void(float time_addition) LQ_AppendCameraTime = if (time_between_cameras <= 0) time_between_cameras = 1; - bprint(LOC_LQ_CAMERA_TIME_A); - bprint(ftos(time_between_cameras)); - bprint(LOC_LQ_CAMERA_TIME_B); - bprint("\n"); + bprint(PRINT_HIGH, LOC_LQ_CAMERA_TIME_A); + bprint(PRINT_HIGH, ftos(time_between_cameras)); + bprint(PRINT_HIGH, LOC_LQ_CAMERA_TIME_B); + bprint(PRINT_HIGH, "\n"); }; /* @@ -153,16 +153,16 @@ LQ_PlayCameras void() LQ_PlayCameras = { if (!cvar("developer")) { - bprint(LOC_LQ_ISDEVELOPER); - bprint("\n"); + bprint(PRINT_HIGH, LOC_LQ_ISDEVELOPER); + bprint(PRINT_HIGH, "\n"); return; } entity camera = find(world, targetname, "lq_camera_1"); if (camera == world) { - bprint(LOC_LQ_CAMERA_NONE); - bprint("\n"); + bprint(PRINT_HIGH, LOC_LQ_CAMERA_NONE); + bprint(PRINT_HIGH, "\n"); return; } diff --git a/qcsrc/misc.qc b/qcsrc/misc.qc index 4b8233cd1..1d24b9ec4 100644 --- a/qcsrc/misc.qc +++ b/qcsrc/misc.qc @@ -244,7 +244,7 @@ void() fire_fly = void() fire_touch = { - T_Damage (other, self, self, 200); + T_Damage (other, self, self, 20); remove(self); }; @@ -255,12 +255,22 @@ void() barrel_explode = { self.takedamage = DAMAGE_NO; self.classname = "explo_box"; - T_RadiusDamage (self, self, 160, world); + T_RadiusDamage (self, self, 160, world, ""); +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_EXPLOSION); + WriteCoord (MSG_MULTICAST, self.origin_x); + WriteCoord (MSG_MULTICAST, self.origin_y); + WriteCoord (MSG_MULTICAST, self.origin_z+32); + multicast (self.origin, MULTICAST_PHS); + remove (self); +#else sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM); particle (self.origin, '0 0 0', 75, 255); self.origin_z = self.origin_z + 32; BecomeExplosion (); +#endif }; /*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) @@ -275,6 +285,7 @@ void() misc_explobox = self.movetype = MOVETYPE_NONE; precache_model ("maps/b_explob.bsp"); setmodel (self, "maps/b_explob.bsp"); + setsize (self, '0 0 0', '32 32 64'); precache_sound ("weapons/r_exp3.wav"); self.health = 20; self.th_die = barrel_explode; @@ -312,6 +323,7 @@ void() misc_explobox2 = self.movetype = MOVETYPE_NONE; precache_model2 ("maps/b_exbox2.bsp"); setmodel (self, "maps/b_exbox2.bsp"); + setsize (self, '0 0 0', '32 32 32'); precache_sound ("weapons/r_exp3.wav"); self.health = 20; self.th_die = barrel_explode; @@ -339,7 +351,76 @@ void() misc_explobox2 = float SPAWNFLAG_SUPERSPIKE = 1; float SPAWNFLAG_LASER = 2; -void(vector org, vector vec) LaunchLaser; +void() Laser_Touch = +{ + local vector org; + + if (other == self.owner) + return; // don't explode on owner + + if (pointcontents(self.origin) == CONTENT_SKY) + { + remove(self); + return; + } + + sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); + org = self.origin - 8*normalize(self.velocity); + + if (other.health) + { + SpawnBlood (org, self.velocity*0.2, 15); + other.deathtype = "laser"; + T_Damage (other, self, self.owner, 15); + } + else + { +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_GUNSHOT); + WriteByte (MSG_MULTICAST, 5); + WriteCoord (MSG_MULTICAST, org_x); + WriteCoord (MSG_MULTICAST, org_y); + WriteCoord (MSG_MULTICAST, org_z); + multicast (org, MULTICAST_PVS); +#else + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); +#endif + } + + remove(self); +}; + +void(vector org, vector vec) LaunchLaser = +{ + if (self.classname == "monster_enforcer") + sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM); + + vec = normalize(vec); + + newmis = spawn(); + newmis.classname = "enforcer_laser"; //gnounc + newmis.owner = self; + newmis.movetype = MOVETYPE_FLY; + newmis.solid = SOLID_BBOX; + newmis.effects = EF_DIMLIGHT; + + setmodel (newmis, "progs/laser.mdl"); + setsize (newmis, '0 0 0', '0 0 0'); + + setorigin (newmis, org); + + newmis.velocity = vec * 600; + newmis.angles = vectoangles(newmis.velocity); + + newmis.nextthink = time + 5; + newmis.think = SUB_Remove; + newmis.touch = Laser_Touch; +}; void() spikeshooter_use = { diff --git a/qcsrc/monsters/enforcer.qc b/qcsrc/monsters/enforcer.qc index 2674699f8..7cbf820c4 100644 --- a/qcsrc/monsters/enforcer.qc +++ b/qcsrc/monsters/enforcer.qc @@ -56,68 +56,6 @@ $frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16 $frame paind17 paind18 paind19 -void() Laser_Touch = -{ - local vector org; - - if (other == self.owner) - return; // don't explode on owner - - if (pointcontents(self.origin) == CONTENT_SKY) - { - remove(self); - return; - } - - sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); - org = self.origin - 8*normalize(self.velocity); - - if (other.health) - { - SpawnBlood (org, self.velocity*0.2, 15); - T_Damage (other, self, self.owner, 15); - } - else - { - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_GUNSHOT); - WriteCoord (MSG_BROADCAST, org_x); - WriteCoord (MSG_BROADCAST, org_y); - WriteCoord (MSG_BROADCAST, org_z); - } - - remove(self); -}; - -void(vector org, vector vec) LaunchLaser = -{ - if (self.classname == "monster_enforcer") - sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM); - - vec = normalize(vec); - - newmis = spawn(); - newmis.classname = "enforcer_laser"; //gnounc - newmis.owner = self; - newmis.movetype = MOVETYPE_FLY; - newmis.solid = SOLID_BBOX; - newmis.effects = EF_DIMLIGHT; - - setmodel (newmis, "progs/laser.mdl"); - setsize (newmis, '0 0 0', '0 0 0'); - - setorigin (newmis, org); - - newmis.velocity = vec * 600; - newmis.angles = vectoangles(newmis.velocity); - - newmis.nextthink = time + 5; - newmis.think = SUB_Remove; - newmis.touch = Laser_Touch; -}; - - - void() enforcer_fire = { local vector org; diff --git a/qcsrc/monsters/grunt.qc b/qcsrc/monsters/grunt.qc index e22cebd4d..05b9d0eec 100644 --- a/qcsrc/monsters/grunt.qc +++ b/qcsrc/monsters/grunt.qc @@ -218,7 +218,7 @@ void() army_fire = dir = en.origin - en.velocity*0.2; dir = normalize (dir - self.origin); - FireBullets (4, dir, '0.1 0.1 0'); + FireBullets (4, dir, '0.1 0.1 0', ""); }; diff --git a/qcsrc/monsters/ogre.qc b/qcsrc/monsters/ogre.qc index 934cad71b..0dafaf961 100644 --- a/qcsrc/monsters/ogre.qc +++ b/qcsrc/monsters/ogre.qc @@ -70,7 +70,7 @@ $frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11 void() OgreGrenadeExplode = { - T_RadiusDamage (self, self.owner, 40, world); + T_RadiusDamage (self, self.owner, 40, world, ""); sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM); WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); diff --git a/qcsrc/monsters/spawn.qc b/qcsrc/monsters/spawn.qc index 09b003523..e15de87d5 100644 --- a/qcsrc/monsters/spawn.qc +++ b/qcsrc/monsters/spawn.qc @@ -190,7 +190,7 @@ void() tbaby_jump6 =[ $jump6,tbaby_fly1 ] {}; void() tbaby_die1 =[ $exp, tbaby_die2 ] {self.takedamage = DAMAGE_NO;}; void() tbaby_die2 =[ $exp, tbaby_run1 ] { - T_RadiusDamage (self, self, 120, world); + T_RadiusDamage (self, self, 120, world, ""); sound (self, CHAN_VOICE, "blob/death1.wav", 1, ATTN_NORM); self.origin = self.origin - 8*normalize(self.velocity); diff --git a/qcsrc/monsters/vore.qc b/qcsrc/monsters/vore.qc index 272d1e88d..6578ba8b5 100644 --- a/qcsrc/monsters/vore.qc +++ b/qcsrc/monsters/vore.qc @@ -217,7 +217,7 @@ void() ShalMissileTouch = if (other.classname == "monster_zombie") T_Damage (other, self, self, 110); - T_RadiusDamage (self, self.owner, 40, world); + T_RadiusDamage (self, self.owner, 40, world, ""); sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); diff --git a/qcsrc/plats.qc b/qcsrc/plats.qc index 965791af0..be2ce28a7 100644 --- a/qcsrc/plats.qc +++ b/qcsrc/plats.qc @@ -64,7 +64,7 @@ void() plat_spawn_inside_trigger = void() plat_hit_top = { - sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM); self.state = STATE_TOP; self.think = plat_go_down; self.nextthink = self.ltime + 3; @@ -72,7 +72,7 @@ void() plat_hit_top = void() plat_hit_bottom = { - sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM); + sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise1, 1, ATTN_NORM); self.state = STATE_BOTTOM; }; @@ -252,6 +252,7 @@ void() train_blocked = return; self.attack_finished = time + 0.5; + other.deathtype = "squish"; T_Damage (other, self, self, self.dmg); }; @@ -268,7 +269,7 @@ void() train_wait = if (self.wait) { self.nextthink = self.ltime + self.wait; - sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); + sound (self, CHAN_NO_PHS_ADD+CHAN_VOICE, self.noise, 1, ATTN_NORM); } else diff --git a/qcsrc/player.qc b/qcsrc/player.qc index cbb975d05..9baa99f3a 100644 --- a/qcsrc/player.qc +++ b/qcsrc/player.qc @@ -166,13 +166,18 @@ void() player_run =[ $rockrun1, player_run ] self.walkframe = self.walkframe + 1; }; - -void() player_shot1 = [$shotatt1, player_shot2 ] +void() muzzleflash = { - self.weaponframe=1; +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_MUZZLEFLASH); + WriteEntity (MSG_MULTICAST, self); + multicast (self.origin, MULTICAST_PVS); +#else self.effects = self.effects | EF_MUZZLEFLASH; +#endif }; +void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1;muzzleflash();}; void() player_shot2 = [$shotatt2, player_shot3 ] {self.weaponframe=2;}; void() player_shot3 = [$shotatt3, player_shot4 ] {self.weaponframe=3;}; void() player_shot4 = [$shotatt4, player_shot5 ] {self.weaponframe=4;}; @@ -204,9 +209,9 @@ void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;}; void() player_nail1 =[$nailatt1, player_nail2 ] { - self.effects = self.effects | EF_MUZZLEFLASH; + muzzleflash(); - if (!self.button0) + if (!self.button0 || intermission_running) {player_run ();return;} self.weaponframe = self.weaponframe + 1; @@ -221,9 +226,9 @@ void() player_nail1 =[$nailatt1, player_nail2 ] void() player_nail2 =[$nailatt2, player_nail1 ] { - self.effects = self.effects | EF_MUZZLEFLASH; + muzzleflash(); - if (!self.button0) + if (!self.button0 || intermission_running) {player_run ();return;} self.weaponframe = self.weaponframe + 1; @@ -240,9 +245,9 @@ void() player_nail2 =[$nailatt2, player_nail1 ] void() player_light1 =[$light1, player_light2 ] { - self.effects = self.effects | EF_MUZZLEFLASH; + muzzleflash(); - if (!self.button0) + if (!self.button0 || intermission_running) {player_run ();return;} self.weaponframe = self.weaponframe + 1; @@ -257,9 +262,9 @@ void() player_light1 =[$light1, player_light2 ] void() player_light2 =[$light2, player_light1 ] { - self.effects = self.effects | EF_MUZZLEFLASH; + muzzleflash(); - if (!self.button0) + if (!self.button0 || intermission_running) {player_run ();return;} self.weaponframe = self.weaponframe + 1; @@ -275,12 +280,8 @@ void() player_light2 =[$light2, player_light1 ] //============================================================================ -void() player_rocket1 =[$rockatt1, player_rocket2 ] -{ - self.weaponframe=1; - self.effects = self.effects | EF_MUZZLEFLASH; -}; - +void() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1; + muzzleflash();}; void() player_rocket2 =[$rockatt2, player_rocket3 ] {self.weaponframe=2;}; void() player_rocket3 =[$rockatt3, player_rocket4 ] {self.weaponframe=3;}; void() player_rocket4 =[$rockatt4, player_rocket5 ] {self.weaponframe=4;}; @@ -473,7 +474,10 @@ void() DeathSound = // water death sounds if (self.waterlevel == 3) { - DeathBubbles(20); + if (deathmatch) + DeathBubbles(5); + else + DeathBubbles(20); sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE); return; @@ -512,9 +516,20 @@ vector(float dm) VelocityForDamage = { local vector v; - v_x = 100 * crandom(); - v_y = 100 * crandom(); - v_z = 200 + 100 * random(); + if (deathmatch && vlen(damage_inflictor.velocity)>0) + { + v = 0.5 * damage_inflictor.velocity; + v = v + (25 * normalize(self.origin-damage_inflictor.origin)); + v_z = 100 + 240 * random(); + v_x = v_x + (200 * crandom()); + v_y = v_y + (200 * crandom()); + } + else + { + v_x = 100 * crandom(); + v_y = 100 * crandom(); + v_z = 200 + 100 * random(); + } if (dm > -50) { @@ -600,6 +615,40 @@ void() GibPlayer = void() PlayerDie = { local float i; + local string s; + + if (deathmatch_drop_quad()) { + if (self.super_damage_finished > 0) + { + DropQuad (self.super_damage_finished - time); + bprint (PRINT_LOW, self.netname); + bprint (PRINT_LOW, LOC_ITEM_LOST_A); + if (deathmatch_supermode()) + bprint (PRINT_LOW, LOC_ITEM_NAME_OCTDMG); + else + bprint (PRINT_LOW, LOC_ITEM_NAME_QUADDMG); + bprint (PRINT_LOW, LOC_ITEM_LOST_B); + s = ftos(rint(self.super_damage_finished - time)); + bprint (PRINT_LOW, s); + bprint (PRINT_LOW, LOC_ITEM_LOST_C); + bprint (PRINT_LOW, "\n"); + } + } + + if (deathmatch_drop_ring()) { + if (self.invisible_finished > 0) + { + DropRing (self.invisible_finished - time); + bprint (PRINT_LOW, self.netname); + bprint (PRINT_LOW, LOC_ITEM_LOST_A); + bprint (PRINT_LOW, LOC_ITEM_NAME_SHADRING); + bprint (PRINT_LOW, LOC_ITEM_LOST_B); + s = ftos(rint(self.invisible_finished - time)); + bprint (PRINT_LOW, s); + bprint (PRINT_LOW, LOC_ITEM_LOST_C); + bprint (PRINT_LOW, "\n"); + } + } self.items = self.items - (self.items & IT_INVISIBILITY); self.invisible_finished = 0; // don't die as eyes diff --git a/qcsrc/progs.src b/qcsrc/progs.src index d663e0856..e41108f5b 100644 --- a/qcsrc/progs.src +++ b/qcsrc/progs.src @@ -1,26 +1,50 @@ -../lq1/progs.dat +#ifdef __QW__ +#pragma progs_dat "../lq1/qwprogs.dat" +#else +#pragma progs_dat "../lq1/progs.dat" +#endif + +#includelist defs.qc localized_text.qc // LQ: Localized strings, also applies to Quake +deathmatch_settings.qc subs.qc + +#ifdef __QW__ +server.qc +#endif + +#ifndef __QW__ fight.qc ai.qc -combat.qc - lq1/cutscene_camera.qc // LQ: svc_cutscene firing camera +#endif + +combat.qc items.qc weapons.qc world.qc client.qc + +#ifdef __QW__ +spectate.qc +#endif + player.qc + +#ifndef __QW__ monsters.qc +#endif + doors.qc buttons.qc triggers.qc plats.qc misc.qc +#ifndef __QW__ monsters/ogre.qc monsters/fiend.qc monsters/shambler.qc @@ -37,3 +61,6 @@ monsters/rotfish.qc // registered monsters/vore.qc // registered monsters/enforcer.qc // registered monsters/shub.qc // registered +#endif + +#endlist \ No newline at end of file diff --git a/qcsrc/server.qc b/qcsrc/server.qc new file mode 100644 index 000000000..d549f3933 --- /dev/null +++ b/qcsrc/server.qc @@ -0,0 +1,120 @@ +/* Copyright (C) 1996-1997 Id Software, Inc. + + 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() monster_ogre = {remove(self);}; +void() monster_demon1 = {remove(self);}; +void() monster_shambler = {remove(self);}; +void() monster_knight = {remove(self);}; +void() monster_army = {remove(self);}; +void() monster_wizard = {remove(self);}; +void() monster_dog = {remove(self);}; +void() monster_zombie = {remove(self);}; +void() monster_boss = {remove(self);}; +void() monster_tarbaby = {remove(self);}; +void() monster_hell_knight = {remove(self);}; +void() monster_fish = {remove(self);}; +void() monster_shalrath = {remove(self);}; +void() monster_enforcer = {remove(self);}; +void() monster_oldone = {remove(self);}; +void() event_lightning = {remove(self);}; + +/* +============================================================================== + +MOVETARGET CODE + +The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which allways heads to the next target. + +targetname +must be present. The name of this movetarget. + +target +the next spot to move to. If not present, stop here for good. + +pausetime +The number of seconds to spend standing or bowing for path_stand or path_bow + +============================================================================== +*/ + +/* +============= +t_movetarget + +Something has bumped into a movetarget. If it is a monster +moving towards it, change the next destination and continue. +============== +*/ +void() t_movetarget = +{ +local entity temp; + + if (other.movetarget != self) + return; + + if (other.enemy) + return; // fighting, not following a path + + temp = self; + self = other; + other = temp; + +//dprint ("t_movetarget\n"); + self.goalentity = self.movetarget = find (world, targetname, other.target); + self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin); + if (!self.movetarget) + { + self.pausetime = time + 999999; + self.th_stand (); + return; + } +}; + + + +void() movetarget_f = +{ + if (!self.targetname) + objerror ("monster_movetarget: no targetname"); + + self.solid = SOLID_TRIGGER; + self.touch = t_movetarget; + setsize (self, '-8 -8 -8', '8 8 8'); + +}; + +/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8) +Monsters will continue walking towards the next target corner. +*/ +void() path_corner = +{ + movetarget_f (); +}; + + + +//============================================================================ + +// Empty versions of functions that are referenced but not needed +void() monster_death_use = {}; +void() FoundTarget = {}; +float(entity targ) visible = { return FALSE; }; diff --git a/qcsrc/spectate.qc b/qcsrc/spectate.qc new file mode 100644 index 000000000..e40b61151 --- /dev/null +++ b/qcsrc/spectate.qc @@ -0,0 +1,104 @@ +/* Copyright (C) 1996-1997 Id Software, Inc. + + 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 + +*/ +// Added Aug11'97 by Zoid +// +// These functions are called from the server if they exist. +// Note that Spectators only have one think since they movement code doesn't +// track them much. Impulse commands work as usual, but don't call +// the regular ImpulseCommand handler in weapons.qc since Spectators don't +// have any weapons and things can explode. +// +// --- Zoid. + +/* +=========== +SpectatorConnect + +called when a spectator connects to a server +============ +*/ +void() SpectatorConnect = +{ + bprint (PRINT_MEDIUM, "Spectator "); + bprint (PRINT_MEDIUM, self.netname); + bprint (PRINT_MEDIUM, " entered the game\n"); + + self.goalentity = world; // used for impulse 1 below +}; + +/* +=========== +SpectatorDisconnect + +called when a spectator disconnects from a server +============ +*/ +void() SpectatorDisconnect = +{ + bprint (PRINT_MEDIUM, "Spectator "); + bprint (PRINT_MEDIUM, self.netname); + bprint (PRINT_MEDIUM, " left the game\n"); +}; + +/* +================ +SpectatorImpulseCommand + +Called by SpectatorThink if the spectator entered an impulse +================ +*/ +void() SpectatorImpulseCommand = +{ + if (self.impulse == 1) { + // teleport the spectator to the next spawn point + // note that if the spectator is tracking, this doesn't do + // much + self.goalentity = find(self.goalentity, classname, "info_player_deathmatch"); + if (self.goalentity == world) + self.goalentity = find(self.goalentity, classname, "info_player_deathmatch"); + if (self.goalentity != world) { + setorigin(self, self.goalentity.origin); + self.angles = self.goalentity.angles; + self.fixangle = TRUE; // turn this way immediately + } + } + + self.impulse = 0; +}; + +/* +================ +SpectatorThink + +Called every frame after physics are run +================ +*/ +void() SpectatorThink = +{ + // self.origin, etc contains spectator position, so you could + // do some neat stuff here + + if (self.impulse) + SpectatorImpulseCommand(); +}; + + diff --git a/qcsrc/subs.qc b/qcsrc/subs.qc index 420dfae59..841b82456 100644 --- a/qcsrc/subs.qc +++ b/qcsrc/subs.qc @@ -20,6 +20,24 @@ void() SUB_Remove = {remove(self);}; void() SUB_Null = {}; +//pitch (angles_x) is inverted in quake due to a bug + //use makevectors2 for monsters with nonzero pitch +//anyone encountering this comment with a better understanding should update the comment to be more informative and useful to modders --gnounc +void(vector ang) makevectors2 = +{ + ang_x = ang_x * -1; + makevectors(ang); +}; + +float(float v) anglemod = +{ + while (v >= 360) + v = v - 360; + while (v < 0) + v = v + 360; + return v; +}; + /*QuakeEd only writes a single float for angles (bad idea), so up and down are just constant angles.*/ @@ -310,6 +328,7 @@ void() SUB_UseTargets = }; + /*in nightmare mode, all attack_finished times become 0 some monsters refire twice automatically*/ @@ -321,6 +340,7 @@ void(float normal) SUB_AttackFinished = self.attack_finished = time + normal; }; + float (entity targ) visible; void (void() thinkst) SUB_CheckRefire = diff --git a/qcsrc/triggers.qc b/qcsrc/triggers.qc index f857103e1..894a76d72 100644 --- a/qcsrc/triggers.qc +++ b/qcsrc/triggers.qc @@ -340,35 +340,56 @@ void(vector org) spawn_tfog = s.nextthink = time + 0.2; s.think = play_teleport; +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_TELEPORT); + WriteCoord (MSG_MULTICAST, org_x); + WriteCoord (MSG_MULTICAST, org_y); + WriteCoord (MSG_MULTICAST, org_z); + multicast (org, MULTICAST_PHS); +#else WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_TELEPORT); WriteCoord (MSG_BROADCAST, org_x); WriteCoord (MSG_BROADCAST, org_y); WriteCoord (MSG_BROADCAST, org_z); +#endif }; void() tdeath_touch = { + local entity other2; + if (other == self.owner) return; +// frag anyone who teleports in on top of an invincible player if (other.classname == "player") { - if (other.invincible_finished > time) { - // frag anyone who teleports in on top of an invincible player + if (other.invincible_finished > time && + self.owner.invincible_finished > time) { + self.classname = "teledeath3"; + other.invincible_finished = 0; + self.owner.invincible_finished = 0; + T_Damage (other, self, self, 50000); + other2 = self.owner; + self.owner = other; + T_Damage (other2, self, self, 50000); + } + else if (other.invincible_finished > time) + { self.classname = "teledeath2"; - self.enemy = other; - T_Damage (self.owner, self, self, 50000); + other2 = self.owner; + self.owner = other; + T_Damage (other2, self, self, 50000); return; } - - if (self.owner.classname != "player") + else if (self.owner.classname != "player") { // monsters explode themselves T_Damage (self.owner, self, self, 50000); return; } - } if (other.health) @@ -531,6 +552,11 @@ Only used on start map. */ void() trigger_setskill = { + if (deathmatch) { + remove (self); + return; + } + InitTrigger (); self.touch = trigger_skill_touch; }; diff --git a/qcsrc/weapons.qc b/qcsrc/weapons.qc index 490e9a545..24754264b 100644 --- a/qcsrc/weapons.qc +++ b/qcsrc/weapons.qc @@ -19,7 +19,7 @@ void (entity targ, entity inflictor, entity attacker, float damage) T_Damage; void () player_run; -void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage; +void(entity bomb, entity attacker, float rad, entity ignore, string dtype) T_RadiusDamage; void(vector org, vector vel, float damage) SpawnBlood; void() SuperDamageSound; @@ -46,46 +46,6 @@ float() crandom = return 2*(random() - 0.5); }; -/* -================ -W_FireAxe -================ -*/ -void() W_FireAxe = -{ - local vector source; - local vector org; - - makevectors (self.v_angle); - source = self.origin + '0 0 22'; - traceline (source, source + v_forward*64, FALSE, self); - if (trace_fraction == 1.0) - return; - - org = trace_endpos - v_forward*4; - - if (trace_ent.takedamage) - { - trace_ent.axhitme = 1; - SpawnBlood (org, '0 0 0', 20); - T_Damage (trace_ent, self, self, 20); - } - - else - { // hit wall - sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_GUNSHOT); - WriteCoord (MSG_BROADCAST, org_x); - WriteCoord (MSG_BROADCAST, org_y); - WriteCoord (MSG_BROADCAST, org_z); - } -}; - - -//============================================================================ - - vector() wall_velocity = { local vector vel; @@ -98,7 +58,6 @@ vector() wall_velocity = return vel; }; - /* ================ SpawnMeatSpray @@ -136,9 +95,43 @@ SpawnBlood */ void(vector org, vector vel, float damage) SpawnBlood = { +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_BLOOD); + WriteByte (MSG_MULTICAST, 1); + WriteCoord (MSG_MULTICAST, org_x); + WriteCoord (MSG_MULTICAST, org_y); + WriteCoord (MSG_MULTICAST, org_z); + multicast (org, MULTICAST_PVS); +#else particle (org, vel*0.1, 73, damage*2); +#endif }; +/* +================ +SpawnPuff +================ +*/ +void(vector org, float count) SpawnPuff = +{ +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_GUNSHOT); + WriteByte (MSG_MULTICAST, count); + WriteCoord (MSG_MULTICAST, org_x); + WriteCoord (MSG_MULTICAST, org_y); + WriteCoord (MSG_MULTICAST, org_z); + multicast (org, MULTICAST_PVS); +#else + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); +#endif +} + /* ================ spawn_touchblood @@ -152,15 +145,58 @@ void(float damage) spawn_touchblood = SpawnBlood (self.origin + vel*0.01, vel, damage); }; +void() SmallKick = { +#ifdef __QW__ // Differences in engine protocols + msg_entity = self; + WriteByte (MSG_ONE, SVC_SMALLKICK); +#else + self.punchangle_x = -2; +#endif +}; + +void() BigKick = { +#ifdef __QW__ // Differences in engine protocols + msg_entity = self; + WriteByte (MSG_ONE, SVC_BIGKICK); +#else + self.punchangle_x = -4; +#endif +}; /* ================ -SpawnChunk +W_FireAxe ================ */ -void(vector org, vector vel) SpawnChunk = +void() W_FireAxe = { - particle (org, vel*0.02, 0, 10); + local vector source; + local vector org; + + makevectors (self.v_angle); + source = self.origin + '0 0 22'; + traceline (source, source + v_forward*64, FALSE, self); + if (trace_fraction == 1.0) + return; + + org = trace_endpos - v_forward*4; + + if (trace_ent.takedamage) + { + trace_ent.axhitme = 1; + SpawnBlood (org, '0 0 0', 20); + trace_ent.deathtype = "axe"; + if (deathmatch_buffed_axe()) + T_Damage (trace_ent, self, self, 75); + else + T_Damage (trace_ent, self, self, 20); + } + + else + { // hit wall + sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); + SpawnPuff(org, 3); + } }; /* @@ -218,7 +254,7 @@ BULLETS TraceAttack ================ */ -void(float damage, vector dir) TraceAttack = +void(float damage, vector dir, string dtype) TraceAttack = { local vector vel, org; @@ -229,18 +265,17 @@ void(float damage, vector dir) TraceAttack = org = trace_endpos - dir*4; if (trace_ent.takedamage) - { + { + SpawnBlood (org, vel*0.2, damage); + + trace_ent.deathtype = dtype; AddMultiDamage (trace_ent, damage); } else { - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_GUNSHOT); - WriteCoord (MSG_BROADCAST, org_x); - WriteCoord (MSG_BROADCAST, org_y); - WriteCoord (MSG_BROADCAST, org_z); + SpawnPuff(org, 1); } }; @@ -252,7 +287,7 @@ Used by shotgun, super shotgun, and enemy soldier firing Go to the trouble of combining multiple pellets into a single damage call. ================ */ -void(float shotcount, vector dir, vector spread) FireBullets = +void(float shotcount, vector dir, vector spread, string dtype) FireBullets = { local vector direction; local vector src; @@ -262,13 +297,14 @@ void(float shotcount, vector dir, vector spread) FireBullets = src = self.origin + v_forward*10 + '0 0 22'; ClearMultiDamage (); + while (shotcount > 0) { direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up; traceline (src, src + direction*2048, FALSE, self); if (trace_fraction != 1.0) - TraceAttack (4, direction); + TraceAttack (4, direction, dtype); shotcount = shotcount - 1; } @@ -286,11 +322,13 @@ void() W_FireShotgun = sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM); - self.punchangle_x = -2; - - self.currentammo = self.ammo_shells = self.ammo_shells - 1; + SmallKick(); + + if (!deathmatch_unlimited_ammo()) + self.currentammo = self.ammo_shells = self.ammo_shells - 1; + dir = aim (self, 100000); - FireBullets (6, dir, '0.04 0.04 0'); + FireBullets (6, dir, '0.04 0.04 0', "shotgun"); }; @@ -311,11 +349,13 @@ void() W_FireSuperShotgun = sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); - self.punchangle_x = -4; + BigKick(); + + if (!deathmatch_unlimited_ammo()) + self.currentammo = self.ammo_shells = self.ammo_shells - 2; - self.currentammo = self.ammo_shells = self.ammo_shells - 2; dir = aim (self, 100000); - FireBullets (14, dir, '0.14 0.08 0'); + FireBullets (14, dir, '0.14 0.08 0', "supershotgun"); }; @@ -327,6 +367,7 @@ ROCKETS ============================================================================== */ +#ifndef __QW__ // Unused by QW code void() s_explode1 = [0, s_explode2] {}; void() s_explode2 = [1, s_explode3] {}; void() s_explode3 = [2, s_explode4] {}; @@ -343,6 +384,29 @@ void() BecomeExplosion = self.solid = SOLID_NOT; s_explode1 (); }; +#endif + +void() MissileExplode = +{ +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_EXPLOSION); + WriteCoord (MSG_MULTICAST, self.origin_x); + WriteCoord (MSG_MULTICAST, self.origin_y); + WriteCoord (MSG_MULTICAST, self.origin_z); + multicast (self.origin, MULTICAST_PHS); + + remove(self); +#else + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_EXPLOSION); + WriteCoord (MSG_BROADCAST, self.origin_x); + WriteCoord (MSG_BROADCAST, self.origin_y); + WriteCoord (MSG_BROADCAST, self.origin_z); + + BecomeExplosion (); +#endif +}; void() T_MissileTouch = { @@ -350,6 +414,11 @@ void() T_MissileTouch = if (other == self.owner) return; // don't explode on owner + + if (self.voided) { + return; + } + self.voided = 1; if (pointcontents(self.origin) == CONTENT_SKY) { @@ -361,24 +430,19 @@ void() T_MissileTouch = if (other.health) { + other.deathtype = "rocket"; if (other.classname == "monster_shambler") damg = damg * 0.5; // mostly immune - T_Damage (other, self, self.owner, damg ); + T_Damage (other, self, self.owner, damg); } // don't do radius damage to the other, because all the damage // was done in the impact - T_RadiusDamage (self, self.owner, 120, other); + T_RadiusDamage (self, self.owner, 120, other, "rocket"); self.origin = self.origin - 8*normalize(self.velocity); - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_EXPLOSION); - WriteCoord (MSG_BROADCAST, self.origin_x); - WriteCoord (MSG_BROADCAST, self.origin_y); - WriteCoord (MSG_BROADCAST, self.origin_z); - - BecomeExplosion (); + MissileExplode(); }; @@ -390,35 +454,35 @@ W_FireRocket */ void() W_FireRocket = { - local entity missile; - - self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; + if (!deathmatch_unlimited_ammo()) + self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM); - self.punchangle_x = -2; + SmallKick(); - missile = spawn (); - missile.owner = self; - missile.movetype = MOVETYPE_FLYMISSILE; - missile.solid = SOLID_BBOX; - missile.classname = "missile"; + newmis = spawn (); + newmis.owner = self; + newmis.movetype = MOVETYPE_FLYMISSILE; + newmis.solid = SOLID_BBOX; // set missile speed makevectors (self.v_angle); - missile.velocity = aim(self, 1000); - missile.velocity = missile.velocity * 1000; - missile.angles = vectoangles(missile.velocity); + newmis.velocity = aim(self, 1000); + newmis.velocity = newmis.velocity * 1000; + newmis.angles = vectoangles(newmis.velocity); - missile.touch = T_MissileTouch; + newmis.touch = T_MissileTouch; + newmis.voided = 0; // set missile duration - missile.nextthink = time + 5; - missile.think = SUB_Remove; + newmis.nextthink = time + 5; + newmis.think = SUB_Remove; + newmis.classname = "rocket"; - setmodel (missile, "progs/missile.mdl"); - setsize (missile, '0 0 0', '0 0 0'); - setorigin (missile, self.origin + v_forward*8 + '0 0 16'); + setmodel (newmis, "progs/missile.mdl"); + setsize (newmis, '0 0 0', '0 0 0'); + setorigin (newmis, self.origin + v_forward*8 + '0 0 16'); }; /* @@ -429,6 +493,23 @@ LIGHTNING =============================================================================== */ +void(entity from, float damage) LightningHit = +{ +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_LIGHTNINGBLOOD); + WriteCoord (MSG_MULTICAST, trace_endpos_x); + WriteCoord (MSG_MULTICAST, trace_endpos_y); + WriteCoord (MSG_MULTICAST, trace_endpos_z); + multicast (trace_endpos, MULTICAST_PVS); +#else + particle (trace_endpos, '0 0 100', 15, damage*4); +#endif + + trace_ent.deathtype = "lightning"; + T_Damage (trace_ent, from, from, damage); +}; + /* ================= LightningDamage @@ -439,7 +520,6 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage = local entity e1, e2; local vector f; -#define LIGHTNINGFIX #ifdef LIGHTNINGFIX local float tmp; f = p2 - p1; @@ -463,8 +543,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage = traceline (p1, p2, FALSE, self); if (trace_ent.takedamage) { - particle (trace_endpos, '0 0 100', 15, damage*4); - T_Damage (trace_ent, from, from, damage); + LightningHit (from, damage); if (self.classname == "player") { if (other.classname == "player") @@ -477,8 +556,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage = traceline (p1 + f, p2 + f, FALSE, self); if (trace_ent != e1 && trace_ent.takedamage) { - particle (trace_endpos, '0 0 100', 15, damage*4); - T_Damage (trace_ent, from, from, damage); + LightningHit (from, damage); } e2 = trace_ent; @@ -486,8 +564,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage = traceline (p1 - f, p2 - f, FALSE, self); if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage) { - particle (trace_endpos, '0 0 100', 15, damage*4); - T_Damage (trace_ent, from, from, damage); + LightningHit (from, damage); } }; @@ -495,7 +572,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage = void() W_FireLightning = { local vector org; - local float cells; + local float cells; if (self.ammo_cells < 1) { @@ -507,11 +584,19 @@ void() W_FireLightning = // explode if under water if (self.waterlevel > 1) { - cells = self.ammo_cells; - self.ammo_cells = 0; - W_SetCurrentAmmo (); - T_RadiusDamage (self, self, 35*cells, world); - return; + if (deathmatch_supermode() || deathmatch_supermode2()) + { + self.deathtype = "selfwater"; + T_Damage (self, self, self.owner, 4000); + } + else + { + cells = self.ammo_cells; + self.ammo_cells = 0; + W_SetCurrentAmmo (); + T_RadiusDamage (self, self, 35*cells, world, "discharge"); + return; + } } if (self.t_width < time) @@ -520,12 +605,27 @@ void() W_FireLightning = self.t_width = time + 0.6; } - self.punchangle_x = -2; - self.currentammo = self.ammo_cells = self.ammo_cells - 1; + SmallKick(); + + if (!deathmatch_unlimited_ammo()) + self.currentammo = self.ammo_cells = self.ammo_cells - 1; + org = self.origin + '0 0 16'; traceline (org, org + v_forward*600, TRUE, self); +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_LIGHTNING2); + WriteEntity (MSG_MULTICAST, self); + WriteCoord (MSG_MULTICAST, org_x); + WriteCoord (MSG_MULTICAST, org_y); + WriteCoord (MSG_MULTICAST, org_z); + WriteCoord (MSG_MULTICAST, trace_endpos_x); + WriteCoord (MSG_MULTICAST, trace_endpos_y); + WriteCoord (MSG_MULTICAST, trace_endpos_z); + multicast (org, MULTICAST_PHS); +#else WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_LIGHTNING2); WriteEntity (MSG_BROADCAST, self); @@ -535,6 +635,7 @@ void() W_FireLightning = WriteCoord (MSG_BROADCAST, trace_endpos_x); WriteCoord (MSG_BROADCAST, trace_endpos_y); WriteCoord (MSG_BROADCAST, trace_endpos_z); +#endif LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30); }; @@ -545,15 +646,14 @@ void() W_FireLightning = void() GrenadeExplode = { - T_RadiusDamage (self, self.owner, 120, world); + if (self.voided) { + return; + } + self.voided = 1; - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_EXPLOSION); - WriteCoord (MSG_BROADCAST, self.origin_x); - WriteCoord (MSG_BROADCAST, self.origin_y); - WriteCoord (MSG_BROADCAST, self.origin_z); + T_RadiusDamage (self, self.owner, 120, world, "grenade"); - BecomeExplosion (); + MissileExplode(); }; void() GrenadeTouch = @@ -583,48 +683,47 @@ W_FireGrenade */ void() W_FireGrenade = { - local entity missile; - - self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; + if (!deathmatch_unlimited_ammo()) + self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); - self.punchangle_x = -2; + SmallKick(); - missile = spawn (); - missile.owner = self; - missile.movetype = MOVETYPE_BOUNCE; - missile.solid = SOLID_BBOX; - missile.classname = "grenade"; + newmis = spawn (); + newmis.owner = self; + newmis.movetype = MOVETYPE_BOUNCE; + newmis.solid = SOLID_BBOX; + newmis.classname = "grenade"; // set missile speed makevectors (self.v_angle); if (self.v_angle_x) - missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10; + newmis.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10; else { - missile.velocity = aim(self, 10000); - missile.velocity = missile.velocity * 600; - missile.velocity_z = 200; + newmis.velocity = aim(self, 10000); + newmis.velocity = newmis.velocity * 600; + newmis.velocity_z = 200; } - missile.avelocity = '300 300 300'; + newmis.avelocity = '300 300 300'; - missile.angles = vectoangles(missile.velocity); + newmis.angles = vectoangles(newmis.velocity); - missile.touch = GrenadeTouch; + newmis.touch = GrenadeTouch; // set missile duration - missile.nextthink = time + 2.5; - missile.think = GrenadeExplode; + newmis.nextthink = time + 2.5; + newmis.think = GrenadeExplode; - setmodel (missile, "progs/grenade.mdl"); - setsize (missile, '0 0 0', '0 0 0'); - setorigin (missile, self.origin); + setmodel (newmis, "progs/grenade.mdl"); + setsize (newmis, '0 0 0', '0 0 0'); + setorigin (newmis, self.origin); }; @@ -666,14 +765,18 @@ void() W_FireSuperSpikes = sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM); self.attack_finished = time + 0.2; - self.currentammo = self.ammo_nails = self.ammo_nails - 2; + + if (!deathmatch_unlimited_ammo()) + self.currentammo = self.ammo_nails = self.ammo_nails - 2; + dir = aim (self, 1000); launch_spike (self.origin + '0 0 16', dir); newmis.classname = "super_spike"; //so we know the difference --gnounc newmis.touch = superspike_touch; setmodel (newmis, "progs/s_spike.mdl"); setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); - self.punchangle_x = -2; + + SmallKick(); }; void(float ox) W_FireSpikes = @@ -697,20 +800,30 @@ void(float ox) W_FireSpikes = sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM); self.attack_finished = time + 0.2; - self.currentammo = self.ammo_nails = self.ammo_nails - 1; + + if (!deathmatch_unlimited_ammo()) + self.currentammo = self.ammo_nails = self.ammo_nails - 1; + dir = aim (self, 1000); launch_spike (self.origin + '0 0 16' + v_right*ox, dir); - self.punchangle_x = -2; + SmallKick(); }; void() spike_touch = { + local float te_type; + if (other == self.owner) return; if (other.solid == SOLID_TRIGGER) return; // trigger field, do nothing + + if (self.voided) { + return; + } + self.voided = 1; if (pointcontents(self.origin) == CONTENT_SKY) { @@ -722,25 +835,33 @@ void() spike_touch = if (other.takedamage) { spawn_touchblood (9); + other.deathtype = "nail"; T_Damage (other, self, self.owner, 9); } else { - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - if (self.classname == "wizard_spike") - WriteByte (MSG_BROADCAST, TE_WIZSPIKE); - + te_type = TE_WIZSPIKE; else if (self.classname == "knight_spike") - WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE); - + te_type = TE_KNIGHTSPIKE; else - WriteByte (MSG_BROADCAST, TE_SPIKE); - + te_type = TE_SPIKE; + +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, te_type); + WriteCoord (MSG_MULTICAST, self.origin_x); + WriteCoord (MSG_MULTICAST, self.origin_y); + WriteCoord (MSG_MULTICAST, self.origin_z); + multicast (self.origin, MULTICAST_PHS); +#else + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, te_type); WriteCoord (MSG_BROADCAST, self.origin_x); WriteCoord (MSG_BROADCAST, self.origin_y); WriteCoord (MSG_BROADCAST, self.origin_z); +#endif } remove(self); @@ -754,6 +875,11 @@ void() superspike_touch = if (other.solid == SOLID_TRIGGER) return; // trigger field, do nothing + + if (self.voided) { + return; + } + self.voided = 1; if (pointcontents(self.origin) == CONTENT_SKY) { @@ -765,15 +891,25 @@ void() superspike_touch = if (other.takedamage) { spawn_touchblood (18); + other.deathtype = "supernail"; T_Damage (other, self, self.owner, 18); } else { +#ifdef __QW__ // Differences in engine protocols + WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); + WriteByte (MSG_MULTICAST, TE_SUPERSPIKE); + WriteCoord (MSG_MULTICAST, self.origin_x); + WriteCoord (MSG_MULTICAST, self.origin_y); + WriteCoord (MSG_MULTICAST, self.origin_z); + multicast (self.origin, MULTICAST_PHS); +#else WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_SUPERSPIKE); WriteCoord (MSG_BROADCAST, self.origin_x); WriteCoord (MSG_BROADCAST, self.origin_y); WriteCoord (MSG_BROADCAST, self.origin_z); +#endif } remove(self); @@ -1046,15 +1182,15 @@ void(float wep) W_ChangeWeapon = if (!(self.items & fl)) { // don't have the weapon or the ammo - sprint (self, LOC_WEAPON_INVALID); - sprint (self, "\n"); + sprint (self, PRINT_HIGH, LOC_WEAPON_INVALID); + sprint (self, PRINT_HIGH, "\n"); return; } if (am) { // don't have the ammo - sprint (self, LOC_WEAPON_NOAMMO); - sprint (self, "\n"); + sprint (self, PRINT_HIGH, LOC_WEAPON_NOAMMO); + sprint (self, PRINT_HIGH, "\n"); return; } @@ -1305,12 +1441,14 @@ void() QuadCheat = #define ID_IMPULSE_QUADCHEAT 255 #ifdef __LIBREQUAKE__ +#ifndef __QW__ // Cutscene camera is not used in QW #define LQ_IMPULSE_SPAWNCAM 200 #define LQ_IMPULSE_CAMTIMEINC 201 #define LQ_IMPULSE_CAMTIMEDEC 202 #define LQ_IMPULSE_PLAYCAMERAS 203 +#endif // __QW__ #endif // __LIBREQUAKE__ void() ImpulseCommands = @@ -1329,12 +1467,14 @@ void() ImpulseCommands = case ID_IMPULSE_QUADCHEAT: QuadCheat(); break; #ifdef __LIBREQUAKE__ +#ifndef __QW__ // Cutscene camera is not used in QW case LQ_IMPULSE_SPAWNCAM: LQ_SpawnCamera(); break; case LQ_IMPULSE_CAMTIMEDEC: LQ_AppendCameraTime(5); break; case LQ_IMPULSE_CAMTIMEDEC: LQ_AppendCameraTime(-5); break; case LQ_IMPULSE_PLAYCAMERAS: LQ_PlayCameras(); break; +#endif // __QW__ #endif // __LIBREQUAKE__ default: break; diff --git a/qcsrc/world.qc b/qcsrc/world.qc index 78bae14cd..72b3cfe00 100644 --- a/qcsrc/world.qc +++ b/qcsrc/world.qc @@ -233,6 +233,7 @@ void() worldspawn = precache_sound ("items/damage2.wav"); precache_sound ("items/damage3.wav"); + precache_sound ("misc/power.wav"); //lightning for boss // player gib sounds @@ -256,6 +257,8 @@ void() worldspawn = precache_sound ("player/death4.wav"); precache_sound ("player/death5.wav"); + precache_sound ("boss1/sight1.wav"); + // ax sounds precache_sound ("weapons/ax1.wav"); // ax swoosh precache_sound ("player/axhit1.wav"); // ax hit meat @@ -267,6 +270,11 @@ void() worldspawn = precache_sound ("player/inlava.wav"); // player enter lava precache_sound ("misc/outwater.wav"); // leaving water sound +// Invulnerability sounds + precache_sound ("items/protect.wav"); + precache_sound ("items/protect2.wav"); + precache_sound ("items/protect3.wav"); + precache_sound ("player/lburn1.wav"); // lava burn precache_sound ("player/lburn2.wav"); // lava burn @@ -356,6 +364,9 @@ void() worldspawn = void() StartFrame = { + timelimit = cvar("timelimit") * 60; + fraglimit = cvar("fraglimit"); + deathmatch = cvar("deathmatch"); teamplay = cvar("teamplay"); skill = cvar("skill"); framecount = framecount + 1;