Scientist Hunt: Add some basic logic for the insanity mode. This adds
sh_insanity (cvar). Also fixed some shared Half-Life ish stuff with blood, trigger_hurt entities... too tired to list
This commit is contained in:
parent
5ce957bb20
commit
9ea07752f8
19 changed files with 197 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define CSQC
|
||||
#define CLIENT
|
||||
#define VALVE
|
||||
#define CLASSIC_VGUI
|
||||
|
||||
#includelist
|
||||
../../shared/fteextensions.qc
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -419,5 +419,4 @@ void
|
|||
CBaseMonster::CBaseMonster(void)
|
||||
{
|
||||
CBaseEntity::CBaseEntity();
|
||||
Respawn();
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ CBaseTrigger::InitBrushTrigger(void)
|
|||
{
|
||||
SetModel(m_oldModel);
|
||||
movetype = MOVETYPE_NONE;
|
||||
solid = SOLID_BSPTRIGGER;
|
||||
solid = SOLID_TRIGGER;
|
||||
SetRenderMode(RM_TRIGGER);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -95,5 +95,4 @@ trigger_multiple::trigger_multiple(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
InitBrushTrigger();
|
||||
}
|
||||
|
|
|
@ -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' */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -109,7 +109,7 @@ void
|
|||
monster_alien_controller::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
frame = CON_IDLE;
|
||||
SetFrame(CON_IDLE);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -97,6 +97,8 @@ void monster_scientist_dead::Respawn(void)
|
|||
default:
|
||||
SetFrame(DSCIA_LYING1);
|
||||
}
|
||||
|
||||
droptofloor();
|
||||
}
|
||||
|
||||
void monster_scientist_dead::monster_scientist_dead(void)
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
73
src/shared/scihunt/pmove.c
Normal file
73
src/shared/scihunt/pmove.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* 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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -66,6 +66,7 @@ FX_Impact(int iType, vector vecPos, vector vNormal)
|
|||
}
|
||||
|
||||
switch (iType) {
|
||||
case IMPACT_MELEE:
|
||||
case IMPACT_EXPLOSION:
|
||||
break;
|
||||
case IMPACT_GLASS:
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue