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.
This commit is contained in:
Marco Cawthorne 2024-03-02 00:47:42 -08:00
parent c8921b3f09
commit c1457896fd
Signed by: eukara
GPG key ID: CE2032F0A2882A22
17 changed files with 524 additions and 166 deletions

View file

@ -14,6 +14,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
void View_ForceChange(player pl, int targetWeapon);
vector g_vecHUDNums[6] = vector g_vecHUDNums[6] =
{ {
[168 / 256, 72 / 128], [168 / 256, 72 / 128],
@ -39,9 +41,9 @@ HUD_DrawWeaponSelect_Forward(void)
if (pSeat->m_flHUDWeaponSelectTime < time) { if (pSeat->m_flHUDWeaponSelectTime < time) {
pSeat->m_iHUDWeaponSelected = pl.activeweapon; 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 { } 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--; pSeat->m_iHUDWeaponSelected--;
if (pSeat->m_iHUDWeaponSelected <= 0) { if (pSeat->m_iHUDWeaponSelected <= 0) {
pSeat->m_iHUDWeaponSelected = g_weapons.length - 1; pSeat->m_iHUDWeaponSelected = g_weapons.length - 1;
@ -70,9 +72,9 @@ HUD_DrawWeaponSelect_Back(void)
if (pSeat->m_flHUDWeaponSelectTime < time) { if (pSeat->m_flHUDWeaponSelectTime < time) {
pSeat->m_iHUDWeaponSelected = pl.activeweapon; 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 { } 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++; pSeat->m_iHUDWeaponSelected++;
if (pSeat->m_iHUDWeaponSelected >= g_weapons.length) { if (pSeat->m_iHUDWeaponSelected >= g_weapons.length) {
pSeat->m_iHUDWeaponSelected = 1; pSeat->m_iHUDWeaponSelected = 1;
@ -90,9 +92,12 @@ void
HUD_DrawWeaponSelect_Trigger(void) HUD_DrawWeaponSelect_Trigger(void)
{ {
player pl = (player)pSeat->m_ePlayer; player pl = (player)pSeat->m_ePlayer;
pl.activeweapon = pSeat->m_iHUDWeaponSelected;
sendevent("PlayerSwitchWeapon", "i", pSeat->m_iHUDWeaponSelected); if (pl.activeweapon != pSeat->m_iHUDWeaponSelected)
sound(pSeat->m_ePlayer, CHAN_ITEM, "common/wpn_select.wav", 0.5f, ATTN_NONE); View_ForceChange(pl, pSeat->m_iHUDWeaponSelected);
pl.StartSoundDef("Player.WeaponSelected", CHAN_ITEM, false);
pSeat->m_iHUDWeaponSelected = pSeat->m_flHUDWeaponSelectTime = 0; pSeat->m_iHUDWeaponSelected = pSeat->m_flHUDWeaponSelectTime = 0;
} }
@ -109,7 +114,7 @@ HUD_DrawWeaponSelect_Last(void)
void void
HUD_DrawWeaponSelect_Num(vector vecPos, float fValue) 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 int
@ -146,9 +151,9 @@ HUD_SlotSelect(int slot)
} }
if (pSeat->m_flHUDWeaponSelectTime < time) { 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 { } 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 */ /* 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_flHUDWeaponSelectTime < time) {
if (pSeat->m_iHUDWeaponSelected) { 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; pSeat->m_iHUDWeaponSelected = 0;
} }
return; return;
@ -213,7 +218,7 @@ HUD_DrawWeaponSelect(void)
if (x == wantpos) { if (x == wantpos) {
// Selected Sprite // Selected Sprite
Weapons_HUDPic(pl, pSeat->m_iHUDWeaponSelected, 1, vecPos, 1.0f); 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); [0,180/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE);
vecPos[1] += 50; vecPos[1] += 50;
} else if ((b=HUD_InSlotPos(i, x)) != -1) { } else if ((b=HUD_InSlotPos(i, x)) != -1) {

View file

@ -1,5 +1,187 @@
class /*
entity_digitgod:NSEntity * Copyright (c) 2024 Marco Cawthorne <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.
*/
/*!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();
}

View file

@ -19,16 +19,16 @@
Master entity for emitting a series of sprites. Master entity for emitting a series of sprites.
# KEYS # KEYS
"targetname" : Name - "targetname" : Name
"spritename" : Sprite model to emit - "spritename" : Sprite model to emit
"spritenoise" : Unknown. - "spritenoise" : Unknown.
"spritestartstate" : Whether to start off (0) or on (1) - "spritestartstate" : Whether to start off (0) or on (1)
"spritecount" : How many sprites to emit per interval - "spritecount" : How many sprites to emit per interval
"spritefreq" : Emitting frequency, defaults to 5. - "spritefreq" : Emitting frequency, defaults to 5.
"spritex" : Direction on the X-Axis (?) - "spritex" : Direction on the X-Axis (?)
"spritey" : Direction on the Y-Axis (?) - "spritey" : Direction on the Y-Axis (?)
"spritez" : Direction on the Z-Axis (?) - "spritez" : Direction on the Z-Axis (?)
"targetent" : Target entity, maybe used for setting the direction alternatively (?) - "targetent" : Target entity, maybe used for setting the direction alternatively (?)
# TRIVIA # TRIVIA
This entity was introduced in Gunman Chronicles (2000). This entity was introduced in Gunman Chronicles (2000).

View file

@ -116,8 +116,7 @@ HLMultiplayerRules::PlayerDeath(NSClientPlayer pl)
pl.gflags &= ~GF_EGONBEAM; pl.gflags &= ~GF_EGONBEAM;
pl.armor = pl.activeweapon = pl.g_items = 0; pl.armor = pl.activeweapon = pl.g_items = 0;
pl.health = 0; pl.health = 0;
pl.StartSoundDef("Player.Death", CHAN_AUTO, true);
Sound_Play(pl, CHAN_AUTO, "player.die");
/* force respawn */ /* force respawn */
pl.think = PutClientInServer; pl.think = PutClientInServer;

View file

@ -29,7 +29,7 @@ HLSingleplayerRules::PlayerDeath(NSClientPlayer pl)
pl.gflags &= ~GF_FLASHLIGHT; pl.gflags &= ~GF_FLASHLIGHT;
pl.armor = pl.activeweapon = pl.g_items = pl.weapon = 0; pl.armor = pl.activeweapon = pl.g_items = pl.weapon = 0;
pl.health = 0; pl.health = 0;
Sound_Play(pl, CHAN_AUTO, "player.die"); pl.StartSoundDef("Player.Death", CHAN_AUTO, true);
if (cvar("coop") == 1) { if (cvar("coop") == 1) {
pl.think = PutClientInServer; pl.think = PutClientInServer;

View file

@ -14,22 +14,86 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 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; /*!QUAKED hologram_damage (0 0.8 0.8) (-16 -16 0) (16 16 72)
virtual void(string, string) SpawnKey; # 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 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: case 1:
model = "models/tube.mdl"; model = "models/tube.mdl";
break; break;
@ -40,25 +104,95 @@ hologram_damage::Respawn(void)
model = "models/beak.mdl"; model = "models/beak.mdl";
} }
SetModel(model); precache_model(model);
m_oldModel = model;
} }
void void
hologram_damage::SpawnKey(string strKey, string strValue) hologram_damage::SpawnKey(string strKey, string strValue)
{ {
switch (strKey) { switch (strKey) {
case "targetfail":
m_strFailName = ReadString(strValue);
break;
case "creaturetype": case "creaturetype":
m_iType = stoi(strValue); m_dType = ReadFloat(strValue);
break;
case "damagetype":
m_dDamageType = ReadFloat(strValue);
break; break;
default: default:
NSTalkMonster::SpawnKey(strKey, strValue); super::SpawnKey(strKey, strValue);
} }
} }
void void
hologram_damage::hologram_damage(void) hologram_damage::Respawn(void)
{ {
base_mins = [-16,-16,0]; super::Respawn();
base_maxs = [16,16,72];
NSTalkMonster::NSTalkMonster(); 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);
} }

View file

@ -20,11 +20,11 @@
../shared/include.src ../shared/include.src
gunman_cycler.qc gunman_cycler.qc
hologram_damage.qc
decore.qc decore.qc
entity_digitgod.qc entity_digitgod.qc
hologram_damage.qc
entity_spritegod.qc entity_spritegod.qc
sphere_explosion.qc sphere_explosion.qc
player_giveitems.qc player_giveitems.qc

View file

@ -68,6 +68,7 @@ class player:NSClientPlayer
PREDICTED_INT(dml_state) PREDICTED_INT(dml_state)
virtual void UpdatePlayerAnimation(float); virtual void UpdatePlayerAnimation(float);
virtual void Physics_Jump(void);
#ifdef CLIENT #ifdef CLIENT
virtual void UpdatePlayerAttachments(bool); virtual void UpdatePlayerAttachments(bool);
@ -225,40 +226,40 @@ player::ReceiveEntity(float new, float flChanged)
NSClientPlayer::ReceiveEntity(new, flChanged); NSClientPlayer::ReceiveEntity(new, flChanged);
/* animation */ /* animation */
READENTITY_BYTE(anim_top, PLAYER_TOPFRAME); READENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
READENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME); READENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME)
READENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME); READENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME)
READENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME); READENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME)
READENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME); READENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME)
READENTITY_BYTE(ammo_battery, PLAYER_AMMO1); READENTITY_BYTE(ammo_battery, PLAYER_AMMO1)
READENTITY_BYTE(ammo_chem, PLAYER_AMMO1); READENTITY_BYTE(ammo_chem, PLAYER_AMMO1)
READENTITY_BYTE(ammo_rocket, PLAYER_AMMO1); READENTITY_BYTE(ammo_rocket, PLAYER_AMMO1)
READENTITY_BYTE(ammo_gauss, PLAYER_AMMO1); READENTITY_BYTE(ammo_gauss, PLAYER_AMMO1)
READENTITY_BYTE(ammo_minigun, PLAYER_AMMO1); READENTITY_BYTE(ammo_minigun, PLAYER_AMMO1)
READENTITY_BYTE(ammo_buckshot, PLAYER_AMMO1); READENTITY_BYTE(ammo_buckshot, PLAYER_AMMO1)
READENTITY_BYTE(fist_mode, PLAYER_AMMO1); READENTITY_BYTE(fist_mode, PLAYER_AMMO1)
READENTITY_BYTE(gauss_mode, PLAYER_AMMO1); READENTITY_BYTE(gauss_mode, PLAYER_AMMO1)
READENTITY_BYTE(shotgun_shells, PLAYER_AMMO1); READENTITY_BYTE(shotgun_shells, PLAYER_AMMO1)
READENTITY_BYTE(shotgun_spread, PLAYER_AMMO1); READENTITY_BYTE(shotgun_spread, PLAYER_AMMO1)
READENTITY_BYTE(dml_launch, PLAYER_AMMO2); READENTITY_BYTE(dml_launch, PLAYER_AMMO2)
READENTITY_BYTE(dml_flightpath, PLAYER_AMMO2); READENTITY_BYTE(dml_flightpath, PLAYER_AMMO2)
READENTITY_BYTE(dml_detonate, PLAYER_AMMO2); READENTITY_BYTE(dml_detonate, PLAYER_AMMO2)
READENTITY_BYTE(dml_payload, PLAYER_AMMO2); READENTITY_BYTE(dml_payload, PLAYER_AMMO2)
READENTITY_BYTE(chem_acid, PLAYER_AMMO2); READENTITY_BYTE(chem_acid, PLAYER_AMMO2)
READENTITY_BYTE(chem_neutral, PLAYER_AMMO2); READENTITY_BYTE(chem_neutral, PLAYER_AMMO2)
READENTITY_BYTE(chem_base, PLAYER_AMMO2); READENTITY_BYTE(chem_base, PLAYER_AMMO2)
READENTITY_BYTE(chem_pressure, PLAYER_AMMO2); READENTITY_BYTE(chem_pressure, PLAYER_AMMO2)
READENTITY_BYTE(beam_range, PLAYER_AMMO3); READENTITY_BYTE(beam_range, PLAYER_AMMO3)
READENTITY_BYTE(beam_poweracc, PLAYER_AMMO3); READENTITY_BYTE(beam_poweracc, PLAYER_AMMO3)
READENTITY_BYTE(beam_lightning, PLAYER_AMMO3); READENTITY_BYTE(beam_lightning, PLAYER_AMMO3)
READENTITY_BYTE(gren_detonate, PLAYER_AMMO3); READENTITY_BYTE(gren_detonate, PLAYER_AMMO3)
READENTITY_BYTE(gren_payload, PLAYER_AMMO3); READENTITY_BYTE(gren_payload, PLAYER_AMMO3)
READENTITY_BYTE(menu_active, PLAYER_AMMO3); READENTITY_BYTE(menu_active, PLAYER_AMMO3)
READENTITY_BYTE(dml_state, PLAYER_AMMO3); READENTITY_BYTE(dml_state, PLAYER_AMMO3)
if (flChanged & PLAYER_AMMO1 || flChanged & PLAYER_AMMO2 || flChanged & PLAYER_AMMO3) if (flChanged & PLAYER_AMMO1 || flChanged & PLAYER_AMMO2 || flChanged & PLAYER_AMMO3)
Weapons_AmmoUpdate(this); Weapons_AmmoUpdate(this);
@ -517,40 +518,40 @@ player::EvaluateEntity(void)
{ {
NSClientPlayer::EvaluateEntity(); NSClientPlayer::EvaluateEntity();
EVALUATE_FIELD(anim_top, PLAYER_TOPFRAME); EVALUATE_FIELD(anim_top, PLAYER_TOPFRAME)
EVALUATE_FIELD(anim_top_time, PLAYER_TOPFRAME); EVALUATE_FIELD(anim_top_time, PLAYER_TOPFRAME)
EVALUATE_FIELD(anim_top_delay, PLAYER_TOPFRAME); EVALUATE_FIELD(anim_top_delay, PLAYER_TOPFRAME)
EVALUATE_FIELD(anim_bottom, PLAYER_BOTTOMFRAME); EVALUATE_FIELD(anim_bottom, PLAYER_BOTTOMFRAME)
EVALUATE_FIELD(anim_bottom_time, PLAYER_BOTTOMFRAME); EVALUATE_FIELD(anim_bottom_time, PLAYER_BOTTOMFRAME)
EVALUATE_FIELD(ammo_battery, PLAYER_AMMO1); EVALUATE_FIELD(ammo_battery, PLAYER_AMMO1)
EVALUATE_FIELD(ammo_chem, PLAYER_AMMO1); EVALUATE_FIELD(ammo_chem, PLAYER_AMMO1)
EVALUATE_FIELD(ammo_rocket, PLAYER_AMMO1); EVALUATE_FIELD(ammo_rocket, PLAYER_AMMO1)
EVALUATE_FIELD(ammo_gauss, PLAYER_AMMO1); EVALUATE_FIELD(ammo_gauss, PLAYER_AMMO1)
EVALUATE_FIELD(ammo_minigun, PLAYER_AMMO1); EVALUATE_FIELD(ammo_minigun, PLAYER_AMMO1)
EVALUATE_FIELD(ammo_buckshot, PLAYER_AMMO1); EVALUATE_FIELD(ammo_buckshot, PLAYER_AMMO1)
EVALUATE_FIELD(fist_mode, PLAYER_AMMO1); EVALUATE_FIELD(fist_mode, PLAYER_AMMO1)
EVALUATE_FIELD(gauss_mode, PLAYER_AMMO1); EVALUATE_FIELD(gauss_mode, PLAYER_AMMO1)
EVALUATE_FIELD(shotgun_shells, PLAYER_AMMO1); EVALUATE_FIELD(shotgun_shells, PLAYER_AMMO1)
EVALUATE_FIELD(shotgun_spread, PLAYER_AMMO1); EVALUATE_FIELD(shotgun_spread, PLAYER_AMMO1)
EVALUATE_FIELD(dml_launch, PLAYER_AMMO2); EVALUATE_FIELD(dml_launch, PLAYER_AMMO2)
EVALUATE_FIELD(dml_flightpath, PLAYER_AMMO2); EVALUATE_FIELD(dml_flightpath, PLAYER_AMMO2)
EVALUATE_FIELD(dml_detonate, PLAYER_AMMO2); EVALUATE_FIELD(dml_detonate, PLAYER_AMMO2)
EVALUATE_FIELD(dml_payload, PLAYER_AMMO2); EVALUATE_FIELD(dml_payload, PLAYER_AMMO2)
EVALUATE_FIELD(chem_acid, PLAYER_AMMO2); EVALUATE_FIELD(chem_acid, PLAYER_AMMO2)
EVALUATE_FIELD(chem_neutral, PLAYER_AMMO2); EVALUATE_FIELD(chem_neutral, PLAYER_AMMO2)
EVALUATE_FIELD(chem_base, PLAYER_AMMO2); EVALUATE_FIELD(chem_base, PLAYER_AMMO2)
EVALUATE_FIELD(chem_pressure, PLAYER_AMMO2); EVALUATE_FIELD(chem_pressure, PLAYER_AMMO2)
EVALUATE_FIELD(beam_range, PLAYER_AMMO3); EVALUATE_FIELD(beam_range, PLAYER_AMMO3)
EVALUATE_FIELD(beam_poweracc, PLAYER_AMMO3); EVALUATE_FIELD(beam_poweracc, PLAYER_AMMO3)
EVALUATE_FIELD(beam_lightning, PLAYER_AMMO3); EVALUATE_FIELD(beam_lightning, PLAYER_AMMO3)
EVALUATE_FIELD(gren_detonate, PLAYER_AMMO3); EVALUATE_FIELD(gren_detonate, PLAYER_AMMO3)
EVALUATE_FIELD(gren_payload, PLAYER_AMMO3); EVALUATE_FIELD(gren_payload, PLAYER_AMMO3)
EVALUATE_FIELD(menu_active, PLAYER_AMMO3); EVALUATE_FIELD(menu_active, PLAYER_AMMO3)
EVALUATE_FIELD(dml_state, PLAYER_AMMO3); EVALUATE_FIELD(dml_state, PLAYER_AMMO3)
} }
/* /*
@ -575,40 +576,40 @@ player::SendEntity(entity ePEnt, float flChanged)
/* the generic client attributes */ /* the generic client attributes */
NSClientPlayer::SendEntity(ePEnt, flChanged); NSClientPlayer::SendEntity(ePEnt, flChanged);
SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME); SENDENTITY_BYTE(anim_top, PLAYER_TOPFRAME)
SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME); SENDENTITY_FLOAT(anim_top_time, PLAYER_TOPFRAME)
SENDENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME); SENDENTITY_FLOAT(anim_top_delay, PLAYER_TOPFRAME)
SENDENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME); SENDENTITY_BYTE(anim_bottom, PLAYER_BOTTOMFRAME)
SENDENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME); SENDENTITY_FLOAT(anim_bottom_time, PLAYER_BOTTOMFRAME)
SENDENTITY_BYTE(ammo_battery, PLAYER_AMMO1); SENDENTITY_BYTE(ammo_battery, PLAYER_AMMO1)
SENDENTITY_BYTE(ammo_chem, PLAYER_AMMO1); SENDENTITY_BYTE(ammo_chem, PLAYER_AMMO1)
SENDENTITY_BYTE(ammo_rocket, PLAYER_AMMO1); SENDENTITY_BYTE(ammo_rocket, PLAYER_AMMO1)
SENDENTITY_BYTE(ammo_gauss, PLAYER_AMMO1); SENDENTITY_BYTE(ammo_gauss, PLAYER_AMMO1)
SENDENTITY_BYTE(ammo_minigun, PLAYER_AMMO1); SENDENTITY_BYTE(ammo_minigun, PLAYER_AMMO1)
SENDENTITY_BYTE(ammo_buckshot, PLAYER_AMMO1); SENDENTITY_BYTE(ammo_buckshot, PLAYER_AMMO1)
SENDENTITY_BYTE(fist_mode, PLAYER_AMMO1); SENDENTITY_BYTE(fist_mode, PLAYER_AMMO1)
SENDENTITY_BYTE(gauss_mode, PLAYER_AMMO1); SENDENTITY_BYTE(gauss_mode, PLAYER_AMMO1)
SENDENTITY_BYTE(shotgun_shells, PLAYER_AMMO1); SENDENTITY_BYTE(shotgun_shells, PLAYER_AMMO1)
SENDENTITY_BYTE(shotgun_spread, PLAYER_AMMO1); SENDENTITY_BYTE(shotgun_spread, PLAYER_AMMO1)
SENDENTITY_BYTE(dml_launch, PLAYER_AMMO2); SENDENTITY_BYTE(dml_launch, PLAYER_AMMO2)
SENDENTITY_BYTE(dml_flightpath, PLAYER_AMMO2); SENDENTITY_BYTE(dml_flightpath, PLAYER_AMMO2)
SENDENTITY_BYTE(dml_detonate, PLAYER_AMMO2); SENDENTITY_BYTE(dml_detonate, PLAYER_AMMO2)
SENDENTITY_BYTE(dml_payload, PLAYER_AMMO2); SENDENTITY_BYTE(dml_payload, PLAYER_AMMO2)
SENDENTITY_BYTE(chem_acid, PLAYER_AMMO2); SENDENTITY_BYTE(chem_acid, PLAYER_AMMO2)
SENDENTITY_BYTE(chem_neutral, PLAYER_AMMO2); SENDENTITY_BYTE(chem_neutral, PLAYER_AMMO2)
SENDENTITY_BYTE(chem_base, PLAYER_AMMO2); SENDENTITY_BYTE(chem_base, PLAYER_AMMO2)
SENDENTITY_BYTE(chem_pressure, PLAYER_AMMO2); SENDENTITY_BYTE(chem_pressure, PLAYER_AMMO2)
SENDENTITY_BYTE(beam_range, PLAYER_AMMO3); SENDENTITY_BYTE(beam_range, PLAYER_AMMO3)
SENDENTITY_BYTE(beam_poweracc, PLAYER_AMMO3); SENDENTITY_BYTE(beam_poweracc, PLAYER_AMMO3)
SENDENTITY_BYTE(beam_lightning, PLAYER_AMMO3); SENDENTITY_BYTE(beam_lightning, PLAYER_AMMO3)
SENDENTITY_BYTE(gren_detonate, PLAYER_AMMO3); SENDENTITY_BYTE(gren_detonate, PLAYER_AMMO3)
SENDENTITY_BYTE(gren_payload, PLAYER_AMMO3); SENDENTITY_BYTE(gren_payload, PLAYER_AMMO3)
SENDENTITY_BYTE(menu_active, PLAYER_AMMO3); SENDENTITY_BYTE(menu_active, PLAYER_AMMO3)
SENDENTITY_BYTE(dml_state, PLAYER_AMMO3); SENDENTITY_BYTE(dml_state, PLAYER_AMMO3)
return (1); return (1);
} }

View file

@ -285,7 +285,7 @@ w_dml_hud(player pl)
"CLUSTER" "CLUSTER"
}; };
vector pos; vector pos;
vector jitter; vector jitter = g_vec_null;
float lerp; float lerp;
/* laser */ /* laser */

View file

@ -143,34 +143,40 @@ w_fists_release(player pl)
void void
w_fists_primary(player pl) w_fists_primary(player pl)
{ {
vector src;
int finalDamage = 0i;
if (pl.w_attack_next) { if (pl.w_attack_next) {
return; 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; pl.a_ammo1 = 1 - pl.a_ammo1;
if (pl.fist_mode == HS_KNIFE) { if (pl.fist_mode == HS_KNIFE) {
#ifdef SERVER #ifdef SERVER
Sound_Play(pl, 8, "weapon_fists.missknife"); Sound_Play(pl, 8, "weapon_fists.missknife");
#endif #endif
if (pl.a_ammo1 == 1) { if (pl.a_ammo1 == 1) {
Weapons_ViewAnimation(pl, KNIFE_ATTACK1); Weapons_ViewAnimation(pl, KNIFE_ATTACK1);
} else { } else {
Weapons_ViewAnimation(pl, KNIFE_ATTACK2); Weapons_ViewAnimation(pl, KNIFE_ATTACK2);
} }
#ifdef SERVER #ifdef SERVER
traceline(Weapons_GetCameraPos(pl), Weapons_GetCameraPos(pl) + (v_forward * 96),\ finalDamage = (int)Skill_GetValue("knife1_d", 25);
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 #endif
pl.w_attack_next = 0.5f; pl.w_attack_next = 0.5f;
pl.w_idle_next = pl.w_attack_next;
} else { } else {
if (pl.a_ammo1 == 1) { if (pl.a_ammo1 == 1) {
Weapons_ViewAnimation(pl, FISTS_RIGHT); Weapons_ViewAnimation(pl, FISTS_RIGHT);
@ -183,20 +189,29 @@ w_fists_primary(player pl)
Sound_Play(pl, CHAN_WEAPON, "weapon_fists.hitleft"); Sound_Play(pl, CHAN_WEAPON, "weapon_fists.hitleft");
#endif #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 #ifdef SERVER
traceline(Weapons_GetCameraPos(pl), Weapons_GetCameraPos(pl) + (v_forward * 96),\ if (trace_fraction >= 1.0) {
FALSE, pl); return;
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);
} }
/* 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 #endif
pl.w_attack_next = 0.25f;
pl.w_idle_next = pl.w_attack_next;
}
} }
void void

View file

@ -98,14 +98,14 @@ w_minigun_primary(player pl)
if (pl.menu_active == 1) { if (pl.menu_active == 1) {
Weapons_ViewAnimation(pl, MG_FIRELOOP); Weapons_ViewAnimation(pl, MG_FIRELOOP);
#ifdef SERVER #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 #endif
pl.w_attack_next = 0.1f; pl.w_attack_next = 0.1f;
pl.w_idle_next = 0.1f; pl.w_idle_next = 0.1f;
} else { } else {
Weapons_ViewAnimation(pl, MG_FIRE); Weapons_ViewAnimation(pl, MG_FIRE);
#ifdef SERVER #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 #endif
pl.w_attack_next = 0.25f; pl.w_attack_next = 0.25f;
pl.w_idle_next = 2.5f; pl.w_idle_next = 2.5f;
@ -120,9 +120,9 @@ w_minigun_secondary(player pl)
#ifdef SERVER #ifdef SERVER
if (pl.menu_active == 0) { if (pl.menu_active == 0) {
Sound_Play(pl, 8, "weapon_minigun.spinup"); //Sound_Play(pl, 8, "weapon_minigun.spinup");
} else { } else {
Sound_Play(pl, 8, "weapon_minigun.spindown"); //Sound_Play(pl, 8, "weapon_minigun.spindown");
} }
#endif #endif

View file

@ -106,7 +106,7 @@ w_shotgun_primary(player pl)
pellets = pl.shotgun_shells * 4; 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"); Sound_Play(pl, CHAN_WEAPON, "weapon_shotgun.fire");
#else #else
View_SetMuzzleflash(MUZZLE_SMALL); View_SetMuzzleflash(MUZZLE_SMALL);

View file

@ -104,3 +104,11 @@ seta sk_tubryo_health3 50
seta sk_xenome_health1 50 seta sk_xenome_health1 50
seta sk_xenome_health2 50 seta sk_xenome_health2 50
seta sk_xenome_health3 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

View file

@ -5,6 +5,7 @@ entityDef decore_asteroid
"mins" "-16 -16 0" "mins" "-16 -16 0"
"maxs" "16 16 40" "maxs" "16 16 40"
"rotate" "1" "rotate" "1"
"rendermode" "6"
when "asteroidsize" equals "1" when "asteroidsize" equals "1"
{ {

View file

@ -0,0 +1 @@
include "hologram/beak.def"

View file

@ -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"
}

View file

@ -3,8 +3,12 @@ entityDef weapon_fists
"editor_color" ".3 .3 1" "editor_color" ".3 .3 1"
"editor_mins" "-16 -16 -16" "editor_mins" "-16 -16 -16"
"editor_maxs" "16 16 16" "editor_maxs" "16 16 16"
"editor_usage" "Fists (null)" "editor_usage" "Knife/Fists"
"editor_rotatable" "1" "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"
} }