diff --git a/src/client/scihunt/progs.src b/src/client/scihunt/progs.src index 1ee0b796..a1577641 100644 --- a/src/client/scihunt/progs.src +++ b/src/client/scihunt/progs.src @@ -4,6 +4,7 @@ #define CSQC #define CLIENT #define VALVE +#define CLASSIC_VGUI #includelist ../../shared/fteextensions.qc @@ -35,7 +36,7 @@ ../../shared/valve/animations.c ../../shared/scihunt/player.cpp ../player.c -../../shared/valve/pmove.c +../../shared/scihunt/pmove.c ../../shared/pmove.c ../valve/predict.c ../predict.c diff --git a/src/client/tfc/progs.src b/src/client/tfc/progs.src index cb9011b0..2dfe3ae3 100755 --- a/src/client/tfc/progs.src +++ b/src/client/tfc/progs.src @@ -4,6 +4,7 @@ #define CSQC #define CLIENT #define VALVE +#define CLASSIC_VGUI #includelist ../../shared/fteextensions.qc diff --git a/src/gs-entbase/client/worldspawn.cpp b/src/gs-entbase/client/worldspawn.cpp index 2a9add8d..c4bd1787 100644 --- a/src/gs-entbase/client/worldspawn.cpp +++ b/src/gs-entbase/client/worldspawn.cpp @@ -55,6 +55,11 @@ void worldspawn::SpawnKey(string strField, string strKey) g_ambientsound = spawn(env_soundscape); g_ambientsound.m_iShader = Sound_Precache(strKey); break; +#ifdef HHDEATH + case "_bgm": + localcmd(sprintf("music sound/bgm/%s.mp3\n", strKey)); + break; +#endif case "hdr_iris_minvalue": g_flHDRIrisMinValue = stof(strKey); cvar_set("r_hdr_irisadaptation_minvalue", ftos(g_flHDRIrisMinValue)); diff --git a/src/gs-entbase/server/basemonster.cpp b/src/gs-entbase/server/basemonster.cpp index 53d07b34..8ba1e8cb 100644 --- a/src/gs-entbase/server/basemonster.cpp +++ b/src/gs-entbase/server/basemonster.cpp @@ -419,5 +419,4 @@ void CBaseMonster::CBaseMonster(void) { CBaseEntity::CBaseEntity(); - Respawn(); } diff --git a/src/gs-entbase/server/basetrigger.cpp b/src/gs-entbase/server/basetrigger.cpp index 3b0e904f..0fa3496d 100644 --- a/src/gs-entbase/server/basetrigger.cpp +++ b/src/gs-entbase/server/basetrigger.cpp @@ -132,7 +132,7 @@ CBaseTrigger::InitBrushTrigger(void) { SetModel(m_oldModel); movetype = MOVETYPE_NONE; - solid = SOLID_BSPTRIGGER; + solid = SOLID_TRIGGER; SetRenderMode(RM_TRIGGER); } diff --git a/src/gs-entbase/server/trigger_hurt.cpp b/src/gs-entbase/server/trigger_hurt.cpp index ac5ec0e8..c812390c 100644 --- a/src/gs-entbase/server/trigger_hurt.cpp +++ b/src/gs-entbase/server/trigger_hurt.cpp @@ -61,10 +61,8 @@ trigger_hurt::Trigger(void) } else { dprint(sprintf("trigger_hurt::^3Trigger: %s activated\n", m_strTargetName)); - solid = SOLID_BSPTRIGGER; + InitBrushTrigger(); touch = Touch; - setmodel (this, m_oldModel); - self.movetype = MOVETYPE_NONE; } } @@ -118,20 +116,25 @@ void trigger_hurt::Respawn(void) { /* reset */ - m_flNextDmg = 0.5f; m_flNextTrigger = 0.0f; if (spawnflags & SF_HURT_OFF) { solid = SOLID_NOT; - touch = __NULL__; } else { InitBrushTrigger(); + touch = Touch; } } void trigger_hurt::trigger_hurt(void) { + /* defaults */ + m_iDamage = 15; + m_flNextDmg = 0.5f; + + CBaseEntity::CBaseEntity(); + for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { switch (argv(i)) { case "dmg": @@ -146,6 +149,4 @@ trigger_hurt::trigger_hurt(void) break; } } - - CBaseEntity::CBaseEntity(); } diff --git a/src/gs-entbase/server/trigger_multiple.cpp b/src/gs-entbase/server/trigger_multiple.cpp index 4a0e19d0..c584475a 100644 --- a/src/gs-entbase/server/trigger_multiple.cpp +++ b/src/gs-entbase/server/trigger_multiple.cpp @@ -95,5 +95,4 @@ trigger_multiple::trigger_multiple(void) break; } } - InitBrushTrigger(); } diff --git a/src/server/cstrike/hostage_entity.cpp b/src/server/cstrike/hostage_entity.cpp index c324ea45..f0bcac28 100644 --- a/src/server/cstrike/hostage_entity.cpp +++ b/src/server/cstrike/hostage_entity.cpp @@ -151,8 +151,7 @@ hostage_entity::Death(int iHitBody) WarnAllies(); if (style != MONSTER_DEAD) { - frame = HOSA_DIE_SIMPLE + floor(random(0, 6)); - style = MONSTER_DEAD; + SetFrame(HOSA_DIE_SIMPLE + floor(random(0, 6))); } /* now mark our state as 'dead' */ diff --git a/src/server/scihunt/gamerules.cpp b/src/server/scihunt/gamerules.cpp index 226a2dd0..d00553ba 100644 --- a/src/server/scihunt/gamerules.cpp +++ b/src/server/scihunt/gamerules.cpp @@ -14,13 +14,39 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +var int autocvar_sh_insanity = 10; var int autocvar_sv_playerkeepalive = TRUE; void SHMultiplayerRules::PlayerDeath(player pl) { - weaponbox_spawn(pl); + /* obituary networking */ + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EV_OBITUARY); + if (g_dmg_eAttacker.netname) + WriteString(MSG_MULTICAST, g_dmg_eAttacker.netname); + else + WriteString(MSG_MULTICAST, g_dmg_eAttacker.classname); + WriteString(MSG_MULTICAST, pl.netname); + WriteByte(MSG_MULTICAST, g_dmg_iWeapon); + WriteByte(MSG_MULTICAST, 0); + msg_entity = world; + multicast([0,0,0], MULTICAST_ALL); + + /* death-counter */ + pl.deaths++; + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + /* update score-counter */ + if (pl.flags & FL_CLIENT || pl.flags & FL_MONSTER) + if (g_dmg_eAttacker.flags & FL_CLIENT) { + if (pl == g_dmg_eAttacker) + g_dmg_eAttacker.frags--; + else + g_dmg_eAttacker.frags++; + } + pl.movetype = MOVETYPE_NONE; pl.solid = SOLID_NOT; pl.takedamage = DAMAGE_NO; @@ -286,6 +312,17 @@ SHMultiplayerRules::PlayerPostFrame(player pl) pl.old_a_ammo1 = pl.a_ammo1; pl.old_a_ammo2 = pl.a_ammo2; pl.old_a_ammo3 = pl.a_ammo3; + + pl.sh_insaneactive = bound(0.0f, pl.sh_insaneactive - frametime, pl.sh_insaneactive); + + if (pl.sh_insaneactive > 0.0f) + pl.flags |= FL_RESERVED1; + else { + if (pl.flags & FL_RESERVED1) { + bprint(PRINT_CHAT, sprintf("%s is no longer insane!\n", pl.netname)); + } + pl.flags &= ~FL_RESERVED1; + } } void @@ -327,4 +364,42 @@ void SHMultiplayerRules::PlayerKill(player pl) { Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} + +void +SHMultiplayerRules::ScientistKill(player pl, entity sci) +{ + /* obituary networking */ + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EV_OBITUARY); + WriteString(MSG_MULTICAST, pl.netname); + WriteString(MSG_MULTICAST, sci.netname); + WriteByte(MSG_MULTICAST, g_dmg_iWeapon); + WriteByte(MSG_MULTICAST, 0); + msg_entity = world; + multicast([0,0,0], MULTICAST_ALL); + pl.frags++; + + /*if (g_weapons[g_dmg_iWeapon].slot != 0) + return;*/ + + /* if this is our first kill in a while, or in the timer... */ + if (pl.sh_insanecount == 0 || pl.sh_insanetime > time) { + pl.sh_insanecount++; + } else { + pl.sh_insanecount = 0; + } + + if (pl.sh_insanecount >= autocvar_sh_insanity) { + if (pl.sh_insaneactive <= 0.0f) + bprint(PRINT_CHAT, sprintf("%s is going insane!\n", pl.netname)); + + pl.sh_insaneactive += 3.0f; + + if (pl.sh_insaneactive > 60) + pl.sh_insaneactive = 60; + } + + /* timer gets touched every time */ + pl.sh_insanetime = time + 2.0f; } diff --git a/src/server/scihunt/gamerules.h b/src/server/scihunt/gamerules.h index cf27d87c..12f3cc9b 100644 --- a/src/server/scihunt/gamerules.h +++ b/src/server/scihunt/gamerules.h @@ -25,6 +25,7 @@ class SHMultiplayerRules:CGameRules virtual void(player) PlayerKill; virtual void(player) PlayerDeath; virtual void(player) PlayerPostFrame; + virtual void(player, entity) ScientistKill; virtual void(player) LevelDecodeParms; virtual void(player) LevelChangeParms; diff --git a/src/server/scihunt/monster_scientist.cpp b/src/server/scihunt/monster_scientist.cpp index c699828e..a5913071 100644 --- a/src/server/scihunt/monster_scientist.cpp +++ b/src/server/scihunt/monster_scientist.cpp @@ -515,6 +515,14 @@ void monster_scientist::Physics(void) } else { m_iFlags -= (flags & SCIF_FALLING); } + + /* support for think/nextthink */ + if (think && nextthink > 0.0f) { + if (nextthink < time) { + nextthink = 0.0f; + think(); + } + } } void monster_scientist::touch(void) @@ -582,6 +590,11 @@ void monster_scientist::Death(int iHitBody) return; } + SHMultiplayerRules rules = (SHMultiplayerRules)g_grMode; + + if (g_dmg_eAttacker.flags & FL_CLIENT) + rules.ScientistKill((player)g_dmg_eAttacker, (entity)this); + int r; r = floor(random(0,sci_snddie.length)); Speak(sci_snddie[r]); diff --git a/src/server/scihunt/progs.src b/src/server/scihunt/progs.src index d1d2c628..735d0ce0 100755 --- a/src/server/scihunt/progs.src +++ b/src/server/scihunt/progs.src @@ -68,7 +68,7 @@ monster_scientist.cpp ../../shared/valve/fx_spark.c ../valve/player.c -../../shared/valve/pmove.c +../../shared/scihunt/pmove.c ../../shared/pmove.c ../valve/spectator.c ../../shared/scihunt/items.h diff --git a/src/server/valve/monster_alien_controller.cpp b/src/server/valve/monster_alien_controller.cpp index d7cab98d..1c01a206 100644 --- a/src/server/valve/monster_alien_controller.cpp +++ b/src/server/valve/monster_alien_controller.cpp @@ -109,7 +109,7 @@ void monster_alien_controller::Respawn(void) { CBaseMonster::Respawn(); - frame = CON_IDLE; + SetFrame(CON_IDLE); } void diff --git a/src/server/valve/monster_scientist_dead.cpp b/src/server/valve/monster_scientist_dead.cpp index 356dfc40..cd05c283 100644 --- a/src/server/valve/monster_scientist_dead.cpp +++ b/src/server/valve/monster_scientist_dead.cpp @@ -97,6 +97,8 @@ void monster_scientist_dead::Respawn(void) default: SetFrame(DSCIA_LYING1); } + + droptofloor(); } void monster_scientist_dead::monster_scientist_dead(void) diff --git a/src/shared/scihunt/player.cpp b/src/shared/scihunt/player.cpp index 4eb061b6..4d149c3d 100644 --- a/src/shared/scihunt/player.cpp +++ b/src/shared/scihunt/player.cpp @@ -116,5 +116,9 @@ class player:CBaseEntity int old_a_ammo2; int old_a_ammo3; int voted; + + int sh_insanecount; + float sh_insanetime; + float sh_insaneactive; #endif }; diff --git a/src/shared/scihunt/pmove.c b/src/shared/scihunt/pmove.c new file mode 100644 index 00000000..823aa5ea --- /dev/null +++ b/src/shared/scihunt/pmove.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define PHY_JUMP_CHAINWINDOW 0.5 +#define PHY_JUMP_CHAIN 100 +#define PHY_JUMP_CHAINDECAY 50 + +.float waterlevel; +.float watertype; + +float GamePMove_Maxspeed(player target) +{ + if (target.flags & FL_RESERVED1) + return (target.flags & FL_CROUCHING) ? 135 : 500; + else + return (target.flags & FL_CROUCHING) ? 135 : 270; +} + +void GamePMove_Fall(player target, float impactspeed) +{ + if (impactspeed > 580) { +#ifdef SERVER + float fFallDamage = (impactspeed - 580) * (100 / (1024 - 580)); + Damage_Apply(self, world, fFallDamage, 0, DMG_FALL); + Sound_Play(self, CHAN_AUTO, "player.fall"); +#endif + } +} + +void GamePMove_Jump(player target) +{ + float flJumptimeDelta; + float flChainBonus; + + if (target.waterlevel >= 2) { + if (target.watertype == CONTENT_WATER) { + target.velocity[2] = 100; + } else if (target.watertype == CONTENT_SLIME) { + target.velocity[2] = 80; + } else { + target.velocity[2] = 50; + } + } else { + /* Half-Life: Longjump module */ +#ifdef VALVE + if (target.flags & FL_CROUCHING && target.g_items & 0x00008000i) { + target.velocity = v_forward * 512; + target.velocity[2] += 100; + } +#endif + target.velocity[2] += 240; + } + + if (target.jumptime > 0) { + flJumptimeDelta = 0 - (target.jumptime - PHY_JUMP_CHAINWINDOW); + flChainBonus = PHY_JUMP_CHAIN - (((PHY_JUMP_CHAINWINDOW - (PHY_JUMP_CHAINWINDOW - flJumptimeDelta)) * 2) * PHY_JUMP_CHAINDECAY); + target.velocity[2] += flChainBonus; + } + target.jumptime = PHY_JUMP_CHAINWINDOW; +} diff --git a/src/shared/valve/fx_blood.c b/src/shared/valve/fx_blood.c index 446a01c6..66d1c382 100644 --- a/src/shared/valve/fx_blood.c +++ b/src/shared/valve/fx_blood.c @@ -55,7 +55,7 @@ FX_Blood(vector pos, vector color) eBlood.maxframe = modelframecount(eBlood.modelindex); eBlood.loops = 0; eBlood.scale = 1.0f; - eBlood.colormod = color; + eBlood.m_vecRenderColor = color; eBlood.framerate = 20; eBlood.nextthink = time + 0.05f; @@ -69,7 +69,7 @@ FX_Blood(vector pos, vector color) ePart.drawmask = MASK_ENGINE; ePart.maxframe = modelframecount(ePart.modelindex); ePart.loops = 0; - ePart.colormod = color; + ePart.m_vecRenderColor = color; ePart.framerate = 15; ePart.nextthink = time + 0.1f; ePart.velocity = randomvec() * 64; diff --git a/src/shared/valve/fx_impact.c b/src/shared/valve/fx_impact.c index 4a53ba42..c1a7e5ec 100644 --- a/src/shared/valve/fx_impact.c +++ b/src/shared/valve/fx_impact.c @@ -66,6 +66,7 @@ FX_Impact(int iType, vector vecPos, vector vNormal) } switch (iType) { + case IMPACT_MELEE: case IMPACT_EXPLOSION: break; case IMPACT_GLASS: diff --git a/src/shared/valve/w_crowbar.c b/src/shared/valve/w_crowbar.c index 38f3f448..d2c18dd1 100644 --- a/src/shared/valve/w_crowbar.c +++ b/src/shared/valve/w_crowbar.c @@ -101,7 +101,12 @@ w_crowbar_primary(void) Weapons_MakeVectors(); src = pl.origin + pl.view_ofs; + + /* make sure we can gib corpses */ + int oldhitcontents = self.hitcontentsmaski; + self.hitcontentsmaski = CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE; traceline(src, src + (v_forward * 32), FALSE, pl); + self.hitcontentsmaski = oldhitcontents; if (trace_fraction >= 1.0) { pl.w_attack_next = 0.5f;