From 0909b917037347fcfd5f198b3350d21728890fb4 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Tue, 17 Sep 2024 12:46:31 -0700 Subject: [PATCH] last weeks work, read plan --- Documentation/Modules/.gwdir | 12 - src/client/cmd.qc | 1 + src/client/defs.h | 18 +- src/client/entry.qc | 20 +- src/client/fade.qc | 8 +- src/client/sky.qc | 8 + src/client/view.qc | 31 +- src/gs-entbase/server/env_fade.qc | 8 +- src/gs-entbase/server/env_shooter.qc | 8 +- src/gs-entbase/server/func_tank.qc | 8 +- src/gs-entbase/server/func_train.qc | 2 +- src/gs-entbase/server/item_healthcharger.qc | 4 +- src/gs-entbase/server/item_recharge.qc | 4 +- src/gs-entbase/server/player_loadsaved.qc | 8 +- src/gs-entbase/server/prop_physics.qc | 2 - src/gs-entbase/server/trigger_changelevel.qc | 19 +- src/gs-entbase/shared/env_beam.qc | 5 +- src/gs-entbase/shared/env_bubbles.qc | 8 +- src/gs-entbase/shared/env_funnel.qc | 10 +- src/gs-entbase/shared/env_glow.qc | 28 +- src/gs-entbase/shared/env_laser.qc | 7 +- src/gs-entbase/shared/env_sprite.qc | 41 +-- src/gs-entbase/shared/func_conveyor.qc | 16 +- src/gs-entbase/shared/func_tankmortar.qc | 10 +- src/gs-entbase/shared/point_spotlight.qc | 8 +- src/platform/cmd.qc | 6 +- src/server/entry.qc | 21 +- src/shared/NSAttack.h | 52 ++++ src/shared/NSAttack.qc | 173 +++++++++++ src/shared/NSClient.qc | 8 +- src/shared/NSClientPlayer.qc | 85 +++--- src/shared/NSClientSpectator.qc | 1 - src/shared/NSDebris.qc | 3 +- src/shared/NSEntity.h | 5 + src/shared/NSEntity.qc | 122 +++++--- src/shared/NSIO.qc | 38 ++- src/shared/NSItem.h | 9 +- src/shared/NSItem.qc | 99 ++++-- src/shared/NSMonster.h | 87 ------ src/shared/NSMonster.qc | 245 +++++++-------- src/shared/NSNavAI.h | 1 + src/shared/NSPhysicsEntity.qc | 85 +++--- src/shared/NSProjectile.h | 4 +- src/shared/NSProjectile.qc | 108 +++++-- src/shared/NSRenderableEntity.qc | 68 +++-- src/shared/NSSurfacePropEntity.qc | 22 +- src/shared/NSTalkMonster.qc | 16 +- src/shared/NSWeapon.h | 6 +- src/shared/NSWeapon.qc | 299 ++++++++++--------- src/shared/defs.h | 3 + src/shared/entityDef.qc | 2 +- src/shared/include.src | 1 + 52 files changed, 1147 insertions(+), 716 deletions(-) delete mode 100644 Documentation/Modules/.gwdir create mode 100644 src/shared/NSAttack.h create mode 100644 src/shared/NSAttack.qc diff --git a/Documentation/Modules/.gwdir b/Documentation/Modules/.gwdir deleted file mode 100644 index ea8cacdb..00000000 --- a/Documentation/Modules/.gwdir +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fsn_info_type" = <*I0>; - geometry = "1172 64 600 660 0 0 1920 1080 "; - lastselection = ( - "/4TB/VCS/Nuclide-SDK/Documentation/Modules" - ); - shelfdicts = ( - ); - shelfheight = <*R77>; - singlenode = <*BN>; - viewtype = Browser; -} \ No newline at end of file diff --git a/src/client/cmd.qc b/src/client/cmd.qc index cad01597..e1e810be 100644 --- a/src/client/cmd.qc +++ b/src/client/cmd.qc @@ -246,6 +246,7 @@ NSWeapon_SelectWeapon(NSWeapon nextWeapon) /* this gets passed in NSClientPlayer::ClientInputFrame() to the server */ pSeat->m_iHUDWeaponSelected = nextWeapon.GetSharedID(); + pSeat->m_flHUDWeaponSelectTime = time + 0.5f; } /* diff --git a/src/client/defs.h b/src/client/defs.h index 7393b29f..cf317201 100644 --- a/src/client/defs.h +++ b/src/client/defs.h @@ -28,6 +28,18 @@ var bool g_net_debug = false; var bool g_cheats = false; +var float autocvar_cg_modelSpinSpeed = 120.0f; +var float g_modelSpinAngle; +var float g_modelSpinPitch; +var float g_modelSpinRoll; +var float g_modelBobHeight; +var float autocvar_cg_modelSpinRoll = 0.0f; +var float autocvar_cg_modelSpinRollSpeed = 0.0f; +var float autocvar_cg_modelSpinPitch = 0.0f; +var float autocvar_cg_modelSpinPitchSpeed = 0.0f; +var float autocvar_cg_modelBobHeight = 0.0f; +var float autocvar_cg_modelBobHeightSpeed = 0.0f; + #define PRINTFLAG(x) if (cvar("net_showUpdates") || g_net_debug) \ print(sprintf("%f %s read update %s\n", time, classname, #x)); @@ -400,8 +412,12 @@ struct int m_iSelectedWeapon; } g_seats[4], *pSeat; +.float modelindex2; +.float modelindex3; +.float modelindex4; + var vector g_vecMousePos; var vector g_hudmins; var vector g_hudres; -var NSRadar g_overview; \ No newline at end of file +var NSRadar g_overview; diff --git a/src/client/entry.qc b/src/client/entry.qc index 9f12e1b8..057d6691 100644 --- a/src/client/entry.qc +++ b/src/client/entry.qc @@ -322,6 +322,14 @@ CSQC_UpdateView(float w, float h, float focus) /* make sure we're not running these on invalid seats post frame */ pSeat = __NULL__; pSeatLocal = __NULL__; + + g_modelSpinAngle = time * autocvar_cg_modelSpinSpeed; + g_modelSpinRoll = sin(time * autocvar_cg_modelSpinRollSpeed); + g_modelSpinPitch = sin(time * autocvar_cg_modelSpinPitchSpeed); + g_modelSpinRoll *= autocvar_cg_modelSpinRoll; + g_modelSpinPitch *= autocvar_cg_modelSpinPitch; + g_modelBobHeight = sin(time * autocvar_cg_modelBobHeightSpeed); + g_modelBobHeight *= autocvar_cg_modelBobHeight; } /** Called every time an input event (keys pressed, mouse moved etc.) happens. @@ -543,14 +551,14 @@ CSQC_WorldLoaded(void) //DetailTex_Init(); - /* Primarily for the flashlight */ - if (serverkeyfloat("*bspversion") != BSPVER_HL) { + ///* Primarily for the flashlight */ + //if (serverkeyfloat("*bspversion") != BSPVER_HL) { localcmd("r_shadow_realtime_dlight 1\n"); - } else { - localcmd("r_shadow_realtime_dlight 0\n"); - } + //} else { + // localcmd("r_shadow_realtime_dlight 0\n"); + //} -#if 0 +#if 1 string strTokenized; getentitytoken(0); diff --git a/src/client/fade.qc b/src/client/fade.qc index 0bf5acb9..708c7ec0 100644 --- a/src/client/fade.qc +++ b/src/client/fade.qc @@ -104,10 +104,10 @@ Fade_StartDark(void) void Fade_Parse(void) { - pSeat->m_vecFadeColor[0] = readfloat(); - pSeat->m_vecFadeColor[1] = readfloat(); - pSeat->m_vecFadeColor[2] = readfloat(); - pSeat->m_flFadeMaxAlpha = readfloat(); + pSeat->m_vecFadeColor[0] = readbyte(); + pSeat->m_vecFadeColor[1] = readbyte(); + pSeat->m_vecFadeColor[2] = readbyte(); + pSeat->m_flFadeMaxAlpha = readbyte(); pSeat->m_flFadeDuration = readfloat(); pSeat->m_flFadeHold = readfloat(); pSeat->m_flFadeStyle = readbyte(); diff --git a/src/client/sky.qc b/src/client/sky.qc index d664dc08..8d8534fc 100644 --- a/src/client/sky.qc +++ b/src/client/sky.qc @@ -15,6 +15,7 @@ */ var string g_strSkyName; +var string g_strSkyPath; void Sky_Update(int force) @@ -39,6 +40,13 @@ Sky_Update(int force) return; localcmd(sprintf("sky \"%s\"\n", skyPath)); + g_strSkyPath = skyPath; NSLog("sky update applying %s.", skyPath); } } + +string +Sky_GetMaterial(void) +{ + return (g_strSkyPath); +} diff --git a/src/client/view.qc b/src/client/view.qc index 25f2dfcc..1ffabab8 100644 --- a/src/client/view.qc +++ b/src/client/view.qc @@ -261,8 +261,7 @@ View_DrawViewModel(void) m_eViewModel.origin = m_eViewModelL.origin; if (Client_IsSpectator(cl)) { - m_eViewModel.angles = currentAngle; - m_eViewModelL.angles = currentAngle; + m_eViewModelL.angles = m_eViewModel.angles = currentAngle; /* HACK: fool Viewmodel_CalcBob(); */ pSeat->m_vecPredictedVelocity = pl.velocity; } @@ -319,10 +318,34 @@ View_DrawViewModel(void) m_eViewModelL.renderflags = RF_DEPTHHACK | RF_FIRSTPERSON; m_eViewModel.renderflags = RF_DEPTHHACK | RF_FIRSTPERSON; - if (m_eViewModel.GetRenderMode() != RM_DONTRENDER) + if (m_eViewModel.GetRenderMode() != RM_DONTRENDER) { addentity(m_eViewModel); - if (m_eViewModelL.GetRenderMode() != RM_DONTRENDER) + + /* TODO: clean this up. */ + if (m_eViewModel.modelindex2) { + float oldModelindex = m_eViewModel.modelindex; + m_eViewModel.modelindex = m_eViewModel.modelindex2; + addentity(m_eViewModel); + m_eViewModel.modelindex = oldModelindex; + } + + if (m_eViewModel.modelindex3) { + float oldModelindex = m_eViewModel.modelindex; + m_eViewModel.modelindex = m_eViewModel.modelindex3; + addentity(m_eViewModel); + m_eViewModel.modelindex = oldModelindex; + } + + if (m_eViewModel.modelindex4) { + float oldModelindex = m_eViewModel.modelindex; + m_eViewModel.modelindex = m_eViewModel.modelindex4; + addentity(m_eViewModel); + m_eViewModel.modelindex = oldModelindex; + } + } + if (m_eViewModelL.GetRenderMode() != RM_DONTRENDER) { addentity(m_eViewModelL); + } } } diff --git a/src/gs-entbase/server/env_fade.qc b/src/gs-entbase/server/env_fade.qc index c147dfce..c975f54d 100644 --- a/src/gs-entbase/server/env_fade.qc +++ b/src/gs-entbase/server/env_fade.qc @@ -114,10 +114,10 @@ env_fade::Trigger(entity eAct, triggermode_t iState) /* Half-Life ignores states entirely for env_fade's being triggered */ WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_FADE); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[0]); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[1]); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[2]); - WriteFloat(MSG_MULTICAST, m_flRenderAmt); + WriteByte(MSG_MULTICAST, m_vecRenderColor[0]); + WriteByte(MSG_MULTICAST, m_vecRenderColor[1]); + WriteByte(MSG_MULTICAST, m_vecRenderColor[2]); + WriteByte(MSG_MULTICAST, m_flRenderAmt); WriteFloat(MSG_MULTICAST, m_flFadeDuration); WriteFloat(MSG_MULTICAST, m_flFadeHold); WriteByte(MSG_MULTICAST, spawnflags); diff --git a/src/gs-entbase/server/env_shooter.qc b/src/gs-entbase/server/env_shooter.qc index c36cad7a..fb583396 100644 --- a/src/gs-entbase/server/env_shooter.qc +++ b/src/gs-entbase/server/env_shooter.qc @@ -252,10 +252,10 @@ env_shooter::ShootGib(void) eGib.SetSize([-8,-8,-8],[8,8,8]); eGib.SetOrigin(GetOrigin()); eGib.SetAngles(GetAngles()); - eGib.SetRenderColor(m_vecRenderColor); - eGib.SetRenderMode(m_iRenderMode); - eGib.SetRenderFX(m_iRenderFX); - eGib.SetRenderAmt(m_flRenderAmt); + eGib.SetRenderColor(GetRenderColor()); + eGib.SetRenderMode(GetRenderMode()); + eGib.SetRenderFX(GetRenderFX()); + eGib.SetRenderAmt(GetRenderAmt()); /* scale multiplier only works on sprites. the env_shooter entities in lambda_bunker.bsp rely diff --git a/src/gs-entbase/server/func_tank.qc b/src/gs-entbase/server/func_tank.qc index 67ec5756..8fcc40a7 100644 --- a/src/gs-entbase/server/func_tank.qc +++ b/src/gs-entbase/server/func_tank.qc @@ -304,8 +304,8 @@ func_tank::SpriteSmoke(vector org) smoke.nextthink = time + 0.1f; smoke.scale = m_flSpriteScale; smoke.SetRenderMode(RM_ADDITIVE); - smoke.SetRenderColor([1,1,1]); - smoke.SetRenderAmt(1.0f); + smoke.SetRenderColor([255,255,255]); + smoke.SetRenderAmt(255); } void @@ -325,8 +325,8 @@ func_tank::SpriteFlash(vector org) flash.nextthink = time + 0.1f; flash.scale = m_flSpriteScale; flash.SetRenderMode(RM_ADDITIVE); - flash.SetRenderColor([1,1,1]); - flash.SetRenderAmt(1.0f); + flash.SetRenderColor([255,255,255]); + flash.SetRenderAmt(255); } void diff --git a/src/gs-entbase/server/func_train.qc b/src/gs-entbase/server/func_train.qc index 7fac72dd..7da8dbba 100644 --- a/src/gs-entbase/server/func_train.qc +++ b/src/gs-entbase/server/func_train.qc @@ -217,7 +217,7 @@ func_train::Blocked(entity eBlocker) entityDamage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), "", center, dmgDir, eBlocker.origin); remove(damageDecl); } else { - remove(eBlocker); + /* remove(eBlocker); */ } } diff --git a/src/gs-entbase/server/item_healthcharger.qc b/src/gs-entbase/server/item_healthcharger.qc index a1cae54a..61cc3149 100644 --- a/src/gs-entbase/server/item_healthcharger.qc +++ b/src/gs-entbase/server/item_healthcharger.qc @@ -274,8 +274,8 @@ item_healthcharger::Respawn(void) m_eProgressMeter.SetAngles(GetAngles()); m_eProgressMeter.SetMovetype(MOVETYPE_NONE); m_eProgressMeter.SetRenderMode(RM_COLOR); - m_eProgressMeter.SetRenderColor([1,1,1]); - m_eProgressMeter.SetRenderAmt(0.25f); + m_eProgressMeter.SetRenderColor([255,255,255]); + m_eProgressMeter.SetRenderAmt(64); m_eProgressMeter.SetModel("models/health_charger_both.mdl"); } } diff --git a/src/gs-entbase/server/item_recharge.qc b/src/gs-entbase/server/item_recharge.qc index 60b9d2c8..a0cc294e 100644 --- a/src/gs-entbase/server/item_recharge.qc +++ b/src/gs-entbase/server/item_recharge.qc @@ -274,8 +274,8 @@ item_recharge::Respawn(void) m_eProgressMeter.SetAngles(GetAngles()); m_eProgressMeter.SetMovetype(MOVETYPE_NONE); m_eProgressMeter.SetRenderMode(RM_COLOR); - m_eProgressMeter.SetRenderColor([1,1,1]); - m_eProgressMeter.SetRenderAmt(0.25f); + m_eProgressMeter.SetRenderColor([255,255,255]); + m_eProgressMeter.SetRenderAmt(64); m_eProgressMeter.SetModel("models/field.mdl"); } } diff --git a/src/gs-entbase/server/player_loadsaved.qc b/src/gs-entbase/server/player_loadsaved.qc index b548e4d3..5f22769a 100644 --- a/src/gs-entbase/server/player_loadsaved.qc +++ b/src/gs-entbase/server/player_loadsaved.qc @@ -129,10 +129,10 @@ player_loadsaved::Trigger(entity act, triggermode_t unused) { WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_FADE); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[0]); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[1]); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[2]); - WriteFloat(MSG_MULTICAST, m_flRenderAmt); + WriteByte(MSG_MULTICAST, m_vecRenderColor[0]); + WriteByte(MSG_MULTICAST, m_vecRenderColor[1]); + WriteByte(MSG_MULTICAST, m_vecRenderColor[2]); + WriteByte(MSG_MULTICAST, m_flRenderAmt); WriteFloat(MSG_MULTICAST, m_flFadeDuration); WriteFloat(MSG_MULTICAST, m_flFadeHold); WriteByte(MSG_MULTICAST, 0); diff --git a/src/gs-entbase/server/prop_physics.qc b/src/gs-entbase/server/prop_physics.qc index def351be..84bc8ad5 100644 --- a/src/gs-entbase/server/prop_physics.qc +++ b/src/gs-entbase/server/prop_physics.qc @@ -90,8 +90,6 @@ prop_physics::Respawn(void) if (HasSpawnFlags(PHYSPROPSFL_PHYSDEVICE)) Sleep(); - - Sleep(); } CLASSEXPORT(prop_physics_override, prop_physics) diff --git a/src/gs-entbase/server/trigger_changelevel.qc b/src/gs-entbase/server/trigger_changelevel.qc index 61254b88..1ae16d5f 100644 --- a/src/gs-entbase/server/trigger_changelevel.qc +++ b/src/gs-entbase/server/trigger_changelevel.qc @@ -228,8 +228,9 @@ trigger_changelevel::Spawned(void) { super::Spawned(); - if (m_strOnLevelChange) + if (m_strOnLevelChange) { m_strOnLevelChange = CreateOutput(m_strOnLevelChange); + } } void @@ -246,8 +247,10 @@ trigger_changelevel::IsInside(entity ePlayer, entity eVolume) ePlayer.absmin[2] > eVolume.absmax[2] || ePlayer.absmax[0] < eVolume.absmin[0] || ePlayer.absmax[1] < eVolume.absmin[1] || - ePlayer.absmax[2] < eVolume.absmin[2]) + ePlayer.absmax[2] < eVolume.absmin[2]) { return (0); + } + return (1); } @@ -313,8 +316,9 @@ trigger_changelevel::Change(void) void trigger_changelevel::Trigger(entity act, triggermode_t unused) { - if (GetMaster(act) == false) + if (GetMaster(act) == false) { return; + } /* disable meself */ SetSolid(SOLID_NOT); @@ -331,14 +335,17 @@ trigger_changelevel::Trigger(entity act, triggermode_t unused) void trigger_changelevel::Touch(entity eToucher) { - if (HasSpawnFlags(LC_USEONLY)) + if (HasSpawnFlags(LC_USEONLY)) { return; + } - if (!(eToucher.flags & FL_CLIENT)) + if (isPlayer(eToucher) == false) { return; + } - if (time < 2.0f) + if (time < 2.0f) { return; + } Trigger(eToucher, TRIG_TOGGLE); } diff --git a/src/gs-entbase/shared/env_beam.qc b/src/gs-entbase/shared/env_beam.qc index 2fd84754..7646ae70 100644 --- a/src/gs-entbase/shared/env_beam.qc +++ b/src/gs-entbase/shared/env_beam.qc @@ -190,9 +190,6 @@ env_beam::SpawnKey(string strKey, string strValue) case "NoiseAmplitude": m_flAmplitude = ReadFloat(strValue); break; - case "rendercolor": - m_vecRenderColor = ReadVector(strValue); - break; default: super::SpawnKey(strValue, strKey); } @@ -524,4 +521,4 @@ env_beam::predraw(void) return (PREDRAW_NEXT); } -#endif \ No newline at end of file +#endif diff --git a/src/gs-entbase/shared/env_bubbles.qc b/src/gs-entbase/shared/env_bubbles.qc index 11642669..88eb5cb5 100644 --- a/src/gs-entbase/shared/env_bubbles.qc +++ b/src/gs-entbase/shared/env_bubbles.qc @@ -251,10 +251,10 @@ env_bubbles::EmitBubbles(void) setorigin(eBubble, vecPos); setmodel(eBubble, "sprites/bubble.spr"); eBubble.drawmask = MASK_ENGINE; - eBubble.m_vecRenderColor = [1,1,1]; - eBubble.m_iRenderMode = RM_ADDITIVE; - eBubble.m_flRenderAmt = 1.0f; - eBubble.movetype = MOVETYPE_FLY; + eBubble.SetRenderColor([255,255,255]); + eBubble.SetRenderMode(RM_ADDITIVE); + eBubble.SetRenderAmt(255); + eBubble.SetMovetype(MOVETYPE_FLY); eBubble.velocity[2] = 100 + random(0, 50); /* apply current */ diff --git a/src/gs-entbase/shared/env_funnel.qc b/src/gs-entbase/shared/env_funnel.qc index 2446f674..8873b711 100644 --- a/src/gs-entbase/shared/env_funnel.qc +++ b/src/gs-entbase/shared/env_funnel.qc @@ -117,8 +117,8 @@ env_funnel::Respawn(void) m_vecEndPos = GetOrigin() + [0.0f, 0.0f, m_flHeight]; m_iSpriteID = getmodelindex(m_strTexture, false); pvsflags = PVSF_IGNOREPVS; - m_vecRenderColor = [1,1,1]; - m_flRenderAmt = 1.0f; + SetRenderColor([255,255,255]); + SetRenderAmt(255); } void @@ -268,8 +268,8 @@ env_funnel::RendererRestarted(void) void env_funnel::RenderGlow(vector forg, vector fsize, float amount) { - float alphaTint = m_flRenderAmt * (1.0 - amount); - vector renderColor = m_vecRenderColor; + float alphaTint = (m_flRenderAmt / 255) * (1.0 - amount); + vector renderColor = m_vecRenderColor / 255; R_BeginPolygon(m_strTexture, 1, 0); R_PolygonVertex(forg + v_right * fsize[0] - v_up * fsize[1], @@ -405,4 +405,4 @@ env_funnel::predraw(void) return (PREDRAW_NEXT); } -#endif \ No newline at end of file +#endif diff --git a/src/gs-entbase/shared/env_glow.qc b/src/gs-entbase/shared/env_glow.qc index a22ea06a..789bedc3 100644 --- a/src/gs-entbase/shared/env_glow.qc +++ b/src/gs-entbase/shared/env_glow.qc @@ -142,10 +142,10 @@ env_glow::SendEntity(entity ePEnt, float flChanged) SENDENTITY_FLOAT(scale, SPRITE_CHANGED_SCALE) SENDENTITY_BYTE(m_iRenderMode, SPRITE_CHANGED_RENDERMODE) SENDENTITY_BYTE(m_iRenderFX, SPRITE_CHANGED_RENDERFX) - SENDENTITY_COLOR(m_vecRenderColor[0], SPRITE_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[1], SPRITE_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[2], SPRITE_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) + SENDENTITY_BYTE(m_vecRenderColor[0], SPRITE_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[1], SPRITE_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[2], SPRITE_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) SENDENTITY_STRING(m_strMaterial, SPRITE_CHANGED_MATERIAL) return (1); @@ -186,7 +186,7 @@ env_glow::postdraw(void) { if (GetRenderMode() == RM_GLOW) if (!autocvar_r_skipLensFlares) - env_sun_lensflare(origin, m_flMaxAlpha, m_vecRenderColor); + env_sun_lensflare(origin, m_flMaxAlpha, m_vecRenderColor / 255); } void @@ -206,8 +206,8 @@ env_glow::RendererRestarted(void) void env_glow::RenderGlow(vector forg, vector fsize) { - float alphaTint = GetRenderAmt(); - vector renderColor = m_vecRenderColor; + float alphaTint = GetRenderAmt() / 255; + vector renderColor = m_vecRenderColor / 255; #ifndef FTE_QUADFIX R_BeginPolygon(m_strMaterial, 1, 0); @@ -243,8 +243,8 @@ env_glow::RenderGlow(vector forg, vector fsize) void env_glow::RenderNormal(vector forg, vector fsize) { - float alphaTint = GetRenderAmt(); - vector renderColor = GetRenderColor(); + float alphaTint = GetRenderAmt() / 255; + vector renderColor = m_vecRenderColor / 255; #ifndef FTE_QUADFIX R_BeginPolygon(m_strMaterial, 0, 0); @@ -337,10 +337,10 @@ env_glow::ReceiveEntity(float flNew, float flChanged) READENTITY_FLOAT(scale, SPRITE_CHANGED_SCALE) READENTITY_BYTE(m_iRenderMode, SPRITE_CHANGED_RENDERMODE) READENTITY_BYTE(m_iRenderFX, SPRITE_CHANGED_RENDERFX) - READENTITY_COLOR(m_vecRenderColor[0], SPRITE_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[1], SPRITE_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[2], SPRITE_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) + READENTITY_BYTE(m_vecRenderColor[0], SPRITE_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[1], SPRITE_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[2], SPRITE_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) READENTITY_STRING(m_strMaterial, SPRITE_CHANGED_MATERIAL) if (flNew) @@ -350,4 +350,4 @@ env_glow::ReceiveEntity(float flNew, float flChanged) setsize(this, g_vec_null, g_vec_null); setorigin(this, origin); } -#endif \ No newline at end of file +#endif diff --git a/src/gs-entbase/shared/env_laser.qc b/src/gs-entbase/shared/env_laser.qc index 7e0bc642..a1664d61 100644 --- a/src/gs-entbase/shared/env_laser.qc +++ b/src/gs-entbase/shared/env_laser.qc @@ -158,9 +158,6 @@ env_laser::SpawnKey(string strKey, string strValue) case "NoiseAmplitude": m_flAmplitude = ReadFloat(strValue); break; - case "rendercolor": - m_vecRenderColor = ReadVector(strValue); - break; default: super::SpawnKey(strValue, strKey); } @@ -389,7 +386,7 @@ env_laser::predraw(void) R_PolygonVertex(point, [1, 0], m_vecRenderColor / 255, a); if (autocvar(cl_showoff, 0)) - dynamiclight_add(point, 150, m_vecRenderColor/255); + dynamiclight_add(point, 150, m_vecRenderColor / 255); last_progression = progression; } @@ -417,4 +414,4 @@ env_laser::predraw(void) return (PREDRAW_NEXT); } -#endif \ No newline at end of file +#endif diff --git a/src/gs-entbase/shared/env_sprite.qc b/src/gs-entbase/shared/env_sprite.qc index 907cfbec..c185d687 100644 --- a/src/gs-entbase/shared/env_sprite.qc +++ b/src/gs-entbase/shared/env_sprite.qc @@ -156,10 +156,10 @@ env_sprite::SendEntity(entity ePEnt, float flChanged) SENDENTITY_FLOAT(scale, SPRITE_CHANGED_SCALE) SENDENTITY_BYTE(m_iRenderMode, SPRITE_CHANGED_RENDERMODE) SENDENTITY_BYTE(m_iRenderFX, SPRITE_CHANGED_RENDERFX) - SENDENTITY_COLOR(m_vecRenderColor[0], SPRITE_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[1], SPRITE_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[2], SPRITE_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) + SENDENTITY_BYTE(m_vecRenderColor[0], SPRITE_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[1], SPRITE_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[2], SPRITE_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) SENDENTITY_STRING(m_strMaterial, SPRITE_CHANGED_MATERIAL) return (1); @@ -178,10 +178,10 @@ env_sprite::NetworkOnce(void) WriteFloat(MSG_MULTICAST, scale); WriteByte(MSG_MULTICAST, m_iRenderMode); WriteByte(MSG_MULTICAST, m_iRenderFX); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[0]); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[1]); - WriteFloat(MSG_MULTICAST, m_vecRenderColor[2]); - WriteFloat(MSG_MULTICAST, m_flRenderAmt); + WriteByte(MSG_MULTICAST, m_vecRenderColor[0]); + WriteByte(MSG_MULTICAST, m_vecRenderColor[1]); + WriteByte(MSG_MULTICAST, m_vecRenderColor[2]); + WriteByte(MSG_MULTICAST, m_flRenderAmt); WriteString(MSG_MULTICAST, m_strMaterial); msg_entity = this; @@ -235,6 +235,7 @@ env_sprite::predraw(void) return super::predraw(); } + vector color = m_vecRenderColor / 255; int s = (float)getproperty(VF_ACTIVESEAT); pSeat = &g_seats[s]; vector vecPlayer = pSeat->m_vecPredictedOrigin; @@ -250,13 +251,13 @@ env_sprite::predraw(void) R_BeginPolygon(m_strMaterial, 1, 0); R_PolygonVertex(forg + v_right * fsize[0] - v_up * fsize[1], - [1,1], m_vecRenderColor, 1.0); + [1,1], color, 1.0); R_PolygonVertex(forg - v_right * fsize[0] - v_up * fsize[1], - [0,1], m_vecRenderColor, 1.0); + [0,1], color, 1.0); R_PolygonVertex(forg - v_right * fsize[0] + v_up * fsize[1], - [0,0], m_vecRenderColor, 1.0); + [0,0], color, 1.0); R_PolygonVertex(forg + v_right * fsize[0] + v_up * fsize[1], - [1,0], m_vecRenderColor, 1.0); + [1,0], color, 1.0); R_EndPolygon(); addentity(this); @@ -292,10 +293,10 @@ env_sprite::ReceiveEntity(float flNew, float flChanged) READENTITY_FLOAT(scale, SPRITE_CHANGED_SCALE) READENTITY_BYTE(m_iRenderMode, SPRITE_CHANGED_RENDERMODE) READENTITY_BYTE(m_iRenderFX, SPRITE_CHANGED_RENDERFX) - READENTITY_COLOR(m_vecRenderColor[0], SPRITE_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[1], SPRITE_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[2], SPRITE_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) + READENTITY_BYTE(m_vecRenderColor[0], SPRITE_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[1], SPRITE_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[2], SPRITE_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) READENTITY_STRING(m_strMaterial, SPRITE_CHANGED_MATERIAL) drawmask = MASK_ENGINE; @@ -338,10 +339,10 @@ EnvSprite_ParseEvent(void) spr.scale = readfloat(); spr.m_iRenderMode = readbyte(); spr.m_iRenderFX = readbyte(); - spr.m_vecRenderColor[0] = readfloat(); - spr.m_vecRenderColor[1] = readfloat(); - spr.m_vecRenderColor[2] = readfloat(); - spr.m_flRenderAmt = readfloat(); + spr.m_vecRenderColor[0] = readbyte(); + spr.m_vecRenderColor[1] = readbyte(); + spr.m_vecRenderColor[2] = readbyte(); + spr.m_flRenderAmt = readbyte(); spr.m_strMaterial = readstring(); spr.drawmask = MASK_ENGINE; diff --git a/src/gs-entbase/shared/func_conveyor.qc b/src/gs-entbase/shared/func_conveyor.qc index 8da4a962..4b2b4a10 100644 --- a/src/gs-entbase/shared/func_conveyor.qc +++ b/src/gs-entbase/shared/func_conveyor.qc @@ -304,14 +304,14 @@ func_conveyor::SendEntity(entity ePEnt, float flChanged) SENDENTITY_COORD(avelocity[2], CONVEYOR_CHANGED_ANGULARVELOCITY) SENDENTITY_BYTE(m_iRenderMode, CONVEYOR_CHANGED_RENDERMODE) SENDENTITY_BYTE(m_iRenderFX, CONVEYOR_CHANGED_RENDERMODE) - SENDENTITY_ANGLE(m_vecRenderColor[0], CONVEYOR_CHANGED_RENDERCOLOR) - SENDENTITY_ANGLE(m_vecRenderColor[1], CONVEYOR_CHANGED_RENDERCOLOR) - SENDENTITY_ANGLE(m_vecRenderColor[2], CONVEYOR_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[0], CONVEYOR_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[1], CONVEYOR_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[2], CONVEYOR_CHANGED_RENDERCOLOR) /* these need more precision for shader hacks... */ SENDENTITY_FLOAT(glowmod[0], CONVEYOR_CHANGED_RENDERCOLOR) SENDENTITY_FLOAT(glowmod[1], CONVEYOR_CHANGED_RENDERCOLOR) SENDENTITY_FLOAT(glowmod[2], CONVEYOR_CHANGED_RENDERCOLOR) - SENDENTITY_FLOAT(m_flRenderAmt, CONVEYOR_CHANGED_RENDERAMT) + SENDENTITY_BYTE(m_flRenderAmt, CONVEYOR_CHANGED_RENDERAMT) SENDENTITY_FLOAT(m_flSpeed, CONVEYOR_CHANGED_SPEED) SENDENTITY_FLOAT(m_vecMoveDir[0], CONVEYOR_CHANGED_MOVEDIR) SENDENTITY_FLOAT(m_vecMoveDir[1], CONVEYOR_CHANGED_MOVEDIR) @@ -351,14 +351,14 @@ func_conveyor::ReceiveEntity(float flNew, float flChanged) READENTITY_COORD(avelocity[2], CONVEYOR_CHANGED_ANGULARVELOCITY) READENTITY_BYTE(m_iRenderMode, CONVEYOR_CHANGED_RENDERMODE) READENTITY_BYTE(m_iRenderFX, CONVEYOR_CHANGED_RENDERMODE) - READENTITY_ANGLE(m_vecRenderColor[0], CONVEYOR_CHANGED_RENDERCOLOR) - READENTITY_ANGLE(m_vecRenderColor[1], CONVEYOR_CHANGED_RENDERCOLOR) - READENTITY_ANGLE(m_vecRenderColor[2], CONVEYOR_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[0], CONVEYOR_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[1], CONVEYOR_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[2], CONVEYOR_CHANGED_RENDERCOLOR) /* these need more precision for shader hacks... */ READENTITY_FLOAT(glowmod[0], CONVEYOR_CHANGED_RENDERCOLOR) READENTITY_FLOAT(glowmod[1], CONVEYOR_CHANGED_RENDERCOLOR) READENTITY_FLOAT(glowmod[2], CONVEYOR_CHANGED_RENDERCOLOR) - READENTITY_FLOAT(m_flRenderAmt, CONVEYOR_CHANGED_RENDERAMT) + READENTITY_BYTE(m_flRenderAmt, CONVEYOR_CHANGED_RENDERAMT) READENTITY_FLOAT(m_flSpeed, CONVEYOR_CHANGED_SPEED) READENTITY_FLOAT(m_vecMoveDir[0], CONVEYOR_CHANGED_MOVEDIR) READENTITY_FLOAT(m_vecMoveDir[1], CONVEYOR_CHANGED_MOVEDIR) diff --git a/src/gs-entbase/shared/func_tankmortar.qc b/src/gs-entbase/shared/func_tankmortar.qc index 9083b952..24c2104d 100644 --- a/src/gs-entbase/shared/func_tankmortar.qc +++ b/src/gs-entbase/shared/func_tankmortar.qc @@ -273,8 +273,8 @@ func_tankmortar::SpriteSmoke(vector org) smoke.nextthink = time + 0.1f; smoke.scale = m_flSpriteScale; smoke.SetRenderMode(RM_ADDITIVE); - smoke.SetRenderColor([1,1,1]); - smoke.SetRenderAmt(1.0f); + smoke.SetRenderColor([255,255,255]); + smoke.SetRenderAmt(255); #endif } @@ -296,8 +296,8 @@ func_tankmortar::SpriteFlash(vector org) flash.nextthink = time + 0.1f; flash.scale = m_flSpriteScale; flash.SetRenderMode(RM_ADDITIVE); - flash.SetRenderColor([1,1,1]); - flash.SetRenderAmt(1.0f); + flash.SetRenderColor([255,255,255]); + flash.SetRenderAmt(255); #endif } @@ -456,4 +456,4 @@ func_tankmortar::func_tankmortar(void) { m_iVehicleFlags |= VHF_FROZEN | VHF_NOATTACK; -} \ No newline at end of file +} diff --git a/src/gs-entbase/shared/point_spotlight.qc b/src/gs-entbase/shared/point_spotlight.qc index 1d8e159c..059af023 100644 --- a/src/gs-entbase/shared/point_spotlight.qc +++ b/src/gs-entbase/shared/point_spotlight.qc @@ -148,7 +148,7 @@ point_spotlight::predraw(void) #if 0 //vecPlayer[2] = origin[2]; makevectors(vectoangles(origin - vecPlayer)); - R_BeginPolygon("textures/sfx/spot_cone"); + R_BeginPolygon("materials/sprites/glow_test02"); R_PolygonVertex(m_vecBeamEnd + (v_right * m_flBeamHalfwidth), [1,1], m_vecColor * coneAlpha, 1.0f); R_PolygonVertex(m_vecBeamEnd - (v_right * m_flBeamHalfwidth), @@ -161,7 +161,7 @@ point_spotlight::predraw(void) #else makevectors(vecAngle); setproperty(VF_ORIGIN, vecPlayer); - R_BeginPolygon("textures/sfx/spot_cone"); + R_BeginPolygon("materials/sprites/glow_test02"); R_PolygonVertex(origin, [1,0], finalColor, 1.0f); R_PolygonVertex(m_vecBeamEnd, [1,1], finalColor, 1.0f); R_EndPolygonRibbon(m_flBeamWidth, [-1,0]); @@ -181,7 +181,7 @@ point_spotlight::predraw(void) makevectors(vectoangles(origin - vecPlayer)); flareOrg += v_forward * - 16.0f; - R_BeginPolygon("textures/sfx/spot_flare"); + R_BeginPolygon("sprites/light_glow03"); R_PolygonVertex(flareOrg + v_right * m_flBeamHalfwidth - v_up * m_flBeamHalfwidth, [1,1], m_vecColor * coneAlpha, 1.0f); R_PolygonVertex(flareOrg - v_right * m_flBeamHalfwidth - v_up * m_flBeamHalfwidth, @@ -358,4 +358,4 @@ point_spotlight::point_spotlight(void) m_flBeamWidth = 50.0f; m_vecColor = [1.0,1.0,1.0]; #endif -} \ No newline at end of file +} diff --git a/src/platform/cmd.qc b/src/platform/cmd.qc index 273eb1d8..fd60a8f1 100644 --- a/src/platform/cmd.qc +++ b/src/platform/cmd.qc @@ -40,9 +40,6 @@ Platform_ConsoleCommand(string commandString, int wordCount) case "listGameLibrary": GameLibrary_DebugList(); break; - case "devMap": - localcmd(sprintf("disconnect;set sv_cheats 1;map %S\n", argv(1))); - break; case "ap_userID": ActivityPub_FetchAccountData(argv(1)); break; @@ -62,6 +59,5 @@ Platform_RegisterCommands(void) registercommand("menu_musicloop"); registercommand("map_background"); registercommand("listGameLibrary"); - registercommand("devMap"); registercommand("ap_userID"); -} \ No newline at end of file +} diff --git a/src/server/entry.qc b/src/server/entry.qc index 039b78cb..f06f8616 100644 --- a/src/server/entry.qc +++ b/src/server/entry.qc @@ -665,6 +665,7 @@ CheckSpawn(void() spawnfunc) { NSEntity ent = (NSEntity)self; string desiredClass = ent.classname; + static string lastClass; /* cancel out early */ if (ent == world) { @@ -679,14 +680,12 @@ CheckSpawn(void() spawnfunc) __fullspawndata = ""; if (MapTweak_EntitySpawn(ent) == true) { - ent._mapspawned = true; + ; } else if (EntityDef_SpawnClassname(desiredClass) != __NULL__) { - ent._mapspawned = true; + ; } else if (spawnfunc) { spawnfunc(); ent.classname = desiredClass; - ent._mapspawned = true; - g_ent_spawned++; } else { ent.identity = 0; } @@ -698,7 +697,12 @@ CheckSpawn(void() spawnfunc) g_ent_spawned--; } } else { - NSError("Unable to spawn %s", desiredClass); + /* don't need to spam repetitive messages */ + if (lastClass != desiredClass) { + NSError("Unable to spawn %s", desiredClass); + } + + lastClass = desiredClass; remove(ent); return; } @@ -710,12 +714,17 @@ CheckSpawn(void() spawnfunc) } } + /* count and mark as map spawned */ + ent._mapspawned = true; + g_ent_spawned++; + /* has to be called once, after the spawn values have been read in. */ ent.Spawned(); /* entity may be marked as deleted */ - if (wasfreed(ent)) + if (wasfreed(ent)) { return; + } /* needs to be called at least once after spawn, then any time after. */ ent.Respawn(); diff --git a/src/shared/NSAttack.h b/src/shared/NSAttack.h new file mode 100644 index 00000000..6d42ff47 --- /dev/null +++ b/src/shared/NSAttack.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * 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. +*/ + +/** This entity class represents an attack. Usually spawned by a decl's fireInfo properties. + +@ingroup baseclass +*/ +class NSAttack:NSSurfacePropEntity +{ +public: + void NSAttack(void); + +#ifdef SERVER + virtual void Spawned(void); + virtual void SpawnKey(string, string); + virtual void Save(float); + virtual void Restore(string, string); + + /* launch the attack into the world */ + virtual void Launch(vector, vector, float, float, float); + + nonvirtual void SetWeaponOwner(NSWeapon); + nonvirtual NSWeapon GetWeaponOwner(void); +#endif + +#ifdef SERVER +private: + float m_flFuse; + NSWeapon m_weaponOwner; + int m_iShots; + vector m_vecSpread; +#endif +}; + +#ifdef SERVER +NSAttack NSAttack_SpawnDef(string entityDef, NSActor theOwner); +NSAttack NSAttack_SpawnDefAtPosition(string entityDef, NSActor theOwner, vector vecOrigin, vector vecAngles); +NSAttack NSAttack_SpawnDefAttachment(string entityDef, NSActor theOwner, int attachmentID); +#endif diff --git a/src/shared/NSAttack.qc b/src/shared/NSAttack.qc new file mode 100644 index 00000000..48bd1ff4 --- /dev/null +++ b/src/shared/NSAttack.qc @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * 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. +*/ + +void +NSAttack::NSAttack(void) +{ +#ifdef SERVER + m_iShots = 1i; + m_vecSpread = [0.0, 0.0, 0.0]; + m_weaponOwner = __NULL__; + m_flFuse = -1.0f; +#endif +} + +#ifdef SERVER +void +NSAttack::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "fuse": /* fuse time in seconds */ + m_flFuse = ReadFloat(strValue); + break; + case "spread": + m_vecSpread = ReadVector(strValue); + break; + case "spread_x": + m_vecSpread[0] = ReadFloat(strValue); + break; + case "spread_y": + m_vecSpread[1] = ReadFloat(strValue); + break; + default: + super::SpawnKey(strKey, strValue); + break; + } +} + +void +NSAttack::Save(float handle) +{ + super::Save(handle); + + SaveInt(handle, "m_iShots", m_iShots); + SaveVector(handle, "m_vecSpread", m_vecSpread); + SaveFloat(handle, "m_flFuse", m_flFuse); + SaveEntity(handle, "m_weaponOwner", m_weaponOwner); +} + +void +NSAttack::Restore(string strKey, string strValue) +{ + switch (strKey) { + case "m_iShots": + m_iShots = ReadInt(strValue); + break; + case "m_flFuse": + m_flFuse = ReadFloat(strValue); + break; + case "m_vecSpread": + m_vecSpread = ReadVector(strValue); + break; + case "m_weaponOwner": + m_weaponOwner = ReadEntity(strValue); + break; + default: + super::Restore(strKey, strValue); + break; + } +} + +void +NSAttack::Spawned(void) +{ + super::Spawned(); +} + +void +NSAttack::SetWeaponOwner(NSWeapon weaponOwner) +{ + m_weaponOwner = weaponOwner; +} + +NSWeapon +NSAttack::GetWeaponOwner(void) +{ + return (m_weaponOwner); +} + +void +NSAttack::Launch(vector startPos, vector launchDir, float fuseOffset, float powerMultiplier, float dmgMultiplier) +{ + bool willPlant = GetSpawnBool("plant"); + + if (willPlant) { + string classToPlant = GetSpawnString("def_plant"); + bool willPlantOnGround = GetSpawnBool("plantOnGround"); + float plantDistance = GetSpawnFloat("plantDistance"); + vector forwardPos = (anglesToForward(launchDir) * plantDistance); + float plantOffset = GetSpawnFloat("plantOffset"); + + /* this doesn't need to be customize right now, as testDistance in NSWeapon handles a test */ + traceline(startPos, startPos + forwardPos, MOVE_NORMAL, m_weaponOwner); + NSEntity plantedEntity = spawnClass(classToPlant, trace_endpos + (trace_plane_normal * plantOffset)); + plantedEntity.SetAngles(vectoangles(trace_plane_normal)); + } + + /* free up the entity slot */ + Destroy(); +} + +#endif + + +#ifdef SERVER +NSAttack +NSAttack_SpawnDef(string entityDef, NSActor theOwner) +{ + entity oldself = self; + + NSAttack rocket = spawn(NSAttack); + rocket.owner = theOwner; + self = rocket; + EntityDef_SpawnClassname(entityDef); + self = oldself; + rocket.SetWeaponOwner(theOwner.m_activeWeapon); + rocket.Launch(theOwner.GetEyePos(), theOwner.GetViewAngle(), (time - theOwner.nadeCookingTime), 0.0f, 0.0f); + return rocket; +} + +NSAttack +NSAttack_SpawnDefAtPosition(string entityDef, NSActor theOwner, vector vecOrigin, vector vecAngles) +{ + entity oldself = self; + NSAttack rocket = spawn(NSAttack); + rocket.owner = theOwner; + self = rocket; + EntityDef_SpawnClassname(entityDef); + self = oldself; + rocket.SetWeaponOwner(theOwner.m_activeWeapon); + rocket.Launch(vecOrigin, vecAngles, (time - theOwner.nadeCookingTime), 0.0f, 0.0f); + return rocket; +} + +NSAttack +NSAttack_SpawnDefAttachment(string entityDef, NSActor theOwner, int attachmentID) +{ + entity oldself = self; + float skeletonIndex = skel_create(theOwner.modelindex); + vector attachmentPos = gettaginfo(theOwner, skel_get_numbones(skeletonIndex) + attachmentID); + skel_delete(skeletonIndex); + NSAttack rocket = spawn(NSAttack); + rocket.owner = theOwner; + self = rocket; + EntityDef_SpawnClassname(entityDef); + self = oldself; + rocket.SetWeaponOwner(theOwner.m_activeWeapon); + rocket.Launch(attachmentPos, theOwner.GetViewAngle(), (time - theOwner.nadeCookingTime), 0.0f, 0.0f); + return rocket; +} +#endif diff --git a/src/shared/NSClient.qc b/src/shared/NSClient.qc index d774890e..1f82aa8d 100644 --- a/src/shared/NSClient.qc +++ b/src/shared/NSClient.qc @@ -216,11 +216,13 @@ Client_ShakeOnce(vector pos, float radius, float duration, float frequency, floa { for (entity pl = world; (pl = find(pl, ::classname, "player"));) { float amp; + float distanceCheck = distance(pos, pl.origin); - if (vlen(pos - pl.origin) > radius) + if (distanceCheck > radius) { continue; + } - amp = 1.0 - (vlen(pos - pl.origin) / radius); + amp = 1.0 - (distanceCheck / radius); WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); WriteByte(MSG_MULTICAST, EV_SHAKE); WriteFloat(MSG_MULTICAST, duration); @@ -231,4 +233,4 @@ Client_ShakeOnce(vector pos, float radius, float duration, float frequency, floa multicast([0,0,0], MULTICAST_ONE); } } -#endif \ No newline at end of file +#endif diff --git a/src/shared/NSClientPlayer.qc b/src/shared/NSClientPlayer.qc index 6f7633d8..802319ab 100644 --- a/src/shared/NSClientPlayer.qc +++ b/src/shared/NSClientPlayer.qc @@ -21,12 +21,14 @@ NSClientPlayer::NSClientPlayer(void) vehicle = __NULL__; } -NSWeapon GetWeaponEntity(int theclientsnumber) +NSWeapon +GetWeaponEntity(int theclientsnumber) { - entity e = edict_num((float)theclientsnumber); //can return world when out of range... + entity e = edict_num((float)theclientsnumber); - if (wasfreed(e)) - e = world; //might have been freed... + if (wasfreed(e)) { + e = world; + } return e; } @@ -41,16 +43,24 @@ NSClientPlayer::SharedInputFrame(void) } #ifdef SERVER + /* here is where we check if the clients' desired weapon object exists, + is valid and is assigned to us. clients may send outdated or straight + up bogus values to mess with the server game. any checks go here + as this is where they'll be received first. */ if (input_cursor_entitynumber) { NSWeapon nextWeapon = GetWeaponEntity(input_cursor_entitynumber); - /* inpur_cursor_entity is not ours! */ - if (nextWeapon.owner != this) { - return; - } - - if (nextWeapon.IsWeapon() == false) { - return; + /* might be nothing */ + if (nextWeapon != __NULL__) { + /* item is not ours */ + if (nextWeapon.owner != this) { + return; + } + + /* item isn't a weapon */ + if (nextWeapon.IsWeapon() == false) { + return; + } } input_cursor_entitynumber = 0; @@ -456,10 +466,13 @@ NSClientPlayer::VehicleRelink(void) oldWeapon._SwitchedFromCallback(); } + /* complete new weapon */ if (m_activeWeapon != __NULL__ && oldWeapon == __NULL__) { m_activeWeapon.SetOwner(this); m_activeWeapon._AddedCallback(); m_activeWeapon._SwitchedToCallback(); + } else if (m_activeWeapon != __NULL__ && oldWeapon != m_activeWeapon) { + m_activeWeapon._SwitchedToCallback(); } } @@ -601,6 +614,8 @@ NSClientPlayer::ClientInputFrame(void) if (pSeat->m_iHUDWeaponSelected) { input_cursor_entitynumber = pSeat->m_iHUDWeaponSelected; + } else { + input_cursor_entitynumber = 0; } /* IW style stance override */ @@ -610,18 +625,6 @@ NSClientPlayer::ClientInputFrame(void) input_buttons |= INPUT_PRONE; } -#if 0 - /* The HUD needs more time */ - if (pSeat->m_iHUDWeaponSelected) { - if ((input_buttons & INPUT_PRIMARY)) - HUD_DrawWeaponSelect_Trigger(); - else if ((input_buttons & INPUT_SECONDARY)) - pSeat->m_iHUDWeaponSelected = pSeat->m_flHUDWeaponSelectTime = 0; - - pSeat->m_flInputBlockTime = time + 0.2; - } -#endif - /* prevent accidental input packets */ if (pSeat->m_flInputBlockTime > time) { input_buttons &= ~INPUT_PRIMARY; @@ -709,10 +712,10 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) /* crap the render mode updates in here */ READENTITY_BYTE(m_iRenderMode, PLAYER_MODELINDEX) READENTITY_BYTE(m_iRenderFX, PLAYER_MODELINDEX) - READENTITY_FLOAT(m_vecRenderColor[0], PLAYER_MODELINDEX) - READENTITY_FLOAT(m_vecRenderColor[1], PLAYER_MODELINDEX) - READENTITY_FLOAT(m_vecRenderColor[2], PLAYER_MODELINDEX) - READENTITY_FLOAT(m_flRenderAmt, PLAYER_MODELINDEX) + READENTITY_BYTE(m_vecRenderColor[0], PLAYER_MODELINDEX) + READENTITY_BYTE(m_vecRenderColor[1], PLAYER_MODELINDEX) + READENTITY_BYTE(m_vecRenderColor[2], PLAYER_MODELINDEX) + READENTITY_BYTE(m_flRenderAmt, PLAYER_MODELINDEX) READENTITY_ENTNUM(m_flFirstInventoryItem, PLAYER_ITEMS) READENTITY_ENTNUM(activeweapon, PLAYER_WEAPON) @@ -784,11 +787,8 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) } #endif - VehicleRelink(); - PredictPreFrame(); - Relink(); if (flChanged & PLAYER_SPECTATE) { @@ -808,6 +808,22 @@ at the top of player::PredictPreFrame void NSClientPlayer::PredictPreFrame(void) { + if (!vehicle_entnum) + vehicle = __NULL__; + else + vehicle = findentity(world, ::entnum, vehicle_entnum); + + if (!activeweapon) + m_activeWeapon = __NULL__; + else + m_activeWeapon = (NSWeapon)findentity(world, ::entnum, activeweapon); + + if (!m_flFirstInventoryItem) + m_itemList = __NULL__; + else { + m_itemList = (NSItem)findentity(world, ::entnum, m_flFirstInventoryItem); + } + if (m_activeWeapon) if (m_activeWeapon.PredictPreFrame) m_activeWeapon.PredictPreFrame(); @@ -1098,7 +1114,6 @@ NSClientPlayer::MakeTempSpectator(void) SetSolid(SOLID_NOT); SetMovetype(MOVETYPE_NOCLIP); MakeInvulnerable(); - maxspeed = 250; AddVFlags(VFL_FAKESPEC); max_health = health = 0; armor = 0; @@ -1320,10 +1335,10 @@ NSClientPlayer::SendEntity(entity ePEnt, float flChanged) /* crap the render mode updates in here */ SENDENTITY_BYTE(m_iRenderMode, PLAYER_MODELINDEX) SENDENTITY_BYTE(m_iRenderFX, PLAYER_MODELINDEX) - SENDENTITY_FLOAT(m_vecRenderColor[0], PLAYER_MODELINDEX) - SENDENTITY_FLOAT(m_vecRenderColor[1], PLAYER_MODELINDEX) - SENDENTITY_FLOAT(m_vecRenderColor[2], PLAYER_MODELINDEX) - SENDENTITY_FLOAT(m_flRenderAmt, PLAYER_MODELINDEX) + SENDENTITY_BYTE(m_vecRenderColor[0], PLAYER_MODELINDEX) + SENDENTITY_BYTE(m_vecRenderColor[1], PLAYER_MODELINDEX) + SENDENTITY_BYTE(m_vecRenderColor[2], PLAYER_MODELINDEX) + SENDENTITY_BYTE(m_flRenderAmt, PLAYER_MODELINDEX) SENDENTITY_ENTITY(m_itemList, PLAYER_ITEMS) SENDENTITY_ENTITY(m_activeWeapon, PLAYER_WEAPON) diff --git a/src/shared/NSClientSpectator.qc b/src/shared/NSClientSpectator.qc index 811e2b72..427978cc 100644 --- a/src/shared/NSClientSpectator.qc +++ b/src/shared/NSClientSpectator.qc @@ -82,7 +82,6 @@ void NSClientSpectator::WarpToTarget(void) { entity b = edict_num(spec_ent); - setorigin(this, b.origin); } diff --git a/src/shared/NSDebris.qc b/src/shared/NSDebris.qc index d63af324..41a3db0e 100644 --- a/src/shared/NSDebris.qc +++ b/src/shared/NSDebris.qc @@ -24,8 +24,9 @@ NSDebris::NSDebris(void) void NSDebris::Touch(entity touchingEnt) { - if (m_strImpactDecal) + if (STRING_SET(m_strImpactDecal)) { DecalGroups_Place(m_strImpactDecal, origin); + } } void diff --git a/src/shared/NSEntity.h b/src/shared/NSEntity.h index 773f5255..3f5f40af 100644 --- a/src/shared/NSEntity.h +++ b/src/shared/NSEntity.h @@ -384,6 +384,11 @@ public: /** Sets the @ref bot_info tag on this entity to the desired botInfo_t tag. */ nonvirtual void SetBotTag(botInfo_t); + /** Will enable collision with players, which is the default. */ + nonvirtual void EnablePlayerCollision(void); + /** Will disable collision with player entities. */ + nonvirtual void DisablePlayerCollision(void); + private: float m_flSpawnTime; bool m_bHidden; /**< decides whether the entity is visible or not, without affecting collision */ diff --git a/src/shared/NSEntity.qc b/src/shared/NSEntity.qc index 0a58af9f..01f81fe2 100644 --- a/src/shared/NSEntity.qc +++ b/src/shared/NSEntity.qc @@ -43,7 +43,7 @@ NSEntity::Spawned(void) precache_model(model); } - if (m_strOnTrigger) { + if (m_strOnTrigger != "") { m_strOnTrigger = CreateOutput(m_strOnTrigger); } @@ -105,10 +105,12 @@ NSEntity::VisibleVec(vector org) if (flFoV > 0.3f) { traceline(origin, org, TRUE, this); + if (trace_fraction == 1.0f) { return (true); } } + return (false); } @@ -216,11 +218,13 @@ NSEntity::ReceiveEntity(float flNew, float flChanged) drawmask = (modelindex != 0) ? MASK_ENGINE : 0; - if (scale == 0.0f) + if (scale == 0.0f) { scale = 1.0f; + } - if (flChanged & BASEFL_CHANGED_SIZE) + if (flChanged & BASEFL_CHANGED_SIZE) { setsize(this, mins, maxs); + } } void @@ -248,11 +252,13 @@ NSEntity::DebugDraw(void) float NSEntity::SendEntity(entity ePEnt, float flChanged) { - if (!modelindex) + if (!modelindex) { return (0); + } - if (clienttype(ePEnt) != CLIENTTYPE_REAL) + if (clienttype(ePEnt) != CLIENTTYPE_REAL) { return (0); + } WriteByte(MSG_ENTITY, ENT_ENTITY); @@ -346,12 +352,13 @@ NSEntity::ParentUpdate(void) frame1time += frametime; /* handle end-touch */ - if (m_beingTouched == true) + if (m_beingTouched == true) { if (m_flTouchTime < GetTime()) { EndTouch(m_eTouchLast); m_beingTouched = false; m_eTouchLast = __NULL__; } + } } entity @@ -363,7 +370,7 @@ NSEntity::GetParent(void) void NSEntity::SetParent(string name) { - tag_entity = find(world, ::targetname, m_parent); + tag_entity = find(world, ::targetname, name); } void @@ -429,8 +436,9 @@ NSEntity::SetEffects(float newEffects) void NSEntity::SetFrame(float newFrame) { - if (newFrame == frame) + if (newFrame == frame) { return; + } frame = newFrame; frame1time = 0.0f; @@ -456,10 +464,11 @@ NSEntity::SetFrame(float newFrame) string testData = argv(i+2); if (ourName == testName) { - if (testData != "") + if (testData != "") { Input(this, testInput, testData); - else + } else { Input(this, testInput, ""); /* no parms passed. */ + } tokenize(m_strModelEventCB); /* ensure argv() is 'rewound'... */ } @@ -492,9 +501,6 @@ NSEntity::SetTouch(void ()newTouch) touch = newTouch; } -/* we want to really use those set functions because they'll notify of any - * networking related changes. otherwise we'll have to keep track of copies - * that get updated every frame */ void NSEntity::SetSendFlags(float flSendFlags) { @@ -524,8 +530,9 @@ NSEntity::SetSolid(float newSolid) void NSEntity::SetScale(float newScale) { - if (newScale == scale) + if (newScale == scale) { return; + } scale = newScale; setsize(this, m_vecMins * scale, m_vecMaxs * scale); @@ -541,14 +548,12 @@ NSEntity::GetViewAngle(void) } } - void NSEntity::SetEyePos(vector value) { view_ofs = value; } - vector NSEntity::GetEyePos(void) { @@ -559,7 +564,6 @@ NSEntity::GetEyePos(void) return (origin + view_ofs); } - void NSEntity::UpdateBounds(void) { @@ -570,7 +574,7 @@ NSEntity::UpdateBounds(void) newMaxs = m_vecMaxs; /* avoid useless computation */ - if (angles !=[0, 0, 0]) { + if (angles != [0, 0, 0]) { /* adjust bbox according to rotation */ vector vecCorner[8]; @@ -600,8 +604,9 @@ NSEntity::UpdateBounds(void) } /* 0.0 is never valid, if you want it to disappear do something else */ - if (scale != 0.0) + if (scale != 0.0) { flScale = scale; + } setsize(this, newMins * flScale, newMaxs * flScale); } @@ -627,24 +632,28 @@ NSEntity::SetSize(vector newMins, vector newMaxs) m_vecMaxs = newMaxs; /* 0.0 is never valid, if you want it to disappear do something else */ - if (scale != 0.0f) + if (scale != 0.0f) { flScale = scale; + } setsize(this, newMins * flScale, newMaxs * flScale); } void -NSEntity::SetOrigin(vector newOrigin) { +NSEntity::SetOrigin(vector newOrigin) +{ setorigin(this, newOrigin); } void -NSEntity::SetOriginUnstick(vector newOrigin) { +NSEntity::SetOriginUnstick(vector newOrigin) +{ setorigin_safe(this, newOrigin); } void -NSEntity::SetModel(string newModel) { +NSEntity::SetModel(string newModel) +{ m_bIsBrush = substring(newModel, 0, 1) == "*" ? true : false; model = newModel; setmodel(this, newModel); @@ -652,10 +661,13 @@ NSEntity::SetModel(string newModel) { /* mins/maxs have been updated by setmodel */ SetSize(mins, maxs); } + void -NSEntity::SetModelindex(float newModelIndex) { - if (newModelIndex == modelindex) +NSEntity::SetModelindex(float newModelIndex) +{ + if (newModelIndex == modelindex) { return; + } modelindex = newModelIndex; SetSize(mins, maxs); @@ -725,13 +737,15 @@ NSEntity::SetNextThink(float fl) { float flTime = GetTime() + fl; /* HACK: to make sure things happen post-spawn */ - if (flTime == 0.0f) + if (flTime == 0.0f) { flTime = 0.001f; + } - if (flTime >= 0) + if (flTime >= 0) { nextthink = flTime; - else + } else { EntError("%s sets bogus nextthink value %f", classname, flTime); + } } void @@ -917,8 +931,11 @@ NSEntity::Respawn(void) { super::Respawn(); + if (CreatedByMap()) { + SetOrigin(GetSpawnVector("origin")); + } + SetAngles(GetSpawnVector("angles")); - SetOrigin(GetSpawnVector("origin")); SetModel(GetSpawnString("model")); } @@ -1256,7 +1273,7 @@ NSEntity::NearestWallPointForRadius(float radius) { vector vecRadius = [radius, radius, radius]; tracebox(origin, -vecRadius, vecRadius, origin, MOVE_EVERYTHING, this); - return (trace_fraction <= 1.0) ? trace_endpos : origin; + return (trace_fraction <= 1.0) ? (trace_endpos) : (origin); } void @@ -1307,7 +1324,7 @@ NSEntity::Transport(vector new_pos, vector new_ang) SetAngles(new_ang); #ifdef SERVER - if (flags & FL_CLIENT) { + if (isClient(this)) { Client_FixAngle(this, new_ang); } #endif @@ -1334,57 +1351,65 @@ NSEntity::GetNearbySpot(void) testPos = GetOrigin() + fwdDir * minDist; tracebox(testPos, mins, maxs, testPos, MOVE_NORMAL, this); - if (trace_fraction == 1.0f) + if (trace_fraction == 1.0f) { return (testPos); + } /* behind? */ testPos = GetOrigin() - fwdDir * minDist; tracebox(testPos, mins, maxs, testPos, MOVE_NORMAL, this); - if (trace_fraction == 1.0f) + if (trace_fraction == 1.0f) { return (testPos); + } /* left? */ testPos = GetOrigin() - rightDir * minDist; tracebox(testPos, mins, maxs, testPos, MOVE_NORMAL, this); - if (trace_fraction == 1.0f) + if (trace_fraction == 1.0f) { return (testPos); + } /* right? */ testPos = GetOrigin() + rightDir * minDist; tracebox(testPos, mins, maxs, testPos, MOVE_NORMAL, this); - if (trace_fraction == 1.0f) + if (trace_fraction == 1.0f) { return (testPos); + } /* front left? */ testPos = GetOrigin() + fwdDir * minDist - rightDir * minDist; tracebox(testPos, mins, maxs, testPos, MOVE_NORMAL, this); - if (trace_fraction == 1.0f) + if (trace_fraction == 1.0f) { return (testPos); + } /* front right? */ testPos = GetOrigin() + fwdDir * minDist + rightDir * minDist; tracebox(testPos, mins, maxs, testPos, MOVE_NORMAL, this); - if (trace_fraction == 1.0f) + if (trace_fraction == 1.0f) { return (testPos); + } /* back left? */ testPos = GetOrigin() - fwdDir * minDist - rightDir * minDist; tracebox(testPos, mins, maxs, testPos, MOVE_NORMAL, this); - if (trace_fraction == 1.0f) + if (trace_fraction == 1.0f) { return (testPos); + } /* back right? */ testPos = GetOrigin() - fwdDir * minDist + rightDir * minDist; tracebox(testPos, mins, maxs, testPos, MOVE_NORMAL, this); - if (trace_fraction == 1.0f) + if (trace_fraction == 1.0f) { return (testPos); + } return (g_vec_null); } @@ -1411,7 +1436,7 @@ NSEntity::_ProjectileAttack(string defName, bool wasReleased) for (int i = 0i; i < numProjectiles; i++) { EntLog("Launching %S at %v towards %v", attackDef, GetEyePos(), GetViewAngle()); - NSProjectile_SpawnDefAtPosition(attackDef, this, GetEyePos(), GetViewAngle()); + NSAttack_SpawnDefAtPosition(attackDef, this, GetEyePos(), GetViewAngle()); } #endif @@ -1450,6 +1475,20 @@ NSEntity::GetSharedID(void) #endif } +void +NSEntity::EnablePlayerCollision(void) +{ + dimension_solid = 255; + dimension_hit = 255; +} + +void +NSEntity::DisablePlayerCollision(void) +{ + dimension_solid = 1; + dimension_hit = 1; +} + NSEntity spawnClass(string className, vector desiredPos) { @@ -1469,7 +1508,6 @@ spawnClass(string className, vector desiredPos) } newEntity.classname = className; - newEntity.Input(newEntity, "SetSpawnOrigin", vtos(desiredPos)); newEntity.Input(newEntity, "SetOrigin", vtos(desiredPos)); newEntity.Respawn(); #endif @@ -1537,7 +1575,7 @@ isClient(entity entityToCheck) bool isPlayer(entity entityToCheck) { - if (entityToCheck.flags & FL_CLIENT) { + if (isClient(entityToCheck)) { NSClient pl = (NSClient)entityToCheck; return pl.IsPlayer(); diff --git a/src/shared/NSIO.qc b/src/shared/NSIO.qc index 9e80945f..e8c51188 100644 --- a/src/shared/NSIO.qc +++ b/src/shared/NSIO.qc @@ -126,17 +126,27 @@ NSIO::GetDefInt(string keyName) return (int)stoi(GetDefString(keyName)); } +/** Returns the framegroup for a given activity. */ float -NSIO::GetSubDefAct(string subDef, string keyName) +NSIO::GetSubDefAct(string subDef, string activityName) { float actCount; - string fireValue = GetSubDefString(subDef, keyName); - - /* not in classname either. make it known */ - if (fireValue == "") { - return (-1); + string actNameCheck; + string fireValue; + + /* check within sub-def, then classname decl */ + actNameCheck = strcat("act_", activityName); + fireValue = GetSubDefString(subDef, actNameCheck); + + /* not in class decl either. look it up in the model */ + if (!STRING_SET(fireValue)) { + /* look it up in the model itself now */ + float actModelNum = stof(EntityDef_GetKeyValue("activities", actNameCheck)); + float frameGroup = frameforaction(modelindex, actModelNum); + return (frameGroup); + //return (-1); } - + actCount = tokenizebyseparator(fireValue, ","); if (actCount == 1) { @@ -147,6 +157,12 @@ NSIO::GetSubDefAct(string subDef, string keyName) } } +float +NSIO::GetAct(string activityName) +{ + return GetSubDefAct(classname, activityName); +} + string NSIO::GetSubDefString(string subDef, string keyName) { @@ -390,11 +406,11 @@ NSIO::Input(entity eAct, string strInput, string strData) break; default: if (strData != "") { - EntWarning("Receives unknown input %S from %s (%d) with data %S", - strInput, eAct.classname, num_for_edict(eAct), strData); + EntWarning("%S receives unknown input %S from %s (%d) with data %S", + classname, strInput, eAct.classname, num_for_edict(eAct), strData); } else { - EntWarning("Receives unknown input %S from %s (%d)", - strInput, eAct.classname, num_for_edict(eAct)); + EntWarning("%S receives unknown input %S from %s (%d)", + classname, strInput, eAct.classname, num_for_edict(eAct)); } } } diff --git a/src/shared/NSItem.h b/src/shared/NSItem.h index 1b462727..c4c7f451 100644 --- a/src/shared/NSItem.h +++ b/src/shared/NSItem.h @@ -23,10 +23,9 @@ typedef enumflags ITEMFL_CHANGED_ANGLES_X, ITEMFL_CHANGED_ANGLES_Y, ITEMFL_CHANGED_ANGLES_Z, - ITEMFL_CHANGED_VELOCITY_X, - ITEMFL_CHANGED_VELOCITY_Y, - ITEMFL_CHANGED_VELOCITY_Z, + ITEMFL_CHANGED_VELOCITY, ITEMFL_CHANGED_ANGULARVELOCITY, + ITEMFL_CHANGED_RENDERPROPS, ITEMFL_CHANGED_SIZE, ITEMFL_CHANGED_FLAGS, ITEMFL_CHANGED_SOLID, @@ -64,7 +63,7 @@ These can be used, or be dormant. @ingroup baseclass */ -class NSItem:NSRenderableEntity +class NSItem:NSPhysicsEntity { public: void NSItem(void); @@ -81,8 +80,6 @@ public: virtual float SendEntity(entity,float); /* item related accessors */ - nonvirtual void SetItem(int i); - nonvirtual int GetItem(void); nonvirtual void SetFloating(int); nonvirtual bool GetFloating(void); nonvirtual void SetSpinning(bool); diff --git a/src/shared/NSItem.qc b/src/shared/NSItem.qc index 07fb409e..00cd48d7 100644 --- a/src/shared/NSItem.qc +++ b/src/shared/NSItem.qc @@ -53,16 +53,19 @@ NSItem::Respawn(void) static void AdjustSpawnPos(void) { RestoreAngles(); SetOrigin(GetSpawnVector("origin")); + placeSpawnpoint(this); if (!m_bFloating) { DropToFloor(); - SetMovetype(MOVETYPE_TOSS); } } super::Respawn(); BecomePickup(); + /* being a physics entity, we might have to restore player physics */ + EnablePlayerCollision(); + if (CreatedByMap() == true) { ScheduleThink(AdjustSpawnPos, 0.0f); } @@ -103,6 +106,9 @@ NSItem::SpawnKey(string strKey, string strValue) case "spin": m_bSpins = ReadBool(strValue); break; + case "floating": + m_bFloating = ReadBool(strValue); + break; case "frame": frame = ReadFloat(strValue); break; @@ -207,13 +213,15 @@ NSItem::Restore(string strKey, string strValue) void NSItem::Touch(entity eToucher) { - NSClientPlayer pl = (NSClientPlayer)eToucher; + NSClientPlayer pl; - if (eToucher.classname != "player") { + if (isPlayer(eToucher) == false) { return; } - if (m_strRequires) { + pl = (NSClientPlayer)eToucher; + + if (STRING_SET(m_strRequires)) { if (pl.HasItem(m_strRequires) == false) { return; } @@ -232,21 +240,6 @@ NSItem::Touch(entity eToucher) } } -void -NSItem::SetItem(int i) -{ - m_iInvItem = i; - //m_oldModel = Weapons_GetWorldmodel(m_iInvItem); - SetModel(GetSpawnString("model")); - SetSize([-16,-16,0], [16,16,16]); -} - -int -NSItem::GetItem(void) -{ - return m_iInvItem; -} - void NSItem::SetFloating(int i) { m_bFloating = i ? true : false; @@ -276,6 +269,7 @@ NSItem::PickupRespawn(void) { Respawn(); StartSoundDef(m_sndRespawn, CHAN_ITEM, true); + ReleaseThink(); } void @@ -305,16 +299,42 @@ NSItem::PrintDebugInfo(void) void NSItem::BecomePickup(void) { - SetSolid(SOLID_TRIGGER); SetBotTag(BOTINFO_WEAPON); + SetModel(GetSpawnString("model")); if (m_bSpins) modelflags = MF_ROTATE; else modelflags &= ~MF_ROTATE; - SetSize([-16,-16,0], [16,16,16]); Show(); + + if (GetSpawnBool("physics") == true) { + /* be shootable! */ + Wake(); + SetMovetype(MOVETYPE_PHYSICS); + SetSolid(SOLID_CORPSE); + } else { + vector desiredMins = GetSpawnVector("mins"); + vector desiredMaxs = GetSpawnVector("maxs"); + Sleep(); + SetMovetype(MOVETYPE_NONE); + SetSolid(SOLID_TRIGGER); + MakeInvulnerable(); + + if (desiredMins != g_vec_null) { + mins = desiredMins; + } + + if (desiredMaxs != g_vec_null) { + maxs = desiredMaxs; + } + + SetSize(mins, maxs); + } + + Relink(); + } float @@ -355,12 +375,18 @@ NSItem::SendEntity(entity ePEnt, float flChanged) SENDENTITY_FLOAT(skin, ITEMFL_CHANGED_SKIN) SENDENTITY_FLOAT(effects, ITEMFL_CHANGED_EFFECTS) SENDENTITY_FLOAT(scale, ITEMFL_CHANGED_SCALE) - SENDENTITY_COORD(velocity[0], ITEMFL_CHANGED_VELOCITY_X) - SENDENTITY_COORD(velocity[1], ITEMFL_CHANGED_VELOCITY_Y) - SENDENTITY_COORD(velocity[2], ITEMFL_CHANGED_VELOCITY_Z) + SENDENTITY_COORD(velocity[0], ITEMFL_CHANGED_VELOCITY) + SENDENTITY_COORD(velocity[1], ITEMFL_CHANGED_VELOCITY) + SENDENTITY_COORD(velocity[2], ITEMFL_CHANGED_VELOCITY) SENDENTITY_COORD(avelocity[0], ITEMFL_CHANGED_ANGULARVELOCITY) SENDENTITY_COORD(avelocity[1], ITEMFL_CHANGED_ANGULARVELOCITY) SENDENTITY_COORD(avelocity[2], ITEMFL_CHANGED_ANGULARVELOCITY) + SENDENTITY_BYTE(m_vecRenderColor[0], ITEMFL_CHANGED_RENDERPROPS) + SENDENTITY_BYTE(m_vecRenderColor[1], ITEMFL_CHANGED_RENDERPROPS) + SENDENTITY_BYTE(m_vecRenderColor[2], ITEMFL_CHANGED_RENDERPROPS) + SENDENTITY_BYTE(m_flRenderAmt, ITEMFL_CHANGED_RENDERPROPS) + SENDENTITY_BYTE(m_iRenderMode, ITEMFL_CHANGED_RENDERPROPS) + SENDENTITY_BYTE(m_iRenderFX, ITEMFL_CHANGED_RENDERPROPS) return (1); } @@ -393,12 +419,18 @@ NSItem::EvaluateEntity(void) EVALUATE_FIELD(skin, ITEMFL_CHANGED_SKIN) EVALUATE_FIELD(effects, ITEMFL_CHANGED_EFFECTS) EVALUATE_FIELD(scale, ITEMFL_CHANGED_SCALE) - EVALUATE_VECTOR(velocity, 0, ITEMFL_CHANGED_VELOCITY_X) - EVALUATE_VECTOR(velocity, 1, ITEMFL_CHANGED_VELOCITY_Y) - EVALUATE_VECTOR(velocity, 2, ITEMFL_CHANGED_VELOCITY_Z) + EVALUATE_VECTOR(velocity, 0, ITEMFL_CHANGED_VELOCITY) + EVALUATE_VECTOR(velocity, 1, ITEMFL_CHANGED_VELOCITY) + EVALUATE_VECTOR(velocity, 2, ITEMFL_CHANGED_VELOCITY) EVALUATE_VECTOR(avelocity, 0, ITEMFL_CHANGED_ANGULARVELOCITY) EVALUATE_VECTOR(avelocity, 1, ITEMFL_CHANGED_ANGULARVELOCITY) EVALUATE_VECTOR(avelocity, 2, ITEMFL_CHANGED_ANGULARVELOCITY) + EVALUATE_VECTOR(m_vecRenderColor, 0, ITEMFL_CHANGED_RENDERPROPS) + EVALUATE_VECTOR(m_vecRenderColor, 1, ITEMFL_CHANGED_RENDERPROPS) + EVALUATE_VECTOR(m_vecRenderColor, 2, ITEMFL_CHANGED_RENDERPROPS) + EVALUATE_FIELD(m_flRenderAmt, ITEMFL_CHANGED_RENDERPROPS) + EVALUATE_FIELD(m_iRenderMode, ITEMFL_CHANGED_RENDERPROPS) + EVALUATE_FIELD(m_iRenderFX, ITEMFL_CHANGED_RENDERPROPS) } #endif @@ -431,18 +463,25 @@ NSItem::ReceiveEntity(float flNew, float flChanged) READENTITY_FLOAT(skin, ITEMFL_CHANGED_SKIN) READENTITY_FLOAT(effects, ITEMFL_CHANGED_EFFECTS) READENTITY_FLOAT(scale, ITEMFL_CHANGED_SCALE) - READENTITY_COORD(velocity[0], ITEMFL_CHANGED_VELOCITY_X) - READENTITY_COORD(velocity[1], ITEMFL_CHANGED_VELOCITY_Y) - READENTITY_COORD(velocity[2], ITEMFL_CHANGED_VELOCITY_Z) + READENTITY_COORD(velocity[0], ITEMFL_CHANGED_VELOCITY) + READENTITY_COORD(velocity[1], ITEMFL_CHANGED_VELOCITY) + READENTITY_COORD(velocity[2], ITEMFL_CHANGED_VELOCITY) READENTITY_COORD(avelocity[0], ITEMFL_CHANGED_ANGULARVELOCITY) READENTITY_COORD(avelocity[1], ITEMFL_CHANGED_ANGULARVELOCITY) READENTITY_COORD(avelocity[2], ITEMFL_CHANGED_ANGULARVELOCITY) + READENTITY_BYTE(m_vecRenderColor[0], ITEMFL_CHANGED_RENDERPROPS) + READENTITY_BYTE(m_vecRenderColor[1], ITEMFL_CHANGED_RENDERPROPS) + READENTITY_BYTE(m_vecRenderColor[2], ITEMFL_CHANGED_RENDERPROPS) + READENTITY_BYTE(m_flRenderAmt, ITEMFL_CHANGED_RENDERPROPS) + READENTITY_BYTE(m_iRenderMode, ITEMFL_CHANGED_RENDERPROPS) + READENTITY_BYTE(m_iRenderFX, ITEMFL_CHANGED_RENDERPROPS) if (flChanged & ITEMFL_CHANGED_MODELINDEX) { classname = EntityDef_NameFromNetID(entityDefID); declclass = classname; } + movetype = MOVETYPE_NONE; drawmask = (modelindex != 0) ? MASK_ENGINE : 0; if (flChanged & ITEMFL_CHANGED_CHAIN) { diff --git a/src/shared/NSMonster.h b/src/shared/NSMonster.h index 74db447a..2717ad90 100644 --- a/src/shared/NSMonster.h +++ b/src/shared/NSMonster.h @@ -56,89 +56,6 @@ typedef enumflags MONFL_CHANGED_HEADYAW } nsmonster_changed_t; -/** List of supported ACT types. -These originate from GoldSrc and framegroups within models can be tagged -with them. This way the game-logic doesn't need to know the exact framegroup -but can instead pick a random ACT and we'll pick the right framegroup for you. */ -typedef enum { - ACT_RESET = 0, - ACT_IDLE = 1i, - ACT_GUARD, - ACT_WALK, - ACT_RUN, - ACT_FLY, - ACT_SWIM, - ACT_HOP, - ACT_LEAP, - ACT_FALL, - ACT_LAND, - ACT_STRAFE_LEFT, - ACT_STRAFE_RIGHT, - ACT_ROLL_LEFT, - ACT_ROLL_RIGHT, - ACT_TURN_LEFT, - ACT_TURN_RIGHT, - ACT_CROUCH, - ACT_CROUCHIDLE, - ACT_STAND, - ACT_USE, - ACT_SIGNAL1, - ACT_SIGNAL2, - ACT_SIGNAL3, - ACT_TWITCH, - ACT_COWER, - ACT_SMALL_FLINCH, - ACT_BIG_FLINCH, - ACT_RANGE_ATTACK1, - ACT_RANGE_ATTACK2, - ACT_MELEE_ATTACK1, - ACT_MELEE_ATTACK2, - ACT_RELOAD, - ACT_ARM, - ACT_DISARM, - ACT_EAT, - ACT_DIESIMPLE, - ACT_DIEBACKWARD, - ACT_DIEFORWARD, - ACT_DIEVIOLENT, - ACT_BARNACLE_HIT, - ACT_BARNACLE_PULL, - ACT_BARNACLE_CHOMP, - ACT_BARNACLE_CHEW, - ACT_SLEEP, - ACT_INSPECT_FLOOR, - ACT_INSPECT_WALL, - ACT_IDLE_ANGRY, - ACT_WALK_HURT, - ACT_RUN_HURT, - ACT_HOVER, - ACT_GLIDE, - ACT_FLY_LEFT, - ACT_FLY_RIGHT, - ACT_DETECT_SCENT, - ACT_SNIFF, - ACT_BITE, - ACT_THREAT_DISPLAY, - ACT_FEAR_DISPLAY, - ACT_EXCITED, - ACT_SPECIAL_ATTACK1, - ACT_SPECIAL_ATTACK2, - ACT_COMBAT_IDLE, - ACT_WALK_SCARED, - ACT_RUN_SCARED, - ACT_VICTORY_DANCE, - ACT_DIE_HEADSHOT, - ACT_DIE_CHESTSHOT, - ACT_DIE_GUTSHOT, - ACT_DIE_BACKSHOT, - ACT_FLINCH_HEAD, - ACT_FLINCH_CHEST, - ACT_FLINCH_STOMACH, - ACT_FLINCH_LEFTARM, - ACT_FLINCH_RIGHTARM, - ACT_FLINCH_LEFTLEG, - ACT_FLINCH_RIGHTLEG, -} monster_activity_t; /** Monster flags, these are defined by the level designers. */ typedef enumflags @@ -435,10 +352,6 @@ public: virtual int AnimWalk(void); /** DEPRECATED, Overridable: Called when we need to play a fresh running framegroup. */ virtual int AnimRun(void); - /** Overridable: Returns which framegroup to play for a given ACT. */ - virtual float FramegroupForAct(float); - /** Call to play an ACT on the given NSMonster. */ - nonvirtual void ActPlay(float); /** Call to play a single animation onto it, which cannot be interrupted by movement. */ virtual void AnimPlay(float); /** Internal use only. Run every frame to update animation parameters. */ diff --git a/src/shared/NSMonster.qc b/src/shared/NSMonster.qc index 32fec875..4ce6065d 100644 --- a/src/shared/NSMonster.qc +++ b/src/shared/NSMonster.qc @@ -449,35 +449,22 @@ NSMonster::Restore(string strKey, string strValue) int NSMonster::AnimIdle(void) { - return FramegroupForAct(ACT_IDLE); + return GetAct("idle"); } int NSMonster::AnimWalk(void) { - return FramegroupForAct(ACT_WALK); + return GetAct("walk"); } int NSMonster::AnimRun(void) { - float runAnim = FramegroupForAct(ACT_RUN); + float runAnim = GetAct("run"); return (runAnim == -1) ? AnimWalk() : runAnim; } -float -NSMonster::FramegroupForAct(float actName) -{ - float frameGroup = frameforaction(modelindex, actName); - return frameGroup; -} - -void -NSMonster::ActPlay(float actName) -{ - AnimPlay(FramegroupForAct(actName)); -} - void NSMonster::AnimPlay(float seq) { @@ -802,9 +789,9 @@ NSMonster::_LerpTurnToYaw(vector turnYaw) if (m_bTurning == false) { if (yawDiff < 0) { - AnimPlay(FramegroupForAct(ACT_TURN_RIGHT)); + AnimPlay(GetAct("turnRight")); } else { - AnimPlay(FramegroupForAct(ACT_TURN_LEFT)); + AnimPlay(GetAct("turnLeft")); } } @@ -846,14 +833,17 @@ NSMonster::_LerpTurnToEnemy(void) void NSMonster::AttackThink(void) { - if (InSequence()) + if (InSequence()) { return; + } - if (m_flAttackThink > time) + if (m_flAttackThink > time) { return; + } - if (!m_eEnemy) + if (!m_eEnemy) { return; + } /* do we have a clear shot? */ other = world; @@ -878,8 +868,9 @@ NSMonster::AttackThink(void) } /* the state may have switched */ - if (m_flAttackThink > time) + if (m_flAttackThink > time) { return; + } if (GetState() == MONSTER_AIMING) { int m; @@ -902,8 +893,8 @@ int NSMonster::AttackMelee(void) { #if 0 - float actMelee1 = FramegroupForAct(ACT_MELEE_ATTACK1); - float actMelee2 = FramegroupForAct(ACT_MELEE_ATTACK2); + float actMelee1 = GetAct("meleeAttack1"); + float actMelee2 = GetAct("meleeAttack2"); if (!m_defMelee) return (false); @@ -956,15 +947,15 @@ NSMonster::AttackRanged(void) static void AttackRanged_Throw(void) { for (int i = 0; i < m_iNumProjectiles; i++) - NSProjectile_SpawnDef(m_defSpecial1, this); + NSAttack_SpawnDef(m_defSpecial1, this); } static void AttackRanged_RangedSpecial(void) { NSMonsterLog("AttackRanged_RangedSpecial: %S", m_defRanged2); - NSProjectile_SpawnDef(m_defRanged2, this); + NSAttack_SpawnDef(m_defRanged2, this); } - float distToEnemy = vlen(m_eEnemy.origin - GetOrigin()); + float distToEnemy = distance(m_eEnemy.origin, GetOrigin()); bool inSpecial1Range = (distToEnemy < m_flSpecial1Range && m_flSpecial1Range != -1.0) ? true : false; bool inSpecial2Range = (distToEnemy < m_flSpecial2Range && m_flSpecial2Range != -1.0) ? true : false; @@ -989,7 +980,7 @@ NSMonster::AttackRanged(void) float rangedMax = GetSubDefFloat(m_defRanged1, "delay_max"); float burstCount = GetSubDefFloat(m_defRanged1, "burst"); float burstDelay = GetSubDefFloat(m_defRanged1, "burst_delay"); - float actRanged = FramegroupForAct(ACT_RANGE_ATTACK1); + float actRanged = GetAct("rangeAttack1"); float burstTime = 0.0f; if (rangedDly <= 0.0) { @@ -1000,7 +991,7 @@ NSMonster::AttackRanged(void) if (m_flReloadCount) if (_m_flReloadTracker > m_flReloadCount) { float startAmmo = 0; - float actReload = FramegroupForAct(ACT_RELOAD); + float actReload = GetAct("reload"); /* out of ammo, cannot reload */ if (m_flReserveAmmo == 0) { @@ -1042,10 +1033,11 @@ NSMonster::AttackRanged(void) AnimPlay(actRanged); /* if we have no spawnclass, it must be a hitscan weapon */ - if (m_defRanged1) - if (EntityDef_HasSpawnClass(m_defRanged1)) { - NSProjectile_SpawnDef(m_defRanged1, this); - NSMonsterLog("Firing ranged def %S", m_defRanged1); + if (STRING_SET(m_defRanged1)) { + if (EntityDef_HasSpawnClass(m_defRanged1)) { + NSAttack_SpawnDef(m_defRanged1, this); + NSMonsterLog("Firing ranged def %S", m_defRanged1); + } } StartSoundDef(m_sndRangedAttack, CHAN_WEAPON, true); @@ -1069,7 +1061,7 @@ NSMonster::AttackRanged(void) return 1; } else if (throwAnyway == false && inRanged2Range && trace_ent == m_eEnemy) { - float actRangedSpecial = FramegroupForAct(ACT_RANGE_ATTACK2); + float actRangedSpecial = GetAct("rangeAttack2"); AnimReset(); AnimPlay(actRangedSpecial); ScheduleThink(AttackRanged_RangedSpecial, 0.0f); @@ -1077,7 +1069,7 @@ NSMonster::AttackRanged(void) return 1; } else if (inSpecial1Range) { AnimReset(); - AnimPlay(FramegroupForAct(ACT_SPECIAL_ATTACK1)); + AnimPlay(GetAct("specialAttack1")); ScheduleThink(AttackRanged_Throw, m_flProjectileDelay); if (_m_bShouldThrow) @@ -1088,7 +1080,7 @@ NSMonster::AttackRanged(void) return 1; } else if (inSpecial2Range) { AnimReset(); - AnimPlay(FramegroupForAct(ACT_SPECIAL_ATTACK2)); + AnimPlay(GetAct("specialAttack2")); ScheduleThink(AttackRanged_Throw, m_flProjectileDelay); if (_m_bShouldThrow) @@ -1106,11 +1098,11 @@ NSMonster::AttackRanged(void) void NSMonster::AttackDraw(void) { - float actDraw = FramegroupForAct(ACT_ARM); + float actDraw = GetAct("arm"); AnimPlay(actDraw); m_flAttackThink = time + frameduration(modelindex, actDraw); - if (m_strBodyOnDraw) { + if (STRING_SET(m_strBodyOnDraw)) { int t = tokenizebyseparator(m_strBodyOnDraw, ":"); if (t == 1) { @@ -1124,7 +1116,7 @@ NSMonster::AttackDraw(void) void NSMonster::AttackHolster(void) { - float actHolster = FramegroupForAct(ACT_DISARM); + float actHolster = GetAct("disarm"); AnimPlay(actHolster); m_flAttackThink = time + frameduration(modelindex, actHolster); } @@ -1143,7 +1135,7 @@ NSMonster::FreeState(void) which THEN sets its killtarget to be monster that triggers the scripted_sequence. If that happens, the monster will then killtarget itself right after. */ - if (m_strSequenceKillTarget != "") { + if (STRING_SET(m_strSequenceKillTarget)) { NSEntity findKT = (NSEntity)find(world, ::targetname, m_strSequenceKillTarget); if (findKT) { @@ -1168,9 +1160,9 @@ NSMonster::FreeState(void) to_trigger = m_strRouteEnded; m_strRouteEnded = __NULL__; m_ssLast = __NULL__; - + /* trigger when required */ - if (to_trigger) { + if (STRING_SET(to_trigger)) { for (entity f = world; (f = find(f, ::targetname, to_trigger));) { NSEntity trigger = (NSEntity)f; if (trigger.Trigger != __NULL__) { @@ -1317,7 +1309,7 @@ NSMonster::AnimationUpdate(void) m_flAnimTime = 0.0f; if (fr == -1) - act = (frameforaction(modelindex, ACT_IDLE)); + act = GetAct("idle"); m_iMoveState = MOVESTATE_IDLE; @@ -1328,7 +1320,7 @@ NSMonster::AnimationUpdate(void) m_flAnimTime = 0.0f; if (fr == -1) - act = (frameforaction(modelindex, ACT_WALK)); + act = GetAct("walk"); m_iMoveState = MOVESTATE_WALK; @@ -1339,7 +1331,7 @@ NSMonster::AnimationUpdate(void) m_flAnimTime = 0.0f; if (fr == -1) - act = (frameforaction(modelindex, ACT_RUN)); + act = GetAct("run"); m_iMoveState = MOVESTATE_RUN; } @@ -1584,65 +1576,72 @@ NSMonster::HasBeenHit(void) void NSMonster::Pain(entity inflictor, entity attacker, int damage, vector dir, int location) { - float actSmallFlinch = FramegroupForAct(ACT_SMALL_FLINCH); - float actBigFlinch = FramegroupForAct(ACT_BIG_FLINCH); - float actTwitch = FramegroupForAct(ACT_TWITCH); + float actSmallFlinch = GetAct("smallFlinch"); + float actBigFlinch = GetAct("bigFlinch"); + float actTwitch = GetAct("twitch"); float actPain = -1; float baseHealth = GetSpawnFloat("health"); /* dead things tell nuthin */ - if (IsAlive() == false) + if (IsAlive() == false) { return; - - if (GetHealth() <= (baseHealth / 2)) { - if (IsFriend(g_dmg_eAttacker.m_iAlliance) == true) - m_iAlliance = MAL_ROGUE; } - if (IsFriend(g_dmg_eAttacker.m_iAlliance) == true) + if (GetHealth() <= (baseHealth / 2)) { + if (IsFriend(attacker.m_iAlliance) == true) { + m_iAlliance = MAL_ROGUE; + } + } + + if (IsFriend(attacker.m_iAlliance) == true) { return; + } /* if don't have an enemy, set one; else make it random */ - if (!m_eEnemy || (random() < 0.5)) - m_eEnemy = g_dmg_eAttacker; + if (!m_eEnemy || (random() < 0.5)) { + m_eEnemy = attacker; + } /* an alert monster will take a while to calm back down */ - if (GetState() != MONSTER_ALERT) - if (GetState() != MONSTER_FOLLOWING) - if (GetState() != MONSTER_CHASING) + if (GetState() != MONSTER_ALERT) { + if (GetState() != MONSTER_FOLLOWING) { + if (GetState() != MONSTER_CHASING) { SetState(MONSTER_ALERT); + } + } + } /* alert all nearby friendlies */ AlertNearby(); - switch (g_dmg_iHitBody) { + switch (location) { case BODY_HEAD: - actPain = FramegroupForAct(ACT_FLINCH_HEAD); + actPain = GetAct("flinchHead"); break; case BODY_CHEST: - actPain = FramegroupForAct(ACT_FLINCH_CHEST); + actPain = GetAct("flinchChest"); break; case BODY_STOMACH: - actPain = FramegroupForAct(ACT_FLINCH_STOMACH); + actPain = GetAct("flinchStomach"); break; case BODY_ARMLEFT: - actPain = FramegroupForAct(ACT_FLINCH_LEFTARM); + actPain = GetAct("flinchLeftArm"); break; case BODY_ARMRIGHT: - actPain = FramegroupForAct(ACT_FLINCH_RIGHTARM); + actPain = GetAct("flinchRightArm"); break; case BODY_LEGLEFT: - actPain = FramegroupForAct(ACT_FLINCH_LEFTLEG); + actPain = GetAct("flinchLeftLeg"); break; case BODY_LEGRIGHT: - actPain = FramegroupForAct(ACT_FLINCH_RIGHTLEG); + actPain = GetAct("flinchRightLeg"); break; } /* fallback in case we do not have specialized flinches */ if (actPain == -1) { /* for big damage pain anim, we need to take at least 1/3rd of health */ - if (actBigFlinch >= 0 && g_dmg_iDamage > (baseHealth / 3)) + if (actBigFlinch >= 0 && damage > (baseHealth / 3)) actPain = actBigFlinch; else if (actSmallFlinch >= 0) actPain = actSmallFlinch; @@ -1685,11 +1684,11 @@ NSMonster::Death(entity inflictor, entity attacker, int damage, vector dir, int StartSoundDef(m_sndThud, CHAN_BODY, true); } - float actViolent = FramegroupForAct(ACT_DIEVIOLENT); - float actForward = FramegroupForAct(ACT_DIEFORWARD); - float actBackward = FramegroupForAct(ACT_DIEBACKWARD); - float actSimple = FramegroupForAct(ACT_DIESIMPLE); - float actBackshot = FramegroupForAct(ACT_DIE_BACKSHOT); + float actViolent = GetAct("dieViolent"); + float actForward = GetAct("dieForward"); + float actBackward = GetAct("dieBackward"); + float actSimple = GetAct("dieSimple"); + float actBackshot = GetAct("dieBackshot"); float actDeath = -1; @@ -1711,13 +1710,13 @@ NSMonster::Death(entity inflictor, entity attacker, int damage, vector dir, int switch (g_dmg_iHitBody) { case BODY_HEAD: - actDeath = FramegroupForAct(ACT_DIE_HEADSHOT); + actDeath = GetAct("dieHeadshot"); break; case BODY_CHEST: - actDeath = FramegroupForAct(ACT_DIE_CHESTSHOT); + actDeath = GetAct("dieChestshot"); break; case BODY_STOMACH: - actDeath = FramegroupForAct(ACT_DIE_GUTSHOT); + actDeath = GetAct("dieGutshot"); break; } @@ -1749,8 +1748,9 @@ NSMonster::Death(entity inflictor, entity attacker, int damage, vector dir, int SetState(MONSTER_DEAD); /* monsters trigger their targets when dead */ - if (GetTriggerCondition() == MTRIG_DEATH) + if (GetTriggerCondition() == MTRIG_DEATH) { TriggerTargets(); + } /* play thud sound */ ScheduleThink(Death_Thud, frameduration(modelindex, frame) * 0.5f); @@ -1804,7 +1804,7 @@ NSMonster::Respawn(void) RestoreAngles(); v_angle = fixAngle(GetAngles()); - AddFlags(FL_MONSTER); + flags = FL_MONSTER; MakeVulnerable(); EnableAimAssist(); SetState(MONSTER_IDLE); @@ -1852,9 +1852,10 @@ NSMonster::Respawn(void) } /* automatically start */ - if (!targetname) - if (HasTriggerTarget() == true) { - ScheduleThink(_ChaseAfterSpawn, 0.0f); + if (STRING_SET(targetname)) { + if (HasTriggerTarget() == true) { + ScheduleThink(_ChaseAfterSpawn, 0.0f); + } } } @@ -2108,11 +2109,13 @@ NSMonster::EvaluateEntity(void) float NSMonster::SendEntity(entity ePEnt, float flChanged) { - if (!modelindex) + if (!modelindex) { return (0); + } - if (clienttype(ePEnt) != CLIENTTYPE_REAL) + if (clienttype(ePEnt) != CLIENTTYPE_REAL) { return (0); + } WriteByte(MSG_ENTITY, ENT_MONSTER); @@ -2151,10 +2154,10 @@ NSMonster::SendEntity(entity ePEnt, float flChanged) SENDENTITY_COORD(velocity[2], MONFL_CHANGED_VELOCITY) SENDENTITY_BYTE(m_iRenderMode, MONFL_CHANGED_RENDERMODE) SENDENTITY_BYTE(m_iRenderFX, MONFL_CHANGED_RENDERMODE) - SENDENTITY_COLOR(m_vecRenderColor[0], MONFL_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[1], MONFL_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[2], MONFL_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_flRenderAmt, MONFL_CHANGED_RENDERAMT) + SENDENTITY_BYTE(m_vecRenderColor[0], MONFL_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[1], MONFL_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[2], MONFL_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_flRenderAmt, MONFL_CHANGED_RENDERAMT) SENDENTITY_FLOAT(bonecontrol1, MONFL_CHANGED_HEADYAW) SENDENTITY_FLOAT(subblendfrac, MONFL_CHANGED_HEADYAW) SENDENTITY_FLOAT(frame1time, MONFL_CHANGED_HEADYAW) @@ -2173,11 +2176,8 @@ float NSMonster::predraw(void) { float render; - render = super::predraw(); - _RenderDebugViewCone(); - return render; } @@ -2221,24 +2221,29 @@ NSMonster::ReceiveEntity(float flNew, float flChanged) READENTITY_COORD(velocity[2], MONFL_CHANGED_VELOCITY) READENTITY_BYTE(m_iRenderMode, MONFL_CHANGED_RENDERMODE) READENTITY_BYTE(m_iRenderFX, MONFL_CHANGED_RENDERMODE) - READENTITY_COLOR(m_vecRenderColor[0], MONFL_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[1], MONFL_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[2], MONFL_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_flRenderAmt, MONFL_CHANGED_RENDERAMT) + READENTITY_BYTE(m_vecRenderColor[0], MONFL_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[1], MONFL_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[2], MONFL_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_flRenderAmt, MONFL_CHANGED_RENDERAMT) READENTITY_FLOAT(bonecontrol1, MONFL_CHANGED_HEADYAW) READENTITY_FLOAT(subblendfrac, MONFL_CHANGED_HEADYAW) READENTITY_FLOAT(frame1time, MONFL_CHANGED_HEADYAW) - if (scale == 0.0) + if (scale == 0.0) { scale = 1.0f; + } - if (flChanged & MONFL_CHANGED_SIZE) + if (flChanged & MONFL_CHANGED_SIZE) { setsize(this, mins * scale, maxs * scale); + } - if (flChanged & MONFL_CHANGED_BODY) + if (flChanged & MONFL_CHANGED_BODY) { _UpdateGeomset(); - if (flChanged & MONFL_CHANGED_MODELINDEX) + } + + if (flChanged & MONFL_CHANGED_MODELINDEX) { _UpdateBoneCount(); + } } void @@ -2248,11 +2253,13 @@ NSMonster::_RenderDebugViewCone(void) float flDot; vector testOrg; - if (health <= 0 || solid == SOLID_CORPSE) + if (health <= 0 || GetSolid(SOLID_CORPSE)) { return; + } - if (autocvar(r_showViewCone, 0) == 0) + if (autocvar(r_showViewCone, 0) == 0) { return; + } testOrg = pSeat->m_ePlayer.origin; v = normalize(testOrg - GetEyePos()); @@ -2283,25 +2290,16 @@ void NSMonster_AlertEnemyAlliance(vector pos, float radius, int alliance) { /* sometimes many alert-sounds happen at once... we don't really want that */ - if (g_monsteralert_timer > time) + if (g_monsteralert_timer > time) { return; + } if (autocvar_ai_debugAlerts) NSLog("AI alert from %v with radius %f and alliance %i", pos, radius, alliance); + /* always check for the fastest-to-check attributes first here */ for (entity w = world; (w = nextent(w));) { - if (w.takedamage == DAMAGE_NO) - continue; - - /* out of radius */ - if (vlen(pos - w.origin) > radius) { - continue; - } - - /* only target monsters */ - if (!(w.flags & FL_MONSTER)) { - if (autocvar_ai_debugAlerts) - NSLog("\t%S is not a monster", w.classname); + if (isAI(w) == false) { continue; } @@ -2322,14 +2320,20 @@ NSMonster_AlertEnemyAlliance(vector pos, float radius, int alliance) } /* if the monster is dead... ignore */ - if (f.health <= 0) { + if (f.IsAlive() == false) { if (autocvar_ai_debugAlerts) NSLog("\t%S is dead, cannot be alerted", w.classname); continue; } - if (autocvar_ai_debugAlerts) - NSLog("\twe're alerting %S to go to %v", w.classname, pos); + /* expensive, out of radius */ + if (distance(pos, w.origin) > radius) { + continue; + } + + if (autocvar_ai_debugAlerts) { + NSLog("\twe're alerting %S to go to %v", w.classname, pos); + } /* we've heard a noise. investigate the location */ f.RouteClear(); @@ -2341,7 +2345,9 @@ NSMonster_AlertEnemyAlliance(vector pos, float radius, int alliance) g_monsteralert_timer = time + 0.5f; } -entity NSMonster_FindClosestPlayer(entity target) { +entity +NSMonster_FindClosestPlayer(entity target) +{ NSMonster t = (NSMonster)target; entity best = world; float bestdist; @@ -2351,10 +2357,11 @@ entity NSMonster_FindClosestPlayer(entity target) { for (entity e = world; (e = find(e, classname, "player"));) { /* hack: don't ever return dead players. they're invisible. */ - if (!t.IsValidEnemy(e)) + if (t.IsValidEnemy(e) == false) { continue; + } - dist = vlen(target.origin - e.origin); + dist = distance(target.origin, e.origin); if (dist < bestdist) { bestdist = dist; diff --git a/src/shared/NSNavAI.h b/src/shared/NSNavAI.h index bf9b86b8..cb5a1904 100644 --- a/src/shared/NSNavAI.h +++ b/src/shared/NSNavAI.h @@ -182,6 +182,7 @@ private: float m_flMoveSpeedKey; #endif + float nadeCookingTime; /* These are defined in side defs\*.def, ammo_types and ammo_names */ int m_iAmmoTypes[MAX_AMMO_TYPES]; NSWeapon m_activeWeapon_net; diff --git a/src/shared/NSPhysicsEntity.qc b/src/shared/NSPhysicsEntity.qc index 4dbc3839..937f3a9b 100644 --- a/src/shared/NSPhysicsEntity.qc +++ b/src/shared/NSPhysicsEntity.qc @@ -259,14 +259,14 @@ NSPhysicsEntity::SendEntity(entity ePEnt, float flChanged) SENDENTITY_COORD(avelocity[2], RDENT_CHANGED_ANGULARVELOCITY) SENDENTITY_BYTE(m_iRenderMode, RDENT_CHANGED_RENDERMODE) SENDENTITY_BYTE(m_iRenderFX, RDENT_CHANGED_RENDERMODE) - SENDENTITY_COLOR(m_vecRenderColor[0], RDENT_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[1], RDENT_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[2], RDENT_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[0], RDENT_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[1], RDENT_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[2], RDENT_CHANGED_RENDERCOLOR) /* these need more precision for shader hacks... */ SENDENTITY_FLOAT(glowmod[0], RDENT_CHANGED_RENDERCOLOR) SENDENTITY_FLOAT(glowmod[1], RDENT_CHANGED_RENDERCOLOR) SENDENTITY_FLOAT(glowmod[2], RDENT_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_flRenderAmt, RDENT_CHANGED_RENDERAMT) + SENDENTITY_BYTE(m_flRenderAmt, RDENT_CHANGED_RENDERAMT) SENDENTITY_ANGLE(m_flBoneControl1, RDENT_CHANGED_CONTROLLER) SENDENTITY_ANGLE(m_flBoneControl2, RDENT_CHANGED_CONTROLLER) SENDENTITY_ANGLE(m_flBoneControl3, RDENT_CHANGED_CONTROLLER) @@ -323,14 +323,14 @@ NSPhysicsEntity::ReceiveEntity(float flNew, float flChanged) READENTITY_COORD(avelocity[2], RDENT_CHANGED_ANGULARVELOCITY) READENTITY_BYTE(m_iRenderMode, RDENT_CHANGED_RENDERMODE) READENTITY_BYTE(m_iRenderFX, RDENT_CHANGED_RENDERMODE) - READENTITY_COLOR(m_vecRenderColor[0], RDENT_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[1], RDENT_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[2], RDENT_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[0], RDENT_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[1], RDENT_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[2], RDENT_CHANGED_RENDERCOLOR) /* these need more precision for shader hacks... */ READENTITY_FLOAT(glowmod[0], RDENT_CHANGED_RENDERCOLOR) READENTITY_FLOAT(glowmod[1], RDENT_CHANGED_RENDERCOLOR) READENTITY_FLOAT(glowmod[2], RDENT_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_flRenderAmt, RDENT_CHANGED_RENDERAMT) + READENTITY_BYTE(m_flRenderAmt, RDENT_CHANGED_RENDERAMT) READENTITY_ANGLE(m_flBoneControl1, RDENT_CHANGED_CONTROLLER) READENTITY_ANGLE(m_flBoneControl2, RDENT_CHANGED_CONTROLLER) READENTITY_ANGLE(m_flBoneControl3, RDENT_CHANGED_CONTROLLER) @@ -420,6 +420,29 @@ NSPhysicsEntity_Contents(vector org) void NSPhysicsEntity::Touch(entity eToucher) { + /* if we're being held by a player, don't do anything funny! */ + if (owner) { + return; + } + + if (GetHealth() <= 0) { + return; + } + + if (IsAsleep() == true) { + return; + } + + float impactForce = length(GetVelocity()) * 0.01; + + if (impactForce > GetHealth()) { + NSDict damageDecl = spawn(NSDict); + damageDecl.AddKey("damage", ftos(impactForce)); + Damage(eToucher, eToucher, damageDecl, 1.0f, g_vec_null, GetOrigin()); + remove(damageDecl); + printf("New health: %d, impact force: %d\n", health, impactForce); + } + if (eToucher) if (eToucher.movetype) Wake(); @@ -429,31 +452,29 @@ NSPhysicsEntity::Touch(entity eToucher) void NSPhysicsEntity::_TouchThink(void) { - if (!m_iEnabled) { + if (IsAsleep() == true) { return; } - if (physics_supported() == FALSE) { - /* let players collide */ - dimension_solid = 255; - dimension_hit = 255; + if (physics_supported() == FALSE && GetSolid() != SOLID_TRIGGER) { + EnablePlayerCollision(); - tracebox(origin, mins, maxs, origin, FALSE, this); + tracebox(origin, mins, maxs, origin, FALSE, this); - /* stuck */ - if (trace_startsolid) { - if (trace_ent.flags & FL_CLIENT) { - if (trace_ent.absmin[2] < absmax[2]) { - vector dirVec = trace_endpos - trace_ent.origin; - Wake(); - ApplyTorqueCenter(anglesToForward(vectorToAngles(dirVec)) * 240); - } else { - Sleep(); - velocity = [0,0,0]; + /* stuck */ + if (trace_startsolid) { + if (trace_ent.flags & FL_CLIENT) { + if (trace_ent.absmin[2] < absmax[2]) { + vector dirVec = trace_endpos - trace_ent.origin; + Wake(); + ApplyTorqueCenter(anglesToForward(vectorToAngles(dirVec)) * 240); + } else { + Sleep(); + velocity = [0,0,0]; + } } } } - } #if 1 if (m_flCheckTime < time) { @@ -500,10 +521,8 @@ NSPhysicsEntity::_TouchThink(void) hitcontentsmaski &= ~CONTENTBITS_FLUID; - if (physics_supported() == FALSE) { - /* don't let players collide */ - dimension_solid = 1; - dimension_hit = 1; + if (physics_supported() == FALSE && GetSolid() != SOLID_TRIGGER) { + DisablePlayerCollision(); } /* continue testing next frame */ @@ -587,10 +606,8 @@ NSPhysicsEntity::Respawn(void) hitcontentsmaski &= ~CONTENTBITS_FLUID; - if (physics_supported() == FALSE) { - /* don't let players collide */ - dimension_solid = 1; - dimension_hit = 1; + if (physics_supported() == FALSE && GetSolid() != SOLID_TRIGGER) { + DisablePlayerCollision(); } think = _TouchThink; @@ -847,7 +864,7 @@ NSPhysicsEntity::GetVolume(void) bool NSPhysicsEntity::IsAsleep(void) { - return false; + return (m_iEnabled) ? (false) : (true); } bool diff --git a/src/shared/NSProjectile.h b/src/shared/NSProjectile.h index 8125c495..1b85ca7d 100644 --- a/src/shared/NSProjectile.h +++ b/src/shared/NSProjectile.h @@ -44,7 +44,7 @@ Objects such as rockets, grenades, bolts etc. should ideally be this. @ingroup baseclass */ -class NSProjectile:NSSurfacePropEntity +class NSProjectile:NSAttack { public: void NSProjectile(void); @@ -136,6 +136,7 @@ private: string m_matDetonate; float m_flDecalSize; string m_partSmokeFly; + string m_partFXPath; string m_partModelDetonate; string m_partSmokeDetonate; string m_partSmokeBounce; @@ -145,6 +146,7 @@ private: bool m_bDebrisStick; vector m_vecDebrisOffset; vector m_vecImpactPos; + bool m_bThrown; float m_flLightOffset; /* TODO */ vector m_vecExplodeLightColor; /* TODO */ diff --git a/src/shared/NSProjectile.qc b/src/shared/NSProjectile.qc index a27df6e3..272c5d9c 100644 --- a/src/shared/NSProjectile.qc +++ b/src/shared/NSProjectile.qc @@ -43,6 +43,7 @@ NSProjectile::NSProjectile(void) m_matDetonate = __NULL__; m_flDecalSize = 0.0f; m_partSmokeFly = __NULL__; + m_partFXPath = __NULL__; m_partModelDetonate = __NULL__; m_partSmokeDetonate = __NULL__; m_partSmokeBounce = __NULL__; @@ -159,6 +160,9 @@ NSProjectile::SpawnKey(string strKey, string strValue) case "smoke_fly": m_partSmokeFly = ReadString(strValue); break; + case "fx_path": + m_partFXPath = ReadString(strValue); + break; case "model_detonate": m_partModelDetonate = ReadString(strValue); break; @@ -268,6 +272,9 @@ NSProjectile::SpawnKey(string strKey, string strValue) case "damage": m_flDamage = ReadFloat(strValue); break; + case "thrown": + m_bThrown = ReadBool(strValue); + break; default: super::SpawnKey(strKey, strValue); break; @@ -303,6 +310,7 @@ NSProjectile::Save(float handle) SaveString(handle, "m_matDetonate", m_matDetonate); SaveFloat(handle, "m_flDecalSize", m_flDecalSize); SaveString(handle, "m_partSmokeFly", m_partSmokeFly); + SaveString(handle, "m_partFXPath", m_partFXPath); SaveString(handle, "m_partModelDetonate", m_partModelDetonate); SaveString(handle, "m_partSmokeDetonate", m_partSmokeDetonate); SaveString(handle, "m_partSmokeBounce", m_partSmokeBounce); @@ -327,6 +335,7 @@ NSProjectile::Save(float handle) SaveEntity(handle, "m_thrustHandler", m_thrustHandler); SaveFloat(handle, "m_flSpawnFrame", m_flSpawnFrame); SaveBool(handle, "m_bInheritVelocity", m_bInheritVelocity); + SaveBool(handle, "m_bThrown", m_bThrown); } void @@ -405,6 +414,9 @@ NSProjectile::Restore(string strKey, string strValue) case "m_partSmokeFly": m_partSmokeFly = ReadString(strValue); break; + case "m_partFXPath": + m_partFXPath = ReadString(strValue); + break; case "m_partModelDetonate": m_partModelDetonate = ReadString(strValue); break; @@ -477,6 +489,9 @@ NSProjectile::Restore(string strKey, string strValue) case "m_bInheritVelocity": m_bInheritVelocity = ReadBool(strValue); break; + case "m_bThrown": + m_bThrown = ReadBool(strValue); + break; default: super::Restore(strKey, strValue); break; @@ -724,6 +739,10 @@ NSProjectile::_Explode(entity explodedOn) explodePos = origin - (aimFwd * 32); } + if (m_fExplodelLightRadius > 0.0f) { + te_customflash(explodePos, m_fExplodelLightRadius, m_fExplodelLightFadetime, m_vecExplodeLightColor); + } + if (m_matDetonate) { DecalGroups_Place(m_matDetonate, origin); } @@ -772,6 +791,10 @@ NSProjectile::_LaunchHitscan(vector startPos, vector launchDir, float dmgMultipl ownerAngle = anglesToForward(launchDir); ownerDir = aim(owner, 100000); + if (STRING_SET(m_defDamage)) { + m_flDamage = GetSubDefFloat(m_defDamage, "damage"); + } + while (m_iShots > 0) { /* use cached value */ v_forward = ownerAngle; @@ -810,6 +833,12 @@ NSProjectile::_ApplyDamage(void) trace_surface_id = m_iMultiBody; g_dmg_vecLocation = trace_endpos; NSDict damageDecl = spawn(NSDict); + + if (STRING_SET(m_defDamage)) { + int declID = EntityDef_IDFromName(m_defDamage); + damageDecl.InitWithSpawnData(EntityDef_GetSpawnData(declID)); + } + damageDecl.AddKey("hitbody", itos(trace_surface_id)); damageDecl.AddKey("damage", itos(m_iMultiValue)); vector dmgDir = normalize(angles); @@ -856,6 +885,10 @@ NSProjectile::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float m_iMultiBody |= trace_surface_id; + if (STRING_SET(m_partFXPath)) { + trailparticles(particleeffectnum(m_partFXPath), world, vecPos, trace_endpos); + } + if (trace_fraction >= 1.0f) return; @@ -888,6 +921,8 @@ NSProjectile::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float /* impact per bullet */ if (m_bDetonateOnWorld == true && trace_ent.iBleeds == 0) { + StartSoundDef(m_sndExplode, CHAN_VOICE, true); + if (m_strDecalGroup) DecalGroups_Place(m_strDecalGroup, endPos + (vecAngles * -2)); @@ -959,11 +994,6 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float { vector moveVel = g_vec_null; - if (m_bIsBullet) { - _LaunchHitscan(startPos, launchDir, dmgMultiplier); - return; - } - SetAngles(launchDir); SetSize(m_vecSpawnMins, m_vecSpawnMaxs); @@ -986,8 +1016,32 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float startPos += v_up * m_vecSpawnOrigin[2]; SetOrigin(startPos); - if (m_bInheritVelocity == true) + if (m_bIsBullet) { + _LaunchHitscan(startPos, launchDir, dmgMultiplier); + return; + } + + if (m_bInheritVelocity == true) { moveVel += owner.velocity; + } + + if (m_bThrown) { + vector throwDirection; + float throwingStrength; + + throwDirection = launchDir; + throwDirection[0] = -10.0f; /* always aim a bit up */ + + /* diminish when aiming up */ + if (launchDir[0] < 0) { + throwDirection[0] += (launchDir[0] * 0.9f); + } else { /* increase when aiming down */ + throwDirection[0] += (launchDir[0] * 1.1f); + } + + throwingStrength = bound(0, (90 - throwDirection[0]) * 5.0f, 1000); + moveVel = (v_forward * throwingStrength) + owner.velocity; + } /* fire slower underwater */ if (pointcontents(startPos) == CONTENT_WATER) { @@ -1007,7 +1061,7 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float SetMovetype(MOVETYPE_FLYMISSILE); } - if (m_partSmokeFly) { + if (STRING_SET(m_partSmokeFly)) { traileffectnum = particleeffectnum(m_partSmokeFly); } @@ -1025,7 +1079,25 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float m_thrustHandler = NSTimer::TemporaryTimer(this, _ThrustThink, 0.0, true); } - SetFrame(m_flSpawnFrame); + string startFrame = GetSpawnString("animStartFrame"); + + if (STRING_SET(startFrame)) { + int iStartFrame = stoi(startFrame); + int iEndFrame = GetSpawnInt("animEndFrame"); + float flFrameRate = (1 / GetSpawnFloat("animFrameRate")); + bool animEndRemoves = GetSpawnInt("animEndRemoves"); + + SetFrame((float)iStartFrame); + + if (animEndRemoves) { + AnimateOnce(iStartFrame, iEndFrame, flFrameRate); + } else { + Animate(iStartFrame, iEndFrame, flFrameRate); + } + } else { + SetFrame(m_flSpawnFrame); + } + SetGravity(m_flGravity); StartSoundDef(m_sndFly, CHAN_BODY, true); SendFlags = (-1); @@ -1079,10 +1151,10 @@ NSProjectile::SendEntity(entity ePEnt, float flChanged) SENDENTITY_FLOAT(traileffectnum, PROJ_CHANGED_MODELINDEX) SENDENTITY_BYTE(m_iRenderMode, PROJ_CHANGED_RENDERMODE) SENDENTITY_BYTE(m_iRenderFX, PROJ_CHANGED_RENDERMODE) - SENDENTITY_COLOR(m_vecRenderColor[0], PROJ_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[1], PROJ_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[2], PROJ_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_flRenderAmt, PROJ_CHANGED_RENDERAMT) + SENDENTITY_BYTE(m_vecRenderColor[0], PROJ_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[1], PROJ_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[2], PROJ_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_flRenderAmt, PROJ_CHANGED_RENDERAMT) SENDENTITY_COLOR(m_vecLightColor[0], PROJ_CHANGED_RENDERCOLOR) SENDENTITY_COLOR(m_vecLightColor[1], PROJ_CHANGED_RENDERCOLOR) SENDENTITY_COLOR(m_vecLightColor[2], PROJ_CHANGED_RENDERCOLOR) @@ -1108,10 +1180,10 @@ NSProjectile::ReceiveEntity(float flNew, float flChanged) READENTITY_FLOAT(traileffectnum, PROJ_CHANGED_MODELINDEX) READENTITY_BYTE(m_iRenderMode, PROJ_CHANGED_RENDERMODE) READENTITY_BYTE(m_iRenderFX, PROJ_CHANGED_RENDERMODE) - READENTITY_COLOR(m_vecRenderColor[0], PROJ_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[1], PROJ_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[2], PROJ_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_flRenderAmt, PROJ_CHANGED_RENDERAMT) + READENTITY_BYTE(m_vecRenderColor[0], PROJ_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[1], PROJ_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[2], PROJ_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_flRenderAmt, PROJ_CHANGED_RENDERAMT) READENTITY_COLOR(m_vecLightColor[0], PROJ_CHANGED_RENDERCOLOR) READENTITY_COLOR(m_vecLightColor[1], PROJ_CHANGED_RENDERCOLOR) READENTITY_COLOR(m_vecLightColor[2], PROJ_CHANGED_RENDERCOLOR) @@ -1132,8 +1204,8 @@ NSProjectile::predraw(void) trailparticles(traileffectnum, this, oldorigin, origin); } oldorigin = origin; - - return super::predraw(); + + return NSRenderableEntity::predraw(); } #endif diff --git a/src/shared/NSRenderableEntity.qc b/src/shared/NSRenderableEntity.qc index dbe54bf4..5d24729d 100644 --- a/src/shared/NSRenderableEntity.qc +++ b/src/shared/NSRenderableEntity.qc @@ -14,17 +14,15 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - - void NSRenderableEntity::NSRenderableEntity(void) { m_iRenderMode = RM_NORMAL; m_iRenderFX = RFX_NORMAL; - m_vecRenderColor[0] = 1.0f; - m_vecRenderColor[1] = 1.0f; - m_vecRenderColor[2] = 1.0f; - m_flRenderAmt = 0.0f; + m_vecRenderColor[0] = 255; + m_vecRenderColor[1] = 255; + m_vecRenderColor[2] = 255; + m_flRenderAmt = 0; m_flBoneControl1 = 0.5f; m_flBoneControl2 = 0.5f; m_flBoneControl3 = 0.5f; @@ -43,7 +41,6 @@ NSRenderableEntity::NSRenderableEntity(void) #endif } - #ifdef CLIENT void NSRenderableEntity::RendererRestarted( void ) { _UpdateGeomset(); @@ -333,8 +330,8 @@ NSRenderableEntity::RenderFXPass(void) /* HACK: this tells our GLSL to render this masked */ //glowmod = [1.0,0.0,1.0]; - colormod = m_vecRenderColor; - alpha = m_flRenderAmt; + colormod = m_vecRenderColor / 255; + alpha = m_flRenderAmt / 255; /* these should be reset! */ renderflags = 0; @@ -360,8 +357,8 @@ NSRenderableEntity::RenderFXPass(void) break; case RM_GLOW: - colormod = m_vecRenderColor; - alpha = m_flRenderAmt == 0.0 ? 0.0f : 1.0f; + colormod = m_vecRenderColor / 255; + alpha = (m_flRenderAmt == 0) ? 0.0f : 1.0f; case RM_WORLDGLOW: /* TODO: Figure out what this does differently */ if (checkpvs(vecPlayer, this) == FALSE) alpha -= clframetime; @@ -376,7 +373,7 @@ NSRenderableEntity::RenderFXPass(void) alpha += clframetime; /* max alpha will be applied here to the color instead */ - colormod *= m_flRenderAmt; + colormod *= (m_flRenderAmt / 255); alpha = bound(0.0f, alpha, 1.0f); effects = EF_ADDITIVE | EF_FULLBRIGHT; @@ -386,7 +383,7 @@ NSRenderableEntity::RenderFXPass(void) break; case RM_SOLID: colormod = [1,1,1]; - alpha = m_flRenderAmt == 0.0 ? 0.0f : 1.0f; + alpha = (m_flRenderAmt == 0) ? 0.0f : 1.0f; glowmod[0] = 0.5f; break; case RM_ADDITIVE: @@ -473,7 +470,7 @@ NSRenderableEntity::RenderFXPass(void) float distalpha = dist / 256; alpha = 1.0 - distalpha; alpha -= r; - alpha *= m_flRenderAmt; + alpha *= (m_flRenderAmt / 255); } else { alpha = 0.00001f; } @@ -486,9 +483,9 @@ NSRenderableEntity::RenderFXPass(void) /* make this entity shellchrome */ effects = EF_ADDITIVE; fatness = 0; - colormod = m_vecRenderColor; + colormod = (m_vecRenderColor / 255); forceshader = g_shellchromeshader_cull; - alpha = m_flRenderAmt; + alpha = (m_flRenderAmt / 255); /* copy entity into rendering queue */ addentity(this); /* reset */ @@ -502,9 +499,9 @@ NSRenderableEntity::RenderFXPass(void) /* make this entity shellchrome */ effects = EF_ADDITIVE; fatness = 0; - colormod = m_vecRenderColor; + colormod = (m_vecRenderColor / 255); forceshader = g_shellchromeshader; - alpha = m_flRenderAmt; + alpha = (m_flRenderAmt / 255); /* copy entity into rendering queue */ addentity(this); /* reset */ @@ -625,7 +622,9 @@ NSRenderableEntity::predraw(void) RenderDebugSkeleton(); if (modelflags & MF_ROTATE) { - angles[1] -= frametime * 120.0; + angles[1] = g_modelSpinAngle; + angles[2] = g_modelSpinRoll; + angles[0] = g_modelSpinPitch; } processmodelevents(modelindex, frame, m_flBaseTime, @@ -633,6 +632,13 @@ NSRenderableEntity::predraw(void) RenderAxialScale(); + vector oldOrg = origin; + + /* TODO: make this a separate field */ + if (modelflags & MF_ROTATE) { + origin[2] += g_modelBobHeight; + } + if (alpha > 0.0) { /* TODO: Move this somewhere more sane */ if (m_iRenderFX == RFX_Q2PULSE) { @@ -643,6 +649,7 @@ NSRenderableEntity::predraw(void) addentity(this); } } + origin = oldOrg; if (traileffectnum) { if (oldorigin != g_vec_null) @@ -837,8 +844,9 @@ void NSRenderableEntity::SetRenderColor(vector newColor) { /* rendercolor can NEVER be pitch black. */ - if (newColor == g_vec_null) - m_vecRenderColor = [1.0, 1.0, 1.0]; + if (newColor == g_vec_null) { + m_vecRenderColor = [255, 255, 255]; + } m_vecRenderColor = newColor; } @@ -1117,10 +1125,10 @@ NSRenderableEntity::Input(entity eAct, string strInput, string strData) { switch (strInput) { case "Color": - SetRenderColor(stov(strData) / 255); + SetRenderColor(stov(strData)); break; case "Alpha": - SetRenderAmt(stof(strData) / 255); + SetRenderAmt(stof(strData)); break; case "Skin": SetSkin(stof(strData)); @@ -1181,8 +1189,8 @@ NSRenderableEntity::SpawnKey(string strKey, string strValue) m_vecAxialScale = ReadVector(strValue); break; case "lightingPrecalc": - m_vecRenderColor = ReadVector(strValue); - m_flRenderAmt = 1.0f; + m_vecRenderColor = ReadVector(strValue) * 255; + m_flRenderAmt = 255; break; case "skin": skin = ReadFloat(strValue); @@ -1199,10 +1207,10 @@ NSRenderableEntity::SpawnKey(string strKey, string strValue) } break; case "renderamt": - m_flRenderAmt = ReadFloat(strValue) / 255; + m_flRenderAmt = ReadFloat(strValue); break; case "rendercolor": - m_vecRenderColor = ReadVector(strValue) / 255; + m_vecRenderColor = ReadVector(strValue); break; case "rendermode": m_iRenderMode = ReadFloat(strValue); @@ -1215,3 +1223,9 @@ NSRenderableEntity::SpawnKey(string strKey, string strValue) break; } } + +float +NSRenderableEntity::PlayActOnChannel(float animChannel, string activityName) +{ + +} diff --git a/src/shared/NSSurfacePropEntity.qc b/src/shared/NSSurfacePropEntity.qc index d48c8f7d..c7662192 100644 --- a/src/shared/NSSurfacePropEntity.qc +++ b/src/shared/NSSurfacePropEntity.qc @@ -242,6 +242,7 @@ NSSurfacePropEntity::Damage(entity inflictor, entity attacker, NSDict damageDecl } string damageString = ReadString(damageDecl.GetString("damage")); + float knockBack = damageDecl.GetFloat("knockback"); #if 0 float randomDamage = GetSubDefFloat(m_defDamage, "damage_random"); @@ -253,6 +254,11 @@ NSSurfacePropEntity::Damage(entity inflictor, entity attacker, NSDict damageDecl EntLog("applying %d damage by %s", damagePoints, attacker.classname); + /* apply knockback */ + if (knockBack >= 0) { + SetVelocity(dmgDir * knockBack); + } + /* notify them */ if (isSentient(attacker)) { ourAttacker.DamageFeedback(this, inflictor, damagePoints); @@ -696,10 +702,10 @@ NSSurfacePropEntity::SendEntity(entity ePEnt, float flChanged) SENDENTITY_COORD(avelocity[2], SRFENT_CHANGED_ANGULARVELOCITY) SENDENTITY_BYTE(m_iRenderMode, SRFENT_CHANGED_RENDERMODE) SENDENTITY_BYTE(m_iRenderFX, SRFENT_CHANGED_RENDERMODE) - SENDENTITY_COLOR(m_vecRenderColor[0], SRFENT_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[1], SRFENT_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[2], SRFENT_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_flRenderAmt, SRFENT_CHANGED_RENDERAMT) + SENDENTITY_BYTE(m_vecRenderColor[0], SRFENT_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[1], SRFENT_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[2], SRFENT_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_flRenderAmt, SRFENT_CHANGED_RENDERAMT) SENDENTITY_ANGLE(m_flBoneControl1, SRFENT_CHANGED_CONTROLLER) SENDENTITY_ANGLE(m_flBoneControl2, SRFENT_CHANGED_CONTROLLER) SENDENTITY_ANGLE(m_flBoneControl3, SRFENT_CHANGED_CONTROLLER) @@ -750,10 +756,10 @@ NSSurfacePropEntity::ReceiveEntity(float flNew, float flChanged) READENTITY_COORD(avelocity[2], SRFENT_CHANGED_ANGULARVELOCITY) READENTITY_BYTE(m_iRenderMode, SRFENT_CHANGED_RENDERMODE) READENTITY_BYTE(m_iRenderFX, SRFENT_CHANGED_RENDERMODE) - READENTITY_COLOR(m_vecRenderColor[0], SRFENT_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[1], SRFENT_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[2], SRFENT_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_flRenderAmt, SRFENT_CHANGED_RENDERAMT) + READENTITY_BYTE(m_vecRenderColor[0], SRFENT_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[1], SRFENT_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[2], SRFENT_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_flRenderAmt, SRFENT_CHANGED_RENDERAMT) READENTITY_ANGLE(m_flBoneControl1, SRFENT_CHANGED_CONTROLLER) READENTITY_ANGLE(m_flBoneControl2, SRFENT_CHANGED_CONTROLLER) READENTITY_ANGLE(m_flBoneControl3, SRFENT_CHANGED_CONTROLLER) diff --git a/src/shared/NSTalkMonster.qc b/src/shared/NSTalkMonster.qc index 91ca6c6c..6976b0a6 100644 --- a/src/shared/NSTalkMonster.qc +++ b/src/shared/NSTalkMonster.qc @@ -944,10 +944,10 @@ NSTalkMonster::SendEntity(entity ePEnt, float flChanged) SENDENTITY_COORD(velocity[2], MONFL_CHANGED_VELOCITY) SENDENTITY_BYTE(m_iRenderMode, MONFL_CHANGED_RENDERMODE) SENDENTITY_BYTE(m_iRenderFX, MONFL_CHANGED_RENDERMODE) - SENDENTITY_COLOR(m_vecRenderColor[0], MONFL_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[1], MONFL_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_vecRenderColor[2], MONFL_CHANGED_RENDERCOLOR) - SENDENTITY_COLOR(m_flRenderAmt, MONFL_CHANGED_RENDERAMT) + SENDENTITY_BYTE(m_vecRenderColor[0], MONFL_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[1], MONFL_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_vecRenderColor[2], MONFL_CHANGED_RENDERCOLOR) + SENDENTITY_BYTE(m_flRenderAmt, MONFL_CHANGED_RENDERAMT) SENDENTITY_FLOAT(bonecontrol1, MONFL_CHANGED_HEADYAW) SENDENTITY_FLOAT(subblendfrac, MONFL_CHANGED_HEADYAW) SENDENTITY_FLOAT(frame1time, MONFL_CHANGED_HEADYAW) @@ -1175,10 +1175,10 @@ NSTalkMonster::ReceiveEntity(float flNew, float flChanged) READENTITY_COORD(velocity[2], MONFL_CHANGED_VELOCITY) READENTITY_BYTE(m_iRenderMode, MONFL_CHANGED_RENDERMODE) READENTITY_BYTE(m_iRenderFX, MONFL_CHANGED_RENDERMODE) - READENTITY_COLOR(m_vecRenderColor[0], MONFL_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[1], MONFL_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_vecRenderColor[2], MONFL_CHANGED_RENDERCOLOR) - READENTITY_COLOR(m_flRenderAmt, MONFL_CHANGED_RENDERAMT) + READENTITY_BYTE(m_vecRenderColor[0], MONFL_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[1], MONFL_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_vecRenderColor[2], MONFL_CHANGED_RENDERCOLOR) + READENTITY_BYTE(m_flRenderAmt, MONFL_CHANGED_RENDERAMT) READENTITY_FLOAT(bonecontrol1, MONFL_CHANGED_HEADYAW) READENTITY_FLOAT(subblendfrac, MONFL_CHANGED_HEADYAW) READENTITY_FLOAT(frame1time, MONFL_CHANGED_HEADYAW) diff --git a/src/shared/NSWeapon.h b/src/shared/NSWeapon.h index 838dc9e9..a9bbfe98 100644 --- a/src/shared/NSWeapon.h +++ b/src/shared/NSWeapon.h @@ -182,7 +182,10 @@ public: virtual float SendEntity(entity,float); #endif + virtual bool TestFireAbility(string); + #ifdef CLIENT + virtual void UpdateViewmodel(void); virtual void ClientFX(bool); virtual void PredictPreFrame(void); virtual void PredictPostFrame(void); @@ -306,7 +309,6 @@ private: int m_secondaryAmmoType; float m_muzzleModelIndex; float m_altMuzzleModelIndex; - string m_meleeDef; float m_flPrimedFuse; float m_flTriggerDelay; float m_flZoomFOV; @@ -317,6 +319,7 @@ private: float m_jointTrailView; float m_flSpeedMod; bool m_bAltModeSwitch; + bool m_bBuggyIdleAnim; float m_nextWeapon_entnum; float m_prevWeapon_entnum; @@ -328,6 +331,7 @@ private: float m_fiMeleeRange; vector m_fiPunchAngle; string m_fiSndFire; + string m_fiSndFailed; string m_fiSndFireLast; string m_fiSndRelease; string m_fiSndEmpty; diff --git a/src/shared/NSWeapon.qc b/src/shared/NSWeapon.qc index abace5d5..748f27ff 100644 --- a/src/shared/NSWeapon.qc +++ b/src/shared/NSWeapon.qc @@ -44,6 +44,7 @@ NSWeapon::NSWeapon(void) m_flReloadSpeed = -1.0f; m_nextWeapon = __NULL__; m_prevWeapon = __NULL__; + m_fiMeleeRange = 0.0f; } void @@ -131,6 +132,7 @@ NSWeapon::UpdateFireInfoCache(void) m_fiMeleeRange = GetSubDefFloat(m_strLastFireInfo, "melee_distance"); m_fiPunchAngle = GetSubDefVector(m_strLastFireInfo, "punchAngle"); m_fiSndFire = GetSubDefString(m_strLastFireInfo, "snd_fire"); + m_fiSndFailed = GetSubDefString(m_strLastFireInfo, "snd_fireFailed"); m_fiSndFireLast = GetSubDefString(m_strLastFireInfo, "snd_fireLast"); m_fiSndRelease = GetSubDefString(m_strLastFireInfo, "snd_release"); m_fiSndEmpty = GetSubDefString(m_strLastFireInfo, "snd_empty"); @@ -151,7 +153,7 @@ NSWeapon::UpdateFireInfoCache(void) m_fiSndFireLoop = GetSubDefString(m_strLastFireInfo, "snd_fireLoop"); /* only check if it's present. */ - m_bHasLoop = GetSubDefBool(m_strLastFireInfo, "actLoop"); + m_bHasLoop = GetSubDefBool(m_strLastFireInfo, "loop"); /* keep the last valid value (don't 0.0f it) to prevent overlay dropouts. */ if (m_fiOverheatPoints) { @@ -371,6 +373,10 @@ NSWeapon::Restore(string strKey, string strValue) float NSWeapon::SendEntity(entity ePEnt, float flChanged) { + if (InInventory() == false) { + return NSItem::SendEntity(ePEnt, flChanged); + } + /* item is in somebody elses inventory. */ if (InInventory() == true && ePEnt != GetOwner()) { return (false); @@ -551,14 +557,7 @@ NSWeapon::ReceiveEntity(float flNew, float flChanged) NSActor ourOwner = (NSActor)findfloat(world, ::entnum, owner_entnum); if (ourOwner.m_activeWeapon == this) { - NSRenderableEntity viewModel = (NSRenderableEntity)pSeat->m_eViewModel; - - if (viewModel) { - if (viewModel.modelindex != m_viewModel) { - viewModel.modelindex = m_viewModel; - viewModel._UpdateBoneCount(); - } - } + UpdateViewmodel(); } if (flChanged & WEAPONFL_CHANGED_MODELINDEX) { @@ -689,6 +688,7 @@ NSWeapon::_CacheWeaponDefVariables(void) /* movement vars */ m_flSpeedMod = GetDefFloat("speed_mod"); + m_bBuggyIdleAnim = GetDefBool("buggyIdleAnim"); if (m_flSpeedMod <= 0.0) { m_flSpeedMod = 1.0f; @@ -699,8 +699,6 @@ NSWeapon::_CacheWeaponDefVariables(void) big in the game state changes. like a save/load. */ m_primaryFireInfo = GetDefString("def_fireInfo"); m_secondaryFireInfo = GetDefString("def_altFireInfo"); - /* MIGRATE INTO FIREINFO */ - m_meleeDef = GetDefString("def_melee"); if (!m_primaryFireInfo) { m_primaryFireInfo = classname; @@ -753,6 +751,7 @@ NSWeapon::_SwitchedToCallback(void) Draw(); #ifdef CLIENT + pSeat->m_iHUDWeaponSelected = GetSharedID(); PredictPreFrame(); #endif } @@ -799,32 +798,54 @@ NSWeapon::IsEmpty(void) return (false); } +#ifdef CLIENT +.float vw_index; +void +NSWeapon::UpdateViewmodel(void) +{ + if (pSeat != __NULL__) { + NSRenderableEntity viewModel = (NSRenderableEntity)pSeat->m_eViewModel; + NSRenderableEntity viewModel2 = (NSRenderableEntity)pSeat->m_eViewModelL; + + if (viewModel && viewModel.classname == "vm") { + string viewModelPath2 = GetSubDefString(m_primaryFireInfo, "model_view2"); + string viewModelPath3 = GetSubDefString(m_primaryFireInfo, "model_view3"); + string viewModelPath4 = GetSubDefString(m_primaryFireInfo, "model_view4"); + + viewModel.modelindex = m_viewModel; + viewModel.modelindex2 = getmodelindex(viewModelPath2); + viewModel.modelindex3 = getmodelindex(viewModelPath3); + viewModel.modelindex4 = getmodelindex(viewModelPath4); + + if (viewModel) { + viewModel._UpdateBoneCount(); + } + + if (viewModel2) { + viewModel2._UpdateBoneCount(); + } + } + } +} +#endif + void NSWeapon::Draw(void) { #ifdef CLIENT - if (pSeat != __NULL__) { - NSRenderableEntity viewModel = (NSRenderableEntity)pSeat->m_eViewModel; - - if (viewModel && viewModel.classname == "vm") { - viewModel.modelindex = m_viewModel; - if (m_viewModel) { - viewModel._UpdateBoneCount(); - } - } - } + UpdateViewmodel(); #endif float drawAnimation = -1; float drawTime = 0.0f; if (m_iClipSize > 0 && m_iClip == 0) { - drawAnimation = GetSubDefAct(m_primaryFireInfo, "actDrawEmpty"); + drawAnimation = GetSubDefAct(m_primaryFireInfo, "drawEmpty"); } /* no empty draw anim exists */ if (drawAnimation < 0) { - drawAnimation = GetSubDefAct(m_primaryFireInfo, "actDraw"); + drawAnimation = GetSubDefAct(m_primaryFireInfo, "draw"); } /* no draw anim exists at all... */ @@ -888,6 +909,31 @@ NSWeapon::UseAmmo(string fireInfo) return (false); } } + + if (TestFireAbility(fireInfo) == false) { + float failAnim = GetSubDefAct(fireInfo, "fireFailed"); + float failRate = GetSubDefFloat(fireInfo, "failRate"); + float failDuration = frameduration(m_viewModel, failAnim); + + if (!failRate) { + failRate = failDuration; + } + + if (failAnim >= 0) { + SetWeaponFrame(failAnim); + } + + if (failRate) { + SetAttackNext(failRate); + } + SetIdleNext(failDuration); + +#ifdef SERVER + ourOwner.StartSoundDef(m_fiSndFailed, CHAN_WEAPON, true); +#endif + + return (false); + } return (true); } @@ -967,10 +1013,10 @@ NSWeapon::Attack(string fireInfo) /* no real attack, detonate named satchels, pipe bombs, etc. */ if (m_fiDetonateOnFire != __NULL__) { if (DetonateDef(m_fiDetonateOnFire) == true) { - float detonateAct = GetSubDefAct(fireInfo, "actDetonate"); + float detonateAct = GetSubDefAct(fireInfo, "detonate"); if (detonateAct >= 0) { - SetWeaponFrame(GetSubDefAct(fireInfo, "actDetonate")); + SetWeaponFrame(GetSubDefAct(fireInfo, "detonate")); } return; @@ -987,103 +1033,33 @@ NSWeapon::Attack(string fireInfo) if (m_fiOnRelease != "") { m_fiWillRelease = true; ourOwner.vv_flags |= VFL_PRIMEDFUSE; - NSError("Will release."); - } - - /* melee attacks go through their own routine because we have to test - against objects and walls and if we can even hit them. */ - if (m_meleeDef != "") { - vector eyePos = ourOwner.GetEyePos(); - vector eyeAngles = ourOwner.v_angle; - int oldhitcontents = ourOwner.hitcontentsmaski; - float meleeRange = GetSubDefFloat(m_meleeDef, "melee_distance"); - vector traceStart = ourOwner.GetEyePos(); - vector traceEnd = traceStart + (anglesToForward(eyeAngles) * meleeRange); - float meleeRate; - NSSurfacePropEntity hitEnt; - vector hitLoc; - - ourOwner.hitcontentsmaski = (CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE); - traceline(traceStart, traceEnd, MOVE_NORMAL, ourOwner); - hitEnt = (NSSurfacePropEntity)trace_ent; - hitLoc = trace_endpos; - ourOwner.hitcontentsmaski = oldhitcontents; - - float meleeAnim; - if (trace_fraction >= 1.0) { - meleeAnim = GetSubDefAct(fireInfo, "actMeleeMiss"); - meleeRate = GetSubDefFloat(fireInfo, "meleeRateMiss"); - } else { - meleeAnim = GetSubDefAct(fireInfo, "actMeleeHit"); - meleeRate = GetSubDefFloat(fireInfo, "meleeRateHit"); - } - - SetWeaponFrame(meleeAnim); - SetAttackNext(meleeRate); - SetIdleNext(frameduration(m_viewModel, meleeAnim)); - -#ifdef SERVER - PlaySound(GetSubDefString(m_meleeDef, "snd_miss"), false); - - if (trace_fraction >= 1.0) { - return; - } - - /* don't bother with decals, we got squibs */ - if (hitEnt.iBleeds) { - FX_Blood(hitLoc, hitEnt.GetBloodColor()); - } - - if (hitEnt.takedamage) { - NSDict damageDecl = spawn(NSDict); - damageDecl.AddKey("damage", GetSubDefString(m_meleeDef, "damage")); - hitEnt.Damage(this, owner, damageDecl, 1.0, anglesToForward(eyeAngles), traceEnd); - remove(damageDecl); - //Damage_Apply(trace_ent, ourOwner, meleeDamage, 0, DMG_BLUNT); - - if (hitEnt.iBleeds) { - PlaySound(GetSubDefString(m_meleeDef, "snd_flesh"), false); - } - } else { - PlaySound(GetSubDefString(m_meleeDef, "snd_hit"), false); - DecalGroups_Place("Impact.Shot", hitLoc + (anglesToForward(eyeAngles) * -2)); - } -#endif - - /* below logic is for trace/projectile based attacks. */ - return; } if (UseAmmo(fireInfo) == false) { return; } - /* cooking/grenade type weapons */ - if (GetSubDefFloat(fireInfo, "primed_fuse") > 0.0f) { - shotAnim = GetSubDefAct(fireInfo, "actFire"); - SetWeaponFrame(shotAnim); - ourOwner.vv_flags |= VFL_PRIMEDFUSE; - ourOwner.gflags |= GF_SEMI_TOGGLED; - m_strLastFireInfo = fireInfo; -#ifdef SERVER - ourOwner.nadeCookingTime = time; -#endif - return; - } - /* this weapon has a delay before something shoots out. */ if (m_fiChargeTime > 0.0f) { /* we haven't yet tried firing while charging */ if (GetWeaponState() != WEAPONSTATE_CHARGING) { - shotAnim = GetSubDefAct(fireInfo, "actDelay"); + shotAnim = GetSubDefAct(fireInfo, "delay"); SetAttackNext(m_fiChargeTime); +#ifdef SERVER + ourOwner.nadeCookingTime = time; +#endif + /* mark as charging, play loop anim in Idle() next */ SetIdleNext(frameduration(m_viewModel, shotAnim)); SetWeaponFrame(shotAnim); _SetWeaponState(WEAPONSTATE_CHARGING); return; } + } else { +#ifdef SERVER + ourOwner.nadeCookingTime = time; +#endif } ourOwner.punchangle += m_fiPunchAngle; @@ -1107,11 +1083,11 @@ NSWeapon::Attack(string fireInfo) if (m_bHasLoop == false) { if (m_iClipSize > 0 && m_iClip == 0) { - shotAnim = GetSubDefAct(fireInfo, "actFireLast"); + shotAnim = GetSubDefAct(fireInfo, "fireLast"); } if (shotAnim <= 0) { - shotAnim = GetSubDefAct(fireInfo, "actFire"); + shotAnim = GetSubDefAct(fireInfo, "fire"); } #ifdef CLIENT @@ -1174,11 +1150,11 @@ NSWeapon::_SwitchedWeaponMode(void) float animMode = -1; if (m_iMode) { - animMode = GetSubDefAct(m_strLastFireInfo, "actModeOn"); + animMode = GetSubDefAct(m_strLastFireInfo, "modeOn"); SwitchFireInfo(m_secondaryFireInfo); } else { SwitchFireInfo(m_primaryFireInfo); - animMode = GetSubDefAct(m_strLastFireInfo, "actModeOff"); + animMode = GetSubDefAct(m_strLastFireInfo, "modeOff"); } if (animMode >= 0) { @@ -1204,6 +1180,38 @@ NSWeapon::PlaySound(string soundDef, bool clientOnly) #endif } +bool +NSWeapon::TestFireAbility(string fireInfo) +{ + NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); + float fiTestDistance = GetSubDefFloat(fireInfo, "testDistance"); + + if (fiTestDistance != 0.0f) { + bool invertCheck = (fiTestDistance < 0.0) ? true : false; + vector eyePos = ourOwner.GetEyePos(); + vector eyeAngles = ourOwner.v_angle; + int oldhitcontents = ourOwner.hitcontentsmaski; + vector traceStart = ourOwner.GetEyePos(); + + if (invertCheck) { + fiTestDistance = fabs(fiTestDistance); + } + + vector traceEnd = traceStart + (anglesToForward(eyeAngles) * fiTestDistance); + ourOwner.hitcontentsmaski = (CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE); + traceline(traceStart, traceEnd, MOVE_NORMAL, ourOwner); + ourOwner.hitcontentsmaski = oldhitcontents; + + if (trace_fraction >= 1.0) { + return (invertCheck) ? false : true; + } else { + return (invertCheck) ? true : false; + } + } + + return (true); +} + void NSWeapon::Idle(void) { @@ -1216,10 +1224,20 @@ NSWeapon::Idle(void) return; } + if (m_fiWillRelease) { + idleAnim = GetSubDefAct(m_strLastFireInfo, "cooking"); + + if (idleAnim >= 0) { + SetWeaponFrame(idleAnim); + SetIdleNext(frameduration(m_viewModel, idleAnim)); + } + return; + } + /* handle shotgun style reloads */ switch (m_dState) { case WEAPONSTATE_RELOAD_START: - idleAnim = GetSubDefAct(m_strLastFireInfo, "actReloadStart"); + idleAnim = GetSubDefAct(m_strLastFireInfo, "reloadStart"); _SetWeaponState(WEAPONSTATE_RELOAD); #ifdef SERVER PlaySound(GetDefString("snd_reload_start"), false); @@ -1228,7 +1246,7 @@ NSWeapon::Idle(void) break; case WEAPONSTATE_RELOAD: float reloadTime; - idleAnim = GetSubDefAct(m_strLastFireInfo, "actReload"); + idleAnim = GetSubDefAct(m_strLastFireInfo, "reload"); m_iClip++; ourOwner.UseAmmo(m_primaryAmmoType, 1); @@ -1250,7 +1268,7 @@ NSWeapon::Idle(void) return; break; case WEAPONSTATE_RELOAD_END: - idleAnim = GetSubDefAct(m_strLastFireInfo, "actReloadEnd"); + idleAnim = GetSubDefAct(m_strLastFireInfo, "reloadEnd"); _SetWeaponState(WEAPONSTATE_IDLE); #ifdef SERVER PlaySound(GetDefString("snd_reload_end"), false); @@ -1258,14 +1276,14 @@ NSWeapon::Idle(void) SetAttackNext(frameduration(m_viewModel, idleAnim)); break; case WEAPONSTATE_FIRELOOP: - idleAnim = GetSubDefAct(m_strLastFireInfo, "actLoop"); + idleAnim = GetSubDefAct(m_strLastFireInfo, "loop"); break; case WEAPONSTATE_CHARGING: - idleAnim = GetSubDefAct(m_strLastFireInfo, "actLoop"); + idleAnim = GetSubDefAct(m_strLastFireInfo, "loop"); break; case WEAPONSTATE_RELEASED: //breakpoint(); - idleAnim = GetSubDefAct(m_strLastFireInfo, "actRelease"); + idleAnim = GetSubDefAct(m_strLastFireInfo, "release"); _SetWeaponState(WEAPONSTATE_IDLE); break; case WEAPONSTATE_OVERHEATED: @@ -1278,7 +1296,7 @@ NSWeapon::Idle(void) case WEAPONSTATE_IDLE: default: if (m_iClipSize > 0 && m_iClip == 0) { - idleAnim = GetSubDefAct(m_strLastFireInfo, "actIdleEmpty"); + idleAnim = GetSubDefAct(m_strLastFireInfo, "idleEmpty"); /* TODO: may want this? hard to say. */ /*if (idleAnim < 0) { @@ -1288,7 +1306,7 @@ NSWeapon::Idle(void) } if (idleAnim < 0) { - idleAnim = GetSubDefAct(m_strLastFireInfo, "actIdle"); + idleAnim = GetSubDefAct(m_strLastFireInfo, "idle"); } } @@ -1430,7 +1448,7 @@ NSWeapon::Reload(void) if (m_dState >= WEAPONSTATE_RELOAD_START && m_dState <= WEAPONSTATE_RELOAD_END) { return; } - reloadStartAct = GetSubDefAct(m_strLastFireInfo, "actReloadStart"); + reloadStartAct = GetSubDefAct(m_strLastFireInfo, "reloadStart"); /* we cannot reload this weapon by principle. */ if (!m_iClipSize) { @@ -1465,11 +1483,11 @@ NSWeapon::Reload(void) } if (m_iClipSize > 0 && m_iClip == 0) { - reloadAnimation = GetSubDefAct(m_strLastFireInfo, "actReloadEmpty"); + reloadAnimation = GetSubDefAct(m_strLastFireInfo, "reloadEmpty"); } if (reloadAnimation < 0) { - reloadAnimation = GetSubDefAct(m_strLastFireInfo, "actReload"); + reloadAnimation = GetSubDefAct(m_strLastFireInfo, "reload"); } if (m_flReloadSpeed == -1.0f) { @@ -1529,7 +1547,7 @@ NSWeapon::_WeaponStartedFiring(void) /* hasn't been fired yet. */ if (!(owner.vv_flags & VFL_FIRING)) { - float actFireStart = GetSubDefAct(m_strLastFireInfo, "actFireStart"); + float actFireStart = GetSubDefAct(m_strLastFireInfo, "fireStart"); #ifdef SERVER NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); @@ -1568,7 +1586,8 @@ NSWeapon::_WeaponStoppedFiring(void) /* was still registed as firing */ if (owner.vv_flags & VFL_FIRING) { - float actFireStop = GetSubDefAct(m_strLastFireInfo, "actFireStop"); + NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); + float actFireStop = GetSubDefAct(m_strLastFireInfo, "fireStop"); if (actFireStop >= 0) { SetWeaponFrame(actFireStop); @@ -1578,6 +1597,12 @@ NSWeapon::_WeaponStoppedFiring(void) } WeaponStoppedFiring(); + + /* Remove when empty */ + if (m_bRemoveOnEmpty && HasReserveAmmo() == false && m_iClipSize <= 0i) { + ourOwner.RemoveItem(classname); + return; + } } owner.vv_flags &= ~VFL_FIRING; @@ -1607,24 +1632,8 @@ NSWeapon::Release(void) ourOwner.gflags &= ~GF_SEMI_TOGGLED; if (m_fiWillRelease) { - string defThrown = GetSubDefString(m_strLastFireInfo, "def_thrown"); - string defPlant = GetSubDefString(m_strLastFireInfo, "def_plant"); - /* delayed shot release */ - idleAnim = GetSubDefAct(m_strLastFireInfo, "actRelease"); - - /* aimed at attached to whatever we're looking at */ - if (defPlant != "") { - /* attempt to plant */ - if (ourOwner.PlantCharge(defPlant) == true) { - /* no ammo type, so remove item from inventory once depleted */ - if (m_strAmmoType == "") { - if (m_iClip == 0i) { - ourOwner.RemoveItem(this.classname); - } - } - } - } + idleAnim = GetSubDefAct(m_strLastFireInfo, "release"); if (m_fiSndRelease) { ourOwner.StartSoundDef(m_fiSndRelease, CHAN_WEAPON, true); @@ -1643,14 +1652,6 @@ NSWeapon::Release(void) return; } -#if 0 - /* Remove when empty */ - if (m_bRemoveOnEmpty && HasReserveAmmo() == false && m_iClipSize <= 0i) { - ourOwner.RemoveItem(classname); - return; - } -#endif - /* already in a reload? */ if (!(m_dState >= WEAPONSTATE_RELOAD_START && m_dState <= WEAPONSTATE_RELOAD_END)) { _SetWeaponState(WEAPONSTATE_IDLE); @@ -1774,8 +1775,12 @@ void NSWeapon::SetIdleNext(float newDelay) { NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); + /* HACK: RT2 requires this as their anims have junk at the end :/ */ - ourOwner.w_idle_next = bound(0.0, newDelay - 0.05f, newDelay); + if (m_bBuggyIdleAnim == true) + ourOwner.w_idle_next = bound(0.0, newDelay - 0.05f, newDelay); + else + ourOwner.w_idle_next = newDelay; } bool diff --git a/src/shared/defs.h b/src/shared/defs.h index c3e72ca0..c301f04d 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -65,6 +65,8 @@ typedef entity id; #define ATTR_CHANGED(x) (x ##_net != x) #define VEC_CHANGED(x,y) (x ##_net[y] != x[y]) +#define STRING_SET(x) ((x != __NULL__) && (x != "")) + #ifndef MAX_AMMO_TYPES #define MAX_AMMO_TYPES 16i #endif @@ -112,6 +114,7 @@ string __fullspawndata; #include "NSTalkMonster.h" #include "NSSpawnPoint.h" #include "NSSoundScape.h" +#include "NSAttack.h" #include "NSProjectile.h" #include "NSSpraylogo.h" #include "NSPortal.h" diff --git a/src/shared/entityDef.qc b/src/shared/entityDef.qc index adf4ffa4..a72b846e 100644 --- a/src/shared/entityDef.qc +++ b/src/shared/entityDef.qc @@ -204,7 +204,7 @@ EntityDef_Init(void) /* if spawnclass wasn't set, read the one from the inheritkeys entityDef */ for (int i = 0i; i < g_entDefCount; i++) { - if (!g_entDefTable[i].spawnClass) { + if (!STRING_SET(g_entDefTable[i].spawnClass)) { if (g_entDefTable[i].inheritID != -1i) { int baseID = g_entDefTable[i].inheritID; diff --git a/src/shared/include.src b/src/shared/include.src index d367da49..86f65fe6 100644 --- a/src/shared/include.src +++ b/src/shared/include.src @@ -14,6 +14,7 @@ NSBrushTrigger.qc NSPointTrigger.qc pmove.qc NSVehicle.qc +NSAttack.qc NSNavAI.qc NSMonster.qc NSSquadMonster.qc