From c1457896fdc5848e2b154184b9fa3abb42d4e898 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Sat, 2 Mar 2024 00:47:42 -0800 Subject: [PATCH] entity_digitgod: Initial implementation. With Source like I/O for debugging. WEAPON_FISTS: make them work again. WEAPON_SHOTGUN/WEAPON_MACHINEGUN: Spawn decals upon bullet impact. --- src/client/hud_weaponselect.qc | 29 ++-- src/server/entity_digitgod.qc | 190 ++++++++++++++++++++++++- src/server/entity_spritegod.qc | 20 +-- src/server/gamerules_multiplayer.qc | 3 +- src/server/gamerules_singleplayer.qc | 2 +- src/server/hologram_damage.qc | 164 +++++++++++++++++++-- src/server/progs.src | 2 +- src/shared/player.qc | 181 +++++++++++------------ src/shared/w_dml.qc | 2 +- src/shared/w_fists.qc | 61 +++++--- src/shared/w_minigun.qc | 8 +- src/shared/w_shotgun.qc | 2 +- zpak001.pk3dir/cfg/skill_rewolf.cfg | 8 ++ zpak001.pk3dir/def/decore/asteroid.def | 1 + zpak001.pk3dir/def/hologram.def | 1 + zpak001.pk3dir/def/hologram/beak.def | 8 ++ zpak001.pk3dir/def/weapons/fists.def | 8 +- 17 files changed, 524 insertions(+), 166 deletions(-) create mode 100644 zpak001.pk3dir/def/hologram.def create mode 100644 zpak001.pk3dir/def/hologram/beak.def diff --git a/src/client/hud_weaponselect.qc b/src/client/hud_weaponselect.qc index 4583038..935560f 100644 --- a/src/client/hud_weaponselect.qc +++ b/src/client/hud_weaponselect.qc @@ -14,6 +14,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +void View_ForceChange(player pl, int targetWeapon); + vector g_vecHUDNums[6] = { [168 / 256, 72 / 128], @@ -39,9 +41,9 @@ HUD_DrawWeaponSelect_Forward(void) if (pSeat->m_flHUDWeaponSelectTime < time) { pSeat->m_iHUDWeaponSelected = pl.activeweapon; - sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE); + pl.StartSoundDef("Player.WeaponSelectionOpen", CHAN_ITEM, false); } else { - sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE); + pl.StartSoundDef("Player.WeaponSelectionMoveSlot", CHAN_ITEM, false); pSeat->m_iHUDWeaponSelected--; if (pSeat->m_iHUDWeaponSelected <= 0) { pSeat->m_iHUDWeaponSelected = g_weapons.length - 1; @@ -70,9 +72,9 @@ HUD_DrawWeaponSelect_Back(void) if (pSeat->m_flHUDWeaponSelectTime < time) { pSeat->m_iHUDWeaponSelected = pl.activeweapon; - sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE); + pl.StartSoundDef("Player.WeaponSelectionOpen", CHAN_ITEM, false); } else { - sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE); + pl.StartSoundDef("Player.WeaponSelectionMoveSlot", CHAN_ITEM, false); pSeat->m_iHUDWeaponSelected++; if (pSeat->m_iHUDWeaponSelected >= g_weapons.length) { pSeat->m_iHUDWeaponSelected = 1; @@ -90,9 +92,12 @@ void HUD_DrawWeaponSelect_Trigger(void) { player pl = (player)pSeat->m_ePlayer; - pl.activeweapon = pSeat->m_iHUDWeaponSelected; - sendevent("PlayerSwitchWeapon", "i", pSeat->m_iHUDWeaponSelected); - sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_select.wav", 0.5f, ATTN_NONE); + + if (pl.activeweapon != pSeat->m_iHUDWeaponSelected) + View_ForceChange(pl, pSeat->m_iHUDWeaponSelected); + + + pl.StartSoundDef("Player.WeaponSelected", CHAN_ITEM, false); pSeat->m_iHUDWeaponSelected = pSeat->m_flHUDWeaponSelectTime = 0; } @@ -109,7 +114,7 @@ HUD_DrawWeaponSelect_Last(void) void HUD_DrawWeaponSelect_Num(vector vecPos, float fValue) { - drawsubpic(vecPos, [20,20], "sprites/640hud7.spr_0.tga", g_vecHUDNums[fValue], [20/256, 20/128], g_hud_color, 1, DRAWFLAG_ADDITIVE); + drawsubpic(vecPos, [20,20], g_hud7_spr, g_vecHUDNums[fValue], [20/256, 20/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); } int @@ -146,9 +151,9 @@ HUD_SlotSelect(int slot) } if (pSeat->m_flHUDWeaponSelectTime < time) { - sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE); + pl.StartSoundDef("Player.WeaponSelectionOpen", CHAN_ITEM, false); } else { - sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE); + pl.StartSoundDef("Player.WeaponSelectionMoveSlot", CHAN_ITEM, false); } /* weren't in that slot? select the first one then */ @@ -191,7 +196,7 @@ HUD_DrawWeaponSelect(void) } if (pSeat->m_flHUDWeaponSelectTime < time) { if (pSeat->m_iHUDWeaponSelected) { - sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_hudoff.wav", 0.5, ATTN_NONE); + pl.StartSoundDef("Player.WeaponSelectionClose", CHAN_ITEM, false); pSeat->m_iHUDWeaponSelected = 0; } return; @@ -213,7 +218,7 @@ HUD_DrawWeaponSelect(void) if (x == wantpos) { // Selected Sprite Weapons_HUDPic(pl, pSeat->m_iHUDWeaponSelected, 1, vecPos, 1.0f); - drawsubpic(vecPos, [170,45], "sprites/640hud3.spr_0.tga", + drawsubpic(vecPos, [170,45], g_hud3_spr, [0,180/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); vecPos[1] += 50; } else if ((b=HUD_InSlotPos(i, x)) != -1) { diff --git a/src/server/entity_digitgod.qc b/src/server/entity_digitgod.qc index 832b96c..37cf787 100644 --- a/src/server/entity_digitgod.qc +++ b/src/server/entity_digitgod.qc @@ -1,5 +1,187 @@ -class -entity_digitgod:NSEntity -{ +/* + * Copyright (c) 2024 Marco Cawthorne + * + * 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. + */ -}; \ No newline at end of file +/*!QUAKED entity_digitgod (1.0 0.0 0.0) (-32 -32 -16) (32 32 16) +# OVERVIEW +A digital display of numbers, will optionally trigger its targets when hitting a specified number. + +# KEYS +- "targetname" : Name +- "target" : Target when triggered. +- "maxdamage" : Damage to be taken before getting triggered. + +# INPUTS +- "AddToCounter" : Increments the counter by N. +- "SetCounter" : Sets the counter to the desired amount. +- "ResetCounter" : Resets the counter, and will make it able to trigger its target again. + +# NOTES +The hologram_damage entity is specifically made to communicate to it when it is damaged. + +# TRIVIA +This entity was introduced in Gunman Chronicles (2000). +*/ +class +entity_digitgod:NSPointTrigger +{ +public: + void entity_digitgod(void); + + virtual void Input(entity, string, string); + virtual void SpawnKey(string, string); + virtual void Spawned(void); + virtual void Respawn(void); + + nonvirtual void AddToCounter(int); + nonvirtual void SetCounter(int); + nonvirtual void ResetCounter(void); + +private: + int m_iMaxDamage; + int m_iDamageCount; + bool m_bHasFired; + + NSRenderableEntity m_eDigits[3]; + + nonvirtual void _UpdateDigits(void); +}; + +void +entity_digitgod::entity_digitgod(void) +{ + m_bHasFired = false; + m_iDamageCount = 0i; + m_iMaxDamage = 500i; + m_eDigits[0] = m_eDigits[1] = m_eDigits[2] = __NULL__; +} + +void +entity_digitgod::SpawnKey(string keyName, string setValue) +{ + switch (keyName) { + case "maxdamage": + m_iMaxDamage = ReadInt(setValue); + break; + default: + super::SpawnKey(keyName, setValue); + } +} + +void +entity_digitgod::Spawned(void) +{ + super::Spawned(); + + /* allocate our children */ + if (!m_eDigits[0]) { + m_eDigits[0] = spawn(NSRenderableEntity); + m_eDigits[1] = spawn(NSRenderableEntity); + m_eDigits[2] = spawn(NSRenderableEntity); + } +} + +void +entity_digitgod::Input(entity entityActivator, string inputName, string dataField) +{ + switch (inputName) { + case "AddToCounter": + AddToCounter(stoi(dataField)); + break; + case "SetCounter": + SetCounter(stoi(dataField)); + break; + case "ResetCounter": + ResetCounter(); + break; + default: + super::Input(entityActivator, inputName, dataField); + } +} + +void +entity_digitgod::_UpdateDigits(void) +{ + int i = m_iDamageCount; + int d = 2i; + + if (i >= 999) { + m_eDigits[0].SetSkin(9); + m_eDigits[1].SetSkin(9); + m_eDigits[2].SetSkin(9); + } else if (i > 0) { + while (i > 0 && d >= 0) { + m_eDigits[d].SetSkin((float)i % 10.0f); + i = i / 10; + d--; + } + } else { + m_eDigits[0].SetSkin(0); + m_eDigits[1].SetSkin(0); + m_eDigits[2].SetSkin(0); + } + + if (m_bHasFired == true) { + return; + } + + /* Trigger upon completion */ + if (m_iDamageCount >= m_iMaxDamage) { + UseTargets(this, TRIG_TOGGLE, 0.0f); + m_bHasFired = true; + } +} + +void +entity_digitgod::AddToCounter(int newValue) +{ + m_iDamageCount += newValue; + _UpdateDigits(); +} + +void +entity_digitgod::SetCounter(int newValue) +{ + m_iDamageCount = newValue; + _UpdateDigits(); +} + +void +entity_digitgod::ResetCounter(void) +{ + m_iDamageCount = 0i; + _UpdateDigits(); + m_bHasFired = false; +} + +void +entity_digitgod::Respawn(void) +{ + vector digitDir = GetSpawnAngles(); + vector digitPos = GetSpawnOrigin(); + + for (int i = 0i; i < 3; i++) { + m_eDigits[i].SetModel("models/digits.mdl"); + m_eDigits[i].SetRenderMode(RM_FULLBRIGHT); + m_eDigits[i].SetAngles(digitDir); + } + + makevectors(digitDir); + m_eDigits[0].SetOrigin(digitPos + v_right * 16); + m_eDigits[1].SetOrigin(digitPos); + m_eDigits[2].SetOrigin(digitPos + v_right * -16); + + ResetCounter(); +} \ No newline at end of file diff --git a/src/server/entity_spritegod.qc b/src/server/entity_spritegod.qc index 1f16ab5..db9bd00 100644 --- a/src/server/entity_spritegod.qc +++ b/src/server/entity_spritegod.qc @@ -19,16 +19,16 @@ Master entity for emitting a series of sprites. # KEYS -"targetname" : Name -"spritename" : Sprite model to emit -"spritenoise" : Unknown. -"spritestartstate" : Whether to start off (0) or on (1) -"spritecount" : How many sprites to emit per interval -"spritefreq" : Emitting frequency, defaults to 5. -"spritex" : Direction on the X-Axis (?) -"spritey" : Direction on the Y-Axis (?) -"spritez" : Direction on the Z-Axis (?) -"targetent" : Target entity, maybe used for setting the direction alternatively (?) +- "targetname" : Name +- "spritename" : Sprite model to emit +- "spritenoise" : Unknown. +- "spritestartstate" : Whether to start off (0) or on (1) +- "spritecount" : How many sprites to emit per interval +- "spritefreq" : Emitting frequency, defaults to 5. +- "spritex" : Direction on the X-Axis (?) +- "spritey" : Direction on the Y-Axis (?) +- "spritez" : Direction on the Z-Axis (?) +- "targetent" : Target entity, maybe used for setting the direction alternatively (?) # TRIVIA This entity was introduced in Gunman Chronicles (2000). diff --git a/src/server/gamerules_multiplayer.qc b/src/server/gamerules_multiplayer.qc index d3ecd49..e1df4d3 100644 --- a/src/server/gamerules_multiplayer.qc +++ b/src/server/gamerules_multiplayer.qc @@ -116,8 +116,7 @@ HLMultiplayerRules::PlayerDeath(NSClientPlayer pl) pl.gflags &= ~GF_EGONBEAM; pl.armor = pl.activeweapon = pl.g_items = 0; pl.health = 0; - - Sound_Play(pl, CHAN_AUTO, "player.die"); + pl.StartSoundDef("Player.Death", CHAN_AUTO, true); /* force respawn */ pl.think = PutClientInServer; diff --git a/src/server/gamerules_singleplayer.qc b/src/server/gamerules_singleplayer.qc index 3cfb86e..c34d325 100644 --- a/src/server/gamerules_singleplayer.qc +++ b/src/server/gamerules_singleplayer.qc @@ -29,7 +29,7 @@ HLSingleplayerRules::PlayerDeath(NSClientPlayer pl) pl.gflags &= ~GF_FLASHLIGHT; pl.armor = pl.activeweapon = pl.g_items = pl.weapon = 0; pl.health = 0; - Sound_Play(pl, CHAN_AUTO, "player.die"); + pl.StartSoundDef("Player.Death", CHAN_AUTO, true); if (cvar("coop") == 1) { pl.think = PutClientInServer; diff --git a/src/server/hologram_damage.qc b/src/server/hologram_damage.qc index 90a0031..4efdeca 100644 --- a/src/server/hologram_damage.qc +++ b/src/server/hologram_damage.qc @@ -14,22 +14,86 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -class hologram_damage:NSTalkMonster +typedef enum { - int m_iType; + HOLODAMAGE_BEAK = 0, + HOLODAMAGE_TUBE, + HOLODAMAGE_RAPTOR +} holoDamageMonster_t; - void(void) hologram_damage; +typedef enum +{ + HOLOFILTER_GAUSSPULSE = 0, + HOLOFILTER_GAUSSCHARGED, + HOLOFILTER_GAUSSRAPID, + HOLOFILTER_GAUSSSNIPER, + HOLOFILTER_BULLET, + HOLOFILTER_CHEMGUNACID, + HOLOFILTER_CHEMGUNBASE, + HOLOFILTER_CHEMGUNEXPLOSIVE, + HOLOFILTER_CHEMGUNSMOKE, +} holoDamageType_t; - virtual void(void) Respawn; - virtual void(string, string) SpawnKey; +/*!QUAKED hologram_damage (0 0.8 0.8) (-16 -16 0) (16 16 72) +# OVERVIEW +A holographic creature, which will talk to an entity_spritegod when damaged. + +# KEYS +- "targetname" : Name +- "target" : Name of the entity_spritegod to talk to. +- "creaturetype" : Monster id. 0 = Beak, 1 = Tube, 2 = Raptor. +- "damagetype" : Damage type filter. Will only react to the specified type. +- "targetfail" : The entity to trigger when the damage type filter fails. + +# NOTES +Choose one of the following numbers ids (0-8) for `damagetype`: + +0. Gauss Pulse-Shot +1. Gauss Charged-Shot +2. Gauss Rapid-Shot +3. Gauss Sniper-Shot +4. Bullet (Shotgun, Minigun) +5. Chemgun Acid +6. Chemgun Base +7. Chemgun Explosive +8. Chemgun Smoke + +# TRIVIA +This entity was introduced in Gunman Chronicles (2000). +*/ +class +hologram_damage:NSTalkMonster +{ +public: + void hologram_damage(void); + + virtual void SpawnKey(string, string); + virtual void Spawned(void); + virtual void Respawn(void); + virtual void Pain(void); + + nonvirtual void Fail(void); + +private: + string m_strFailName; + holoDamageMonster_t m_dType; + holoDamageType_t m_dDamageType; }; void -hologram_damage::Respawn(void) +hologram_damage::hologram_damage(void) { - SetRenderMode(RM_ADDITIVE); + m_strFailName = __NULL__; + m_dType = HOLODAMAGE_BEAK; + m_dDamageType = HOLOFILTER_BULLET; +} - switch (m_iType) { +void +hologram_damage::Spawned(void) +{ + super::Spawned(); + + switch (m_dType) { case 1: model = "models/tube.mdl"; break; @@ -40,25 +104,95 @@ hologram_damage::Respawn(void) model = "models/beak.mdl"; } - SetModel(model); + precache_model(model); + m_oldModel = model; } void hologram_damage::SpawnKey(string strKey, string strValue) { switch (strKey) { + case "targetfail": + m_strFailName = ReadString(strValue); + break; case "creaturetype": - m_iType = stoi(strValue); + m_dType = ReadFloat(strValue); + break; + case "damagetype": + m_dDamageType = ReadFloat(strValue); break; default: - NSTalkMonster::SpawnKey(strKey, strValue); + super::SpawnKey(strKey, strValue); } } void -hologram_damage::hologram_damage(void) +hologram_damage::Respawn(void) { - base_mins = [-16,-16,0]; - base_maxs = [16,16,72]; - NSTalkMonster::NSTalkMonster(); + super::Respawn(); + + SetModel(GetSpawnModel()); + SetOrigin(GetSpawnOrigin()); + SetSolid(SOLID_CORPSE); + SetMovetype(MOVETYPE_NONE); + SetRenderMode(RM_ADDITIVE); + SetTakedamage(DAMAGE_AIM); + SetHealth(1000); + SetSize([-16,-16,0], [16,16,72]); + DropToFloor(); } + +void +hologram_damage::Fail(void) +{ + string oldTarget = target; + target = m_strFailName; + EntLog("Wrong weapon type, triggering `targetfail` %S", target); + UseTargets(this, TRIG_TOGGLE, 0.0f); + target = oldTarget; +} + +void +hologram_damage::Pain(void) +{ + entity_digitgod digitGod = (entity_digitgod)find(world, ::targetname, target); + + if (!target || !digitGod) { + EntError("entity_digitgod %S not found!", target); + return; + } + + /* TODO: support the weapon modes properly, hah... */ + switch (m_dDamageType) { + case HOLOFILTER_GAUSSPULSE: + case HOLOFILTER_GAUSSCHARGED: + case HOLOFILTER_GAUSSRAPID: + case HOLOFILTER_GAUSSSNIPER: + if (g_dmg_iWeapon != WEAPON_GAUSSPISTOL) { + Fail(); + return; + } + break; + case HOLOFILTER_BULLET: + if (!(g_dmg_iWeapon == WEAPON_SHOTGUN || g_dmg_iWeapon == WEAPON_MINIGUN)) { + Fail(); + return; + } + break; + case HOLOFILTER_CHEMGUNACID: + case HOLOFILTER_CHEMGUNBASE: + case HOLOFILTER_CHEMGUNEXPLOSIVE: + case HOLOFILTER_CHEMGUNSMOKE: + if (g_dmg_iWeapon != WEAPON_GAUSSPISTOL) { + Fail(); + return; + } + break; + default: + return; + } + + EntLog("Hologram informing %S about %i damage taken", target, g_dmg_iRealDamage); + digitGod.AddToCounter(g_dmg_iRealDamage); + SetHealth(1000); +} \ No newline at end of file diff --git a/src/server/progs.src b/src/server/progs.src index 3304b90..b376ae6 100644 --- a/src/server/progs.src +++ b/src/server/progs.src @@ -20,11 +20,11 @@ ../shared/include.src gunman_cycler.qc -hologram_damage.qc decore.qc entity_digitgod.qc +hologram_damage.qc entity_spritegod.qc sphere_explosion.qc player_giveitems.qc diff --git a/src/shared/player.qc b/src/shared/player.qc index b851af4..8e813ac 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -68,6 +68,7 @@ class player:NSClientPlayer PREDICTED_INT(dml_state) virtual void UpdatePlayerAnimation(float); + virtual void Physics_Jump(void); #ifdef CLIENT virtual void UpdatePlayerAttachments(bool); @@ -225,40 +226,40 @@ player::ReceiveEntity(float new, float flChanged) NSClientPlayer::ReceiveEntity(new, flChanged); /* animation */ - READENTITY_BYTE(anim_top, PLAYER_TOPFRAME); - READENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME); - READENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME); + READENTITY_BYTE(anim_top, PLAYER_TOPFRAME) + READENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME) + READENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME) - READENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME); - READENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME); + READENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME) + READENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME) - READENTITY_BYTE(ammo_battery, PLAYER_AMMO1); - READENTITY_BYTE(ammo_chem, PLAYER_AMMO1); - READENTITY_BYTE(ammo_rocket, PLAYER_AMMO1); - READENTITY_BYTE(ammo_gauss, PLAYER_AMMO1); - READENTITY_BYTE(ammo_minigun, PLAYER_AMMO1); - READENTITY_BYTE(ammo_buckshot, PLAYER_AMMO1); - READENTITY_BYTE(fist_mode, PLAYER_AMMO1); - READENTITY_BYTE(gauss_mode, PLAYER_AMMO1); - READENTITY_BYTE(shotgun_shells, PLAYER_AMMO1); - READENTITY_BYTE(shotgun_spread, PLAYER_AMMO1); + READENTITY_BYTE(ammo_battery, PLAYER_AMMO1) + READENTITY_BYTE(ammo_chem, PLAYER_AMMO1) + READENTITY_BYTE(ammo_rocket, PLAYER_AMMO1) + READENTITY_BYTE(ammo_gauss, PLAYER_AMMO1) + READENTITY_BYTE(ammo_minigun, PLAYER_AMMO1) + READENTITY_BYTE(ammo_buckshot, PLAYER_AMMO1) + READENTITY_BYTE(fist_mode, PLAYER_AMMO1) + READENTITY_BYTE(gauss_mode, PLAYER_AMMO1) + READENTITY_BYTE(shotgun_shells, PLAYER_AMMO1) + READENTITY_BYTE(shotgun_spread, PLAYER_AMMO1) - READENTITY_BYTE(dml_launch, PLAYER_AMMO2); - READENTITY_BYTE(dml_flightpath, PLAYER_AMMO2); - READENTITY_BYTE(dml_detonate, PLAYER_AMMO2); - READENTITY_BYTE(dml_payload, PLAYER_AMMO2); - READENTITY_BYTE(chem_acid, PLAYER_AMMO2); - READENTITY_BYTE(chem_neutral, PLAYER_AMMO2); - READENTITY_BYTE(chem_base, PLAYER_AMMO2); - READENTITY_BYTE(chem_pressure, PLAYER_AMMO2); + READENTITY_BYTE(dml_launch, PLAYER_AMMO2) + READENTITY_BYTE(dml_flightpath, PLAYER_AMMO2) + READENTITY_BYTE(dml_detonate, PLAYER_AMMO2) + READENTITY_BYTE(dml_payload, PLAYER_AMMO2) + READENTITY_BYTE(chem_acid, PLAYER_AMMO2) + READENTITY_BYTE(chem_neutral, PLAYER_AMMO2) + READENTITY_BYTE(chem_base, PLAYER_AMMO2) + READENTITY_BYTE(chem_pressure, PLAYER_AMMO2) - READENTITY_BYTE(beam_range, PLAYER_AMMO3); - READENTITY_BYTE(beam_poweracc, PLAYER_AMMO3); - READENTITY_BYTE(beam_lightning, PLAYER_AMMO3); - READENTITY_BYTE(gren_detonate, PLAYER_AMMO3); - READENTITY_BYTE(gren_payload, PLAYER_AMMO3); - READENTITY_BYTE(menu_active, PLAYER_AMMO3); - READENTITY_BYTE(dml_state, PLAYER_AMMO3); + READENTITY_BYTE(beam_range, PLAYER_AMMO3) + READENTITY_BYTE(beam_poweracc, PLAYER_AMMO3) + READENTITY_BYTE(beam_lightning, PLAYER_AMMO3) + READENTITY_BYTE(gren_detonate, PLAYER_AMMO3) + READENTITY_BYTE(gren_payload, PLAYER_AMMO3) + READENTITY_BYTE(menu_active, PLAYER_AMMO3) + READENTITY_BYTE(dml_state, PLAYER_AMMO3) if (flChanged & PLAYER_AMMO1 || flChanged & PLAYER_AMMO2 || flChanged & PLAYER_AMMO3) Weapons_AmmoUpdate(this); @@ -517,40 +518,40 @@ player::EvaluateEntity(void) { NSClientPlayer::EvaluateEntity(); - EVALUATE_FIELD(anim_top, PLAYER_TOPFRAME); - EVALUATE_FIELD(anim_top_time, PLAYER_TOPFRAME); - EVALUATE_FIELD(anim_top_delay, PLAYER_TOPFRAME); + EVALUATE_FIELD(anim_top, PLAYER_TOPFRAME) + EVALUATE_FIELD(anim_top_time, PLAYER_TOPFRAME) + EVALUATE_FIELD(anim_top_delay, PLAYER_TOPFRAME) - EVALUATE_FIELD(anim_bottom, PLAYER_BOTTOMFRAME); - EVALUATE_FIELD(anim_bottom_time, PLAYER_BOTTOMFRAME); + EVALUATE_FIELD(anim_bottom, PLAYER_BOTTOMFRAME) + EVALUATE_FIELD(anim_bottom_time, PLAYER_BOTTOMFRAME) - EVALUATE_FIELD(ammo_battery, PLAYER_AMMO1); - EVALUATE_FIELD(ammo_chem, PLAYER_AMMO1); - EVALUATE_FIELD(ammo_rocket, PLAYER_AMMO1); - EVALUATE_FIELD(ammo_gauss, PLAYER_AMMO1); - EVALUATE_FIELD(ammo_minigun, PLAYER_AMMO1); - EVALUATE_FIELD(ammo_buckshot, PLAYER_AMMO1); - EVALUATE_FIELD(fist_mode, PLAYER_AMMO1); - EVALUATE_FIELD(gauss_mode, PLAYER_AMMO1); - EVALUATE_FIELD(shotgun_shells, PLAYER_AMMO1); - EVALUATE_FIELD(shotgun_spread, PLAYER_AMMO1); + EVALUATE_FIELD(ammo_battery, PLAYER_AMMO1) + EVALUATE_FIELD(ammo_chem, PLAYER_AMMO1) + EVALUATE_FIELD(ammo_rocket, PLAYER_AMMO1) + EVALUATE_FIELD(ammo_gauss, PLAYER_AMMO1) + EVALUATE_FIELD(ammo_minigun, PLAYER_AMMO1) + EVALUATE_FIELD(ammo_buckshot, PLAYER_AMMO1) + EVALUATE_FIELD(fist_mode, PLAYER_AMMO1) + EVALUATE_FIELD(gauss_mode, PLAYER_AMMO1) + EVALUATE_FIELD(shotgun_shells, PLAYER_AMMO1) + EVALUATE_FIELD(shotgun_spread, PLAYER_AMMO1) - EVALUATE_FIELD(dml_launch, PLAYER_AMMO2); - EVALUATE_FIELD(dml_flightpath, PLAYER_AMMO2); - EVALUATE_FIELD(dml_detonate, PLAYER_AMMO2); - EVALUATE_FIELD(dml_payload, PLAYER_AMMO2); - EVALUATE_FIELD(chem_acid, PLAYER_AMMO2); - EVALUATE_FIELD(chem_neutral, PLAYER_AMMO2); - EVALUATE_FIELD(chem_base, PLAYER_AMMO2); - EVALUATE_FIELD(chem_pressure, PLAYER_AMMO2); + EVALUATE_FIELD(dml_launch, PLAYER_AMMO2) + EVALUATE_FIELD(dml_flightpath, PLAYER_AMMO2) + EVALUATE_FIELD(dml_detonate, PLAYER_AMMO2) + EVALUATE_FIELD(dml_payload, PLAYER_AMMO2) + EVALUATE_FIELD(chem_acid, PLAYER_AMMO2) + EVALUATE_FIELD(chem_neutral, PLAYER_AMMO2) + EVALUATE_FIELD(chem_base, PLAYER_AMMO2) + EVALUATE_FIELD(chem_pressure, PLAYER_AMMO2) - EVALUATE_FIELD(beam_range, PLAYER_AMMO3); - EVALUATE_FIELD(beam_poweracc, PLAYER_AMMO3); - EVALUATE_FIELD(beam_lightning, PLAYER_AMMO3); - EVALUATE_FIELD(gren_detonate, PLAYER_AMMO3); - EVALUATE_FIELD(gren_payload, PLAYER_AMMO3); - EVALUATE_FIELD(menu_active, PLAYER_AMMO3); - EVALUATE_FIELD(dml_state, PLAYER_AMMO3); + EVALUATE_FIELD(beam_range, PLAYER_AMMO3) + EVALUATE_FIELD(beam_poweracc, PLAYER_AMMO3) + EVALUATE_FIELD(beam_lightning, PLAYER_AMMO3) + EVALUATE_FIELD(gren_detonate, PLAYER_AMMO3) + EVALUATE_FIELD(gren_payload, PLAYER_AMMO3) + EVALUATE_FIELD(menu_active, PLAYER_AMMO3) + EVALUATE_FIELD(dml_state, PLAYER_AMMO3) } /* @@ -575,40 +576,40 @@ player::SendEntity(entity ePEnt, float flChanged) /* the generic client attributes */ NSClientPlayer::SendEntity(ePEnt, flChanged); - SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME); - SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME); - SENDENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME); + SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME) + SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME) + SENDENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME) - SENDENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME); - SENDENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME); + SENDENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME) + SENDENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME) - SENDENTITY_BYTE(ammo_battery, PLAYER_AMMO1); - SENDENTITY_BYTE(ammo_chem, PLAYER_AMMO1); - SENDENTITY_BYTE(ammo_rocket, PLAYER_AMMO1); - SENDENTITY_BYTE(ammo_gauss, PLAYER_AMMO1); - SENDENTITY_BYTE(ammo_minigun, PLAYER_AMMO1); - SENDENTITY_BYTE(ammo_buckshot, PLAYER_AMMO1); - SENDENTITY_BYTE(fist_mode, PLAYER_AMMO1); - SENDENTITY_BYTE(gauss_mode, PLAYER_AMMO1); - SENDENTITY_BYTE(shotgun_shells, PLAYER_AMMO1); - SENDENTITY_BYTE(shotgun_spread, PLAYER_AMMO1); + SENDENTITY_BYTE(ammo_battery, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_chem, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_rocket, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_gauss, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_minigun, PLAYER_AMMO1) + SENDENTITY_BYTE(ammo_buckshot, PLAYER_AMMO1) + SENDENTITY_BYTE(fist_mode, PLAYER_AMMO1) + SENDENTITY_BYTE(gauss_mode, PLAYER_AMMO1) + SENDENTITY_BYTE(shotgun_shells, PLAYER_AMMO1) + SENDENTITY_BYTE(shotgun_spread, PLAYER_AMMO1) - SENDENTITY_BYTE(dml_launch, PLAYER_AMMO2); - SENDENTITY_BYTE(dml_flightpath, PLAYER_AMMO2); - SENDENTITY_BYTE(dml_detonate, PLAYER_AMMO2); - SENDENTITY_BYTE(dml_payload, PLAYER_AMMO2); - SENDENTITY_BYTE(chem_acid, PLAYER_AMMO2); - SENDENTITY_BYTE(chem_neutral, PLAYER_AMMO2); - SENDENTITY_BYTE(chem_base, PLAYER_AMMO2); - SENDENTITY_BYTE(chem_pressure, PLAYER_AMMO2); + SENDENTITY_BYTE(dml_launch, PLAYER_AMMO2) + SENDENTITY_BYTE(dml_flightpath, PLAYER_AMMO2) + SENDENTITY_BYTE(dml_detonate, PLAYER_AMMO2) + SENDENTITY_BYTE(dml_payload, PLAYER_AMMO2) + SENDENTITY_BYTE(chem_acid, PLAYER_AMMO2) + SENDENTITY_BYTE(chem_neutral, PLAYER_AMMO2) + SENDENTITY_BYTE(chem_base, PLAYER_AMMO2) + SENDENTITY_BYTE(chem_pressure, PLAYER_AMMO2) - SENDENTITY_BYTE(beam_range, PLAYER_AMMO3); - SENDENTITY_BYTE(beam_poweracc, PLAYER_AMMO3); - SENDENTITY_BYTE(beam_lightning, PLAYER_AMMO3); - SENDENTITY_BYTE(gren_detonate, PLAYER_AMMO3); - SENDENTITY_BYTE(gren_payload, PLAYER_AMMO3); - SENDENTITY_BYTE(menu_active, PLAYER_AMMO3); - SENDENTITY_BYTE(dml_state, PLAYER_AMMO3); + SENDENTITY_BYTE(beam_range, PLAYER_AMMO3) + SENDENTITY_BYTE(beam_poweracc, PLAYER_AMMO3) + SENDENTITY_BYTE(beam_lightning, PLAYER_AMMO3) + SENDENTITY_BYTE(gren_detonate, PLAYER_AMMO3) + SENDENTITY_BYTE(gren_payload, PLAYER_AMMO3) + SENDENTITY_BYTE(menu_active, PLAYER_AMMO3) + SENDENTITY_BYTE(dml_state, PLAYER_AMMO3) return (1); } diff --git a/src/shared/w_dml.qc b/src/shared/w_dml.qc index 83e9c1e..4217b5c 100644 --- a/src/shared/w_dml.qc +++ b/src/shared/w_dml.qc @@ -285,7 +285,7 @@ w_dml_hud(player pl) "CLUSTER" }; vector pos; - vector jitter; + vector jitter = g_vec_null; float lerp; /* laser */ diff --git a/src/shared/w_fists.qc b/src/shared/w_fists.qc index 3cecf81..43210b1 100644 --- a/src/shared/w_fists.qc +++ b/src/shared/w_fists.qc @@ -143,34 +143,40 @@ w_fists_release(player pl) void w_fists_primary(player pl) { + vector src; + int finalDamage = 0i; + if (pl.w_attack_next) { return; } + Weapons_MakeVectors(pl); + src = pl.origin + pl.view_ofs; + +#ifdef SERVER + /* make sure we can gib corpses */ + int oldhitcontents = pl.hitcontentsmaski; + pl.hitcontentsmaski = CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE; + traceline(src, src + (v_forward * 32), FALSE, pl); + pl.hitcontentsmaski = oldhitcontents; +#endif + pl.a_ammo1 = 1 - pl.a_ammo1; if (pl.fist_mode == HS_KNIFE) { #ifdef SERVER Sound_Play(pl, 8, "weapon_fists.missknife"); #endif + if (pl.a_ammo1 == 1) { Weapons_ViewAnimation(pl, KNIFE_ATTACK1); } else { Weapons_ViewAnimation(pl, KNIFE_ATTACK2); } - -#ifdef SERVER - traceline(Weapons_GetCameraPos(pl), Weapons_GetCameraPos(pl) + (v_forward * 96),\ - FALSE, pl); - if (trace_ent && trace_fraction <= 1.0) { - if (trace_ent.takedamage == DAMAGE_YES) { - Damage_Apply(trace_ent, pl, Skill_GetValue("sk_knife1_d", 25), WEAPON_GAUSSPISTOL, DMG_GENERIC); - } - } -#endif - + #ifdef SERVER + finalDamage = (int)Skill_GetValue("knife1_d", 25); + #endif pl.w_attack_next = 0.5f; - pl.w_idle_next = pl.w_attack_next; } else { if (pl.a_ammo1 == 1) { Weapons_ViewAnimation(pl, FISTS_RIGHT); @@ -183,20 +189,29 @@ w_fists_primary(player pl) Sound_Play(pl, CHAN_WEAPON, "weapon_fists.hitleft"); #endif } + #ifdef SERVER + finalDamage = (int)Skill_GetValue("twohandpunch_d", 10); + #endif + pl.w_attack_next = 0.25f; + } + pl.w_idle_next = pl.w_attack_next; #ifdef SERVER - traceline(Weapons_GetCameraPos(pl), Weapons_GetCameraPos(pl) + (v_forward * 96),\ - FALSE, pl); - if (trace_ent && trace_fraction <= 1.0) { - if (trace_ent.takedamage == DAMAGE_YES) { - Damage_Apply(trace_ent, pl, Skill_GetValue("sk_twohandpunch_d", 10), WEAPON_GAUSSPISTOL, DMG_GENERIC); - } - } -#endif - - pl.w_attack_next = 0.25f; - pl.w_idle_next = pl.w_attack_next; + if (trace_fraction >= 1.0) { + return; } + + /* don't bother with decals, we got squibs */ + if (trace_ent.iBleeds) { + FX_Blood(trace_endpos, [1,0,0]); + } + + if (trace_ent.takedamage) { + Damage_Apply(trace_ent, pl, finalDamage, WEAPON_FISTS, DMG_BLUNT); + } else { + DecalGroups_Place("Impact.Shot", trace_endpos + (v_forward * -2)); + } +#endif } void diff --git a/src/shared/w_minigun.qc b/src/shared/w_minigun.qc index 62cf651..6b33d80 100644 --- a/src/shared/w_minigun.qc +++ b/src/shared/w_minigun.qc @@ -98,14 +98,14 @@ w_minigun_primary(player pl) if (pl.menu_active == 1) { Weapons_ViewAnimation(pl, MG_FIRELOOP); #ifdef SERVER - TraceAttack_FireBullets(1, src, Skill_GetValue("sk_9mmAR_bullet", 10), [0.1,0.1], WEAPON_MINIGUN); + TraceAttack_FireBulletsWithDecal(1, src, Skill_GetValue("sk_9mmAR_bullet", 10), [0.1,0.1], WEAPON_MINIGUN, "Impact.BigShot"); #endif pl.w_attack_next = 0.1f; pl.w_idle_next = 0.1f; } else { Weapons_ViewAnimation(pl, MG_FIRE); #ifdef SERVER - TraceAttack_FireBullets(1, src, Skill_GetValue("sk_9mmAR_bullet", 10), [0.05,0.05], WEAPON_MINIGUN); + TraceAttack_FireBulletsWithDecal(1, src, Skill_GetValue("sk_9mmAR_bullet", 10), [0.05,0.05], WEAPON_MINIGUN, "Impact.BigShot"); #endif pl.w_attack_next = 0.25f; pl.w_idle_next = 2.5f; @@ -120,9 +120,9 @@ w_minigun_secondary(player pl) #ifdef SERVER if (pl.menu_active == 0) { - Sound_Play(pl, 8, "weapon_minigun.spinup"); + //Sound_Play(pl, 8, "weapon_minigun.spinup"); } else { - Sound_Play(pl, 8, "weapon_minigun.spindown"); + //Sound_Play(pl, 8, "weapon_minigun.spindown"); } #endif diff --git a/src/shared/w_shotgun.qc b/src/shared/w_shotgun.qc index af95ed3..5aa0b6e 100644 --- a/src/shared/w_shotgun.qc +++ b/src/shared/w_shotgun.qc @@ -106,7 +106,7 @@ w_shotgun_primary(player pl) pellets = pl.shotgun_shells * 4; - TraceAttack_FireBullets(pellets, src, 5, spread, WEAPON_SHOTGUN); + TraceAttack_FireBulletsWithDecal(pellets, src, 5, spread, WEAPON_SHOTGUN, "Impact.BigShot"); Sound_Play(pl, CHAN_WEAPON, "weapon_shotgun.fire"); #else View_SetMuzzleflash(MUZZLE_SMALL); diff --git a/zpak001.pk3dir/cfg/skill_rewolf.cfg b/zpak001.pk3dir/cfg/skill_rewolf.cfg index f624a8c..a3d25cd 100644 --- a/zpak001.pk3dir/cfg/skill_rewolf.cfg +++ b/zpak001.pk3dir/cfg/skill_rewolf.cfg @@ -104,3 +104,11 @@ seta sk_tubryo_health3 50 seta sk_xenome_health1 50 seta sk_xenome_health2 50 seta sk_xenome_health3 50 + +seta sk_knife1_d1 25 +seta sk_knife1_d2 25 +seta sk_knife1_d3 25 + +seta sk_twohandpunch_d1 10 +seta sk_twohandpunch_d2 10 +seta sk_twohandpunch_d3 10 diff --git a/zpak001.pk3dir/def/decore/asteroid.def b/zpak001.pk3dir/def/decore/asteroid.def index d4602d6..6f9d484 100644 --- a/zpak001.pk3dir/def/decore/asteroid.def +++ b/zpak001.pk3dir/def/decore/asteroid.def @@ -5,6 +5,7 @@ entityDef decore_asteroid "mins" "-16 -16 0" "maxs" "16 16 40" "rotate" "1" + "rendermode" "6" when "asteroidsize" equals "1" { diff --git a/zpak001.pk3dir/def/hologram.def b/zpak001.pk3dir/def/hologram.def new file mode 100644 index 0000000..babec17 --- /dev/null +++ b/zpak001.pk3dir/def/hologram.def @@ -0,0 +1 @@ +include "hologram/beak.def" diff --git a/zpak001.pk3dir/def/hologram/beak.def b/zpak001.pk3dir/def/hologram/beak.def new file mode 100644 index 0000000..affce99 --- /dev/null +++ b/zpak001.pk3dir/def/hologram/beak.def @@ -0,0 +1,8 @@ +entityDef hologram_beak +{ + "spawnclass" "hologram_damage" + "editor_model" "models/beak.mdl" + "editor_mins" "-16 -16 0" + "editor_maxs" "16 16 72" + "creaturetype" "0" +} \ No newline at end of file diff --git a/zpak001.pk3dir/def/weapons/fists.def b/zpak001.pk3dir/def/weapons/fists.def index 7c5f5ab..c9abb90 100644 --- a/zpak001.pk3dir/def/weapons/fists.def +++ b/zpak001.pk3dir/def/weapons/fists.def @@ -3,8 +3,12 @@ entityDef weapon_fists "editor_color" ".3 .3 1" "editor_mins" "-16 -16 -16" "editor_maxs" "16 16 16" - "editor_usage" "Fists (null)" + "editor_usage" "Knife/Fists" "editor_rotatable" "1" - "spawnclass" "info_notnull" + "spawnclass" "NSItem" + "model" "models/w_knife.mdl" + "inv_item" "$WEAPON_FISTS" + "snd_acquire" "weapon.pickup" + "snd_respawn" "item.respawn" } \ No newline at end of file