From aa4b96f68c43e6cdf5c1530f5424ef31d944130b Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Thu, 31 Oct 2024 04:11:30 -0700 Subject: [PATCH] NSRagdoll: some minor optimisations. Platform: Background handler will look for assets in current game-dir for prioritisation Server: add server command `setLightStyle` (two args, style num + pattern) Bunch more tiny fixes for various classes. --- src/client/NSView.qc | 1 + src/platform/background.qc | 4 +- src/platform/maplibrary.qc | 4 + src/server/api.qc | 32 ++++++ src/server/api_func.h | 12 +++ src/server/cmd_sv.qc | 9 ++ src/server/spawn.qc | 10 ++ src/shared/NSClientPlayer.h | 4 +- src/shared/NSClientPlayer.qc | 71 +++++++++----- src/shared/NSDebris.h | 1 + src/shared/NSDebris.qc | 6 ++ src/shared/NSEntity.qc | 48 +++++++++ src/shared/NSIO.qc | 6 ++ src/shared/NSProjectile.h | 4 + src/shared/NSProjectile.qc | 80 +++++++++------ src/shared/NSRagdoll.h | 8 +- src/shared/NSRagdoll.qc | 81 ++++++++++++---- src/shared/NSRenderableEntity.h | 2 +- src/shared/NSRenderableEntity.qc | 57 ++++++++++- src/shared/NSSurfacePropEntity.h | 42 ++++---- src/shared/NSSurfacePropEntity.qc | 156 +++++++++++++++--------------- src/shared/api.h | 11 ++- src/shared/api.qc | 16 ++- src/shared/entityDef.h | 2 + src/shared/entityDef.qc | 62 +++++++----- src/shared/player_pmove.qc | 20 ++-- src/shared/pmove_custom.qc | 79 +++++++-------- src/shared/propdata.qc | 4 +- src/vgui/ui.qc | 4 +- 29 files changed, 579 insertions(+), 257 deletions(-) diff --git a/src/client/NSView.qc b/src/client/NSView.qc index 63746423..15cd10ee 100644 --- a/src/client/NSView.qc +++ b/src/client/NSView.qc @@ -298,6 +298,7 @@ NSView::UpdateView(void) pSeat->m_vecPredictedOrigin = cl.origin; pSeat->m_flPredictedFlags = cl.flags; pSeat->m_vecPredictedVelocity = cl.velocity; + SetCameraOrigin(cl.origin); /* this player will respawn, so null visual damage cues */ if (Client_IsDead(cl)) { diff --git a/src/platform/background.qc b/src/platform/background.qc index 2f6556d2..c10ea1c9 100755 --- a/src/platform/background.qc +++ b/src/platform/background.qc @@ -53,9 +53,9 @@ backResource_t g_back800[] = void Background_RendererRestarted(void) { - if (fileExists("resource/background/800_1_a_loading.tga")) { + if (Platform_FileInCurrentGamedir("resource/background/800_1_a_loading.tga")) { g_bgMode = BACK_VGUI1; - } else if (fileExists("gfx/shell/splash.bmp")) { + } else if (Platform_FileInCurrentGamedir("gfx/shell/splash.bmp")) { g_bgMode = BACK_WON; } else { g_bgMode = BACK_MATERIAL; diff --git a/src/platform/maplibrary.qc b/src/platform/maplibrary.qc index 7716c109..2f408615 100644 --- a/src/platform/maplibrary.qc +++ b/src/platform/maplibrary.qc @@ -28,6 +28,10 @@ MapLibrary_GetMapGamedir(void) if (gdir == "ftehl") gdir = "valve"; + /* HACK: work around FTEQW's path choice */ + if (gdir == "fteq2") + gdir = "baseq2"; + return gdir; } diff --git a/src/server/api.qc b/src/server/api.qc index 87d33a10..ec58eae5 100644 --- a/src/server/api.qc +++ b/src/server/api.qc @@ -112,6 +112,38 @@ SVPF_actor_GetInventory(NSActor targetActor) return (outputString); } +int +SVPF_actor_TotalActors(void) +{ + int actorCount = 0i; + + for (NSActor actorEnum = __NULL__; (actorEnum = (NSActor)nextent(actorEnum));) { + if (actorEnum.flags & FL_MONSTER) { + if (actorEnum.IsAlive() == true) { + actorCount++; + } + } + } + + return (actorCount); +} + +int +SVPF_actor_TotalActorsOnTeam(int teamID) +{ + int actorCount = 0i; + + for (NSActor actorEnum = __NULL__; (actorEnum = (NSActor)nextent(actorEnum));) { + if (actorEnum.flags & FL_MONSTER) { + if (actorEnum.team == (float)teamID && actorEnum.IsAlive() == true) { + actorCount++; + } + } + } + + return (actorCount); +} + string SVPF_util_TimeToString(int realTime, int zoneType, string formatString) { diff --git a/src/server/api_func.h b/src/server/api_func.h index 2a77c74e..0f1f63de 100644 --- a/src/server/api_func.h +++ b/src/server/api_func.h @@ -122,6 +122,15 @@ typedef struct string GetInventory(entity); int GetReserveAmmo(entity, int); bool MaxAmmo(entity, int); + int TotalActors(void); + int TotalActorsOnTeam(int); + + float AimAtPos(entity, vector); + float MoveToPos(entity, vector); + bool CanSee(entity, entity); + bool CanShoot(entity, vector, vector); + bool ClearEnemy(); + entity FindCoverNode(entity); } actorAPI_t; var actorAPI_t actor; @@ -206,6 +215,9 @@ _server_main(void) actor.GetInventory = linkToServerProgs("SVPF_actor_GetInventory"); actor.GetReserveAmmo = linkToServerProgs("SVPF_actor_GetReserveAmmo"); actor.MaxAmmo = linkToServerProgs("SVPF_actor_MaxAmmo"); + actor.TotalActors = linkToServerProgs("SVPF_actor_TotalActors"); + actor.TotalActorsOnTeam = linkToServerProgs("SVPF_actor_TotalActorsOnTeam"); + actor.MoveToPos = linkToServerProgs("SVPF_actor_MoveToPos"); exists.InMap = linkToServerProgs("SVPF_exists_InMap"); exists.InVFS = linkToServerProgs("SVPF_exists_InVFS"); diff --git a/src/server/cmd_sv.qc b/src/server/cmd_sv.qc index bdff96c5..0e7d5024 100644 --- a/src/server/cmd_sv.qc +++ b/src/server/cmd_sv.qc @@ -198,6 +198,12 @@ CMD_PropSpawn(void) newProp.Wake(); } +static void +CMD_SetLightStyle(void) +{ + lightstyle(stof(argv(1)), argv(2)); +} + bool Cmd_ParseServerCommand(void) { @@ -261,6 +267,9 @@ Cmd_ParseServerCommand(void) case "traceMaterial": CMD_TraceMaterial(); break; + case "setLightStyle": + CMD_SetLightStyle(); + break; default: return (false); } diff --git a/src/server/spawn.qc b/src/server/spawn.qc index eaa3ecb4..13b39268 100644 --- a/src/server/spawn.qc +++ b/src/server/spawn.qc @@ -74,6 +74,16 @@ float Spawn_PlayerRange(entity spot) { } } + for (pl = world; (pl = findfloat(pl, takedamage, DAMAGE_AIM));) { + if (pl->health <= 0) { + continue; + } + dist = vlen(spot.origin - pl.origin); + if (dist < bestdist) { + bestdist = dist; + } + } + return bestdist; } diff --git a/src/shared/NSClientPlayer.h b/src/shared/NSClientPlayer.h index 2e3156b7..33de5b08 100644 --- a/src/shared/NSClientPlayer.h +++ b/src/shared/NSClientPlayer.h @@ -143,11 +143,13 @@ private: NETWORKED_VECTOR_N(view_ofs) NETWORKED_VECTOR_N(basevelocity) NETWORKED_VECTOR_N(v_angle) - NETWORKED_FLOAT_N(pmove_flags) + NETWORKED_FLOAT_N(gravity) + NETWORKED_FLOAT_N(friction) NETWORKED_FLOAT(w_attack_next) NETWORKED_FLOAT(w_idle_next) NETWORKED_FLOAT(w_reload_next) + NETWORKED_FLOAT(jump_time) NETWORKED_FLOAT(teleport_time) NETWORKED_FLOAT(weapontime) NETWORKED_VECTOR(punchangle) diff --git a/src/shared/NSClientPlayer.qc b/src/shared/NSClientPlayer.qc index 191dfcd5..582bb572 100644 --- a/src/shared/NSClientPlayer.qc +++ b/src/shared/NSClientPlayer.qc @@ -166,18 +166,19 @@ NSClientPlayer::PreFrame(void) /* run physics code for all the input frames which we've not heard back * from yet. This continues on in Player_ReceiveEntity! */ - for (int i = sequence + 1; i <= clientcommandframe; i++) { - float flSuccess = getinputstate(i); - if (flSuccess == FALSE) { + for (float i = sequence + 1; i <= clientcommandframe; i++) { + bool inputPackets = getinputstate(i); + + if (inputPackets == false) { continue; } /* don't do partial frames, aka incomplete input packets */ - if (input_timelength == 0) { + if (input_timelength <= 0) { break; } - if (i==clientcommandframe){ + if (i == clientcommandframe){ CSQC_Input_Frame(); } @@ -679,6 +680,10 @@ NSClientPlayer::ClientInputFrame(void) } else { input_buttons &= ~INPUT_SPRINT; } + + input_movevalues[0] = floor(input_movevalues[0]); + input_movevalues[1] = floor(input_movevalues[1]); + input_movevalues[2] = floor(input_movevalues[2]); } void @@ -703,9 +708,6 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) if (new) { classname = "player"; - mins = m_pmoveVars.GetStandingMins(); - maxs = m_pmoveVars.GetStandingMaxs(); - Physics_SetViewParms(); } READENTITY_INT(entityDefID, PLAYER_MODELINDEX) @@ -744,7 +746,10 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) READENTITY_INT(flags, PLAYER_FLAGS) READENTITY_INT(vv_flags, PLAYER_FLAGS) READENTITY_INT(gflags, PLAYER_FLAGS) - READENTITY_INT(pmove_flags, PLAYER_FLAGS) + READENTITY_FLOAT(gravity, PLAYER_FLAGS) + READENTITY_FLOAT(friction, PLAYER_FLAGS) + READENTITY_FLOAT(jump_time, PLAYER_FLAGS) + READENTITY_FLOAT(teleport_time, PLAYER_FLAGS) READENTITY_BYTE(weaponframe, PLAYER_WEAPONFRAME) READENTITY_BYTE(health, PLAYER_HEALTH) READENTITY_BYTE(armor, PLAYER_HEALTH) @@ -793,7 +798,13 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) if (pSeat->m_ePlayer != this) { return; } - + + if (new) { + mins = m_pmoveVars.GetStandingMins(); + maxs = m_pmoveVars.GetStandingMaxs(); + Physics_SetViewParms(); + } + #ifdef VALVE if (flChanged & PLAYER_AMMOTYPES) { HUD_AmmoNotify_Check(this); @@ -832,6 +843,11 @@ NSClientPlayer::PredictPreFrame(void) if (m_activeWeapon.PredictPreFrame) m_activeWeapon.PredictPreFrame(); + if (vehicle) { + NSVehicle veh = (NSVehicle)vehicle; + veh.PredictPreFrame(); + } + SAVE_STATE(modelindex) SAVE_STATE(colormap) SAVE_STATE(m_iRenderMode) @@ -847,7 +863,10 @@ NSClientPlayer::PredictPreFrame(void) SAVE_STATE(flags) SAVE_STATE(vv_flags) SAVE_STATE(gflags) - SAVE_STATE(pmove_flags) + SAVE_STATE(gravity) + SAVE_STATE(friction) + SAVE_STATE(jump_time) + SAVE_STATE(teleport_time) SAVE_STATE(m_itemList) SAVE_STATE(activeweapon) SAVE_STATE(weaponframe) @@ -897,7 +916,10 @@ NSClientPlayer::PredictPostFrame(void) ROLL_BACK(flags) ROLL_BACK(vv_flags) ROLL_BACK(gflags) - ROLL_BACK(pmove_flags) + ROLL_BACK(gravity) + ROLL_BACK(friction) + ROLL_BACK(jump_time) + ROLL_BACK(teleport_time) ROLL_BACK(m_itemList) ROLL_BACK(activeweapon) ROLL_BACK(weaponframe) @@ -935,6 +957,11 @@ NSClientPlayer::PredictPostFrame(void) m_activeWeapon.PredictPostFrame(); } } + + if (vehicle) { + NSVehicle veh = (NSVehicle)vehicle; + veh.PredictPostFrame(); + } } #else void @@ -971,7 +998,6 @@ NSClientPlayer::Save(float handle) SaveVector(handle, "punchangle", punchangle); SaveFloat(handle, "movetype", movetype); SaveFloat(handle, "solid", solid); - SaveFloat(handle, "pmove_flags", pmove_flags); SaveFloat(handle, "w_attack_next", w_attack_next); SaveFloat(handle, "w_idle_next", w_idle_next); SaveFloat(handle, "w_reload_next", w_reload_next); @@ -1037,9 +1063,6 @@ NSClientPlayer::Restore(string strKey, string strValue) case "movetype": movetype = ReadFloat(strValue); break; - case "pmove_flags": - pmove_flags = ReadFloat(strValue); - break; case "w_attack_next": w_attack_next = ReadFloat(strValue); break; @@ -1265,7 +1288,10 @@ NSClientPlayer::EvaluateEntity(void) EVALUATE_FIELD(flags, PLAYER_FLAGS) EVALUATE_FIELD(vv_flags, PLAYER_FLAGS) EVALUATE_FIELD(gflags, PLAYER_FLAGS) - EVALUATE_FIELD(pmove_flags, PLAYER_FLAGS) + EVALUATE_FIELD(gravity, PLAYER_FLAGS) + EVALUATE_FIELD(friction, PLAYER_FLAGS) + EVALUATE_FIELD(jump_time, PLAYER_FLAGS) + EVALUATE_FIELD(teleport_time, PLAYER_FLAGS) EVALUATE_FIELD(m_itemList, PLAYER_ITEMS) EVALUATE_FIELD(m_activeWeapon, PLAYER_WEAPON) EVALUATE_FIELD(weaponframe, PLAYER_WEAPONFRAME) @@ -1350,7 +1376,10 @@ NSClientPlayer::SendEntity(entity ePEnt, float flChanged) SENDENTITY_INT(flags, PLAYER_FLAGS) SENDENTITY_INT(vv_flags, PLAYER_FLAGS) SENDENTITY_INT(gflags, PLAYER_FLAGS) - SENDENTITY_INT(pmove_flags, PLAYER_FLAGS) + SENDENTITY_FLOAT(gravity, PLAYER_FLAGS) + SENDENTITY_FLOAT(friction, PLAYER_FLAGS) + SENDENTITY_FLOAT(jump_time, PLAYER_FLAGS) + SENDENTITY_FLOAT(teleport_time, PLAYER_FLAGS) SENDENTITY_BYTE(weaponframe, PLAYER_WEAPONFRAME) SENDENTITY_BYTE(health, PLAYER_HEALTH) SENDENTITY_BYTE(armor, PLAYER_HEALTH) @@ -1615,12 +1644,6 @@ NSClientPlayer::Damage(entity inflictor, entity attacker, NSDict damageDecl, flo return; } - /* apply knockback */ - float knockBack = damageDecl.GetFloat("knockback"); - if (knockBack >= 0) { - AddVelocity(dmgDir * knockBack); - } - /* player god mode */ if (damageDecl.GetBool("noGod") == false && isGodMode(this)) { return; diff --git a/src/shared/NSDebris.h b/src/shared/NSDebris.h index f84c3b77..11c3af67 100644 --- a/src/shared/NSDebris.h +++ b/src/shared/NSDebris.h @@ -26,5 +26,6 @@ public: private: string m_strImpactDecal; + float m_flPlaceTime; }; #endif diff --git a/src/shared/NSDebris.qc b/src/shared/NSDebris.qc index 41a3db0e..b7be82e5 100644 --- a/src/shared/NSDebris.qc +++ b/src/shared/NSDebris.qc @@ -19,13 +19,19 @@ void NSDebris::NSDebris(void) { m_strImpactDecal = __NULL__; + m_flPlaceTime = 0.0f; } void NSDebris::Touch(entity touchingEnt) { + if (m_flPlaceTime > time) { + return; + } + if (STRING_SET(m_strImpactDecal)) { DecalGroups_Place(m_strImpactDecal, origin); + m_flPlaceTime = time + 1.0f; } } diff --git a/src/shared/NSEntity.qc b/src/shared/NSEntity.qc index 6ecce908..27f8094c 100644 --- a/src/shared/NSEntity.qc +++ b/src/shared/NSEntity.qc @@ -1025,6 +1025,21 @@ NSEntity::Restore(string strKey, string strValue) } } +void +NSEntity::Event_SpawnDefRelative(string classDef, float xOfs, float yOfs, float zOfs) +{ + vector posOffset; + posOffset = anglesToForward(GetAngles()) * xOfs; + posOffset += anglesToRight(GetAngles()) * yOfs; + posOffset += anglesToUp(GetAngles()) * zOfs; + NSEntity rocket = EntityDef_NewClassname(classDef); + rocket.SetOrigin(GetOrigin() + posOffset); + rocket.SetAngles(GetAngles()); + rocket.owner = this; + rocket.Spawn(); + EntLog("Spawned decl %S at relative offset %v (%v)", classDef, posOffset, rocket.origin); +} + void NSEntity::Input(entity eAct, string strInput, string strData) { @@ -1056,8 +1071,41 @@ NSEntity::Input(entity eAct, string strInput, string strData) if (PlayerUse) PlayerUse(); break; + case "ShootGib": + tokenize_console(strData); + string breakModel = argv(0); + float breakSpeed = stof(argv(1)); + int breakCount = stoi(argv(2)); + BreakModel_Spawn(origin, origin, v_angle, breakSpeed, breakCount, breakModel); + break; case "SpawnDef": break; + case "SpawnDefOffset": +#ifdef SERVER + tokenize_console(strData); + Event_SpawnDefRelative(argv(0), stof(argv(1)), stof(argv(2)), stof(argv(3))); +#endif + break; + case "KillChildClass": + for (entity e = world; (e = findfloat(e, ::owner, this));) { + if (strData == e.classname) { + NSEntity ent = (NSEntity) e; + ent.Destroy(); + } + } + break; + case "SpawnProjectileOffset": + vector launchOffset; + tokenize_console(strData); + string defName = argv(0); + launchOffset[0]= stof(argv(1)); + launchOffset[1]= stof(argv(2)); + launchOffset[2]= stof(argv(3)); + + if (EntityDef_HasSpawnClass(defName)) { + NSProjectile_SpawnDefAtPosition(defName, (NSActor)this, GetOrigin() + launchOffset, GetViewAngle()); + } + break; case "SpawnProjectileDef": if (EntityDef_HasSpawnClass(strData)) { NSProjectile_SpawnDefAttachment(strData, (NSActor)this, 0); diff --git a/src/shared/NSIO.qc b/src/shared/NSIO.qc index 755992df..fccfc4d7 100644 --- a/src/shared/NSIO.qc +++ b/src/shared/NSIO.qc @@ -881,9 +881,15 @@ NSIO::SpawnKey(string strKey, string strValue) defaults. just in case anybody is wondering. */ switch (strKey) { case "classname": + break; case "spawnflags": + spawnflags = ReadFloat(strValue); + break; case "mins": + mins = ReadVector(strValue); + break; case "maxs": + maxs = ReadVector(strValue); break; case "targetname": targetname = strValue; diff --git a/src/shared/NSProjectile.h b/src/shared/NSProjectile.h index 4648a812..9b9dd993 100644 --- a/src/shared/NSProjectile.h +++ b/src/shared/NSProjectile.h @@ -114,6 +114,7 @@ private: /* temp */ float m_flDmgMultiplier; + float m_trackDelayTime; /* defAPI */ string m_defDamage; @@ -181,6 +182,9 @@ private: bool m_bThrustHoming; bool m_bInheritVelocity; bool m_bReflect; + bool m_bTrackEnemy; + vector m_trackJitter; + float m_trackDelay; NSTimer m_thrustHandler; diff --git a/src/shared/NSProjectile.qc b/src/shared/NSProjectile.qc index 7b9c86d1..96848343 100644 --- a/src/shared/NSProjectile.qc +++ b/src/shared/NSProjectile.qc @@ -286,6 +286,15 @@ NSProjectile::SpawnKey(string strKey, string strValue) case "reflects": m_bReflect = ReadBool(strValue); break; + case "trackEnemy": + m_bTrackEnemy = ReadBool(strValue); + break; + case "trackJitter": + m_trackJitter = ReadVector(strValue); + break; + case "trackDelay": + m_trackDelay = ReadFloat(strValue); + break; default: super::SpawnKey(strKey, strValue); break; @@ -525,8 +534,6 @@ NSProjectile::Spawned(void) SetSize(m_vecSpawnMins, m_vecSpawnMaxs); } - - void NSProjectile::Touch(entity eToucher) { @@ -679,11 +686,11 @@ NSProjectile::_AnimateThink(void) { SetFrame(frame + 1); - if (frame > (float)m_iProjectileAnimEnd) + if (frame > (float)m_iProjectileAnimEnd) { SetFrame(m_iProjectileAnimStart); + } - think = _AnimateThink; - nextthink = time + m_flProjectileFramerate; + ScheduleThink(_AnimateThink, m_flProjectileFramerate); } void @@ -696,8 +703,7 @@ NSProjectile::_AnimateThinkDead(void) return; } - think = _AnimateThinkDead; - nextthink = time + m_flProjectileFramerate; + ScheduleThink(_AnimateThinkDead, m_flProjectileFramerate); } void @@ -706,9 +712,8 @@ NSProjectile::Animate(int startframe, int endframe, float framerate) m_iProjectileAnimStart = startframe; m_iProjectileAnimEnd = endframe; m_flProjectileFramerate = framerate; - frame = startframe; - think = _AnimateThink; - nextthink = time + m_flProjectileFramerate; + SetFrame(startframe); + ScheduleThink(_AnimateThink, m_flProjectileFramerate); } void @@ -717,9 +722,8 @@ NSProjectile::AnimateOnce(int startframe, int endframe, float framerate) m_iProjectileAnimStart = startframe; m_iProjectileAnimEnd = endframe; m_flProjectileFramerate = framerate; - frame = startframe; - think = _AnimateThinkDead; - nextthink = time + m_flProjectileFramerate; + SetFrame(startframe); + ScheduleThink(_AnimateThinkDead, m_flProjectileFramerate); } void @@ -734,7 +738,6 @@ NSProjectile::_FuseEnded(void) pointparticles(particleeffectnum(m_partSmokeFuse), origin, velocity, 1); } - Destroy(); } @@ -845,12 +848,18 @@ void NSProjectile::_ApplyDamage(void) { /* may not be defined yet */ - if (m_eMultiTarget == __NULL__) + if (m_eMultiTarget == __NULL__) { return; + } /* the location _could_ be more accurate... */ if (m_eMultiTarget.CanBleed() == true) { - FX_Blood(trace_endpos, m_eMultiTarget.GetBloodColor()); + NSSurfacePropEntity targetEnt = (NSSurfacePropEntity)m_eMultiTarget; + string surfType = targetEnt.GetPropData(PROPINFO_SURFACEPROP); + + if (STRING_SET(surfType)) { + SurfData_ImpactOfNamedType(surfType, trace_endpos, trace_plane_normal); + } } trace_surface_id = m_iMultiBody; @@ -876,22 +885,23 @@ NSProjectile::_ApplyDamage(void) m_iMultiBody = 0; } - void NSProjectile::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float flRange) { vector range; vector planeNormal; vector endPos; + bool skipFX = false; - if (flRange <= 0) + if (flRange <= 0) { return; + } - if (flDamage < 1) + if (flDamage < 1) { return; + } range = (vecAngles * 8196); - owner.dimension_solid = 255; owner.dimension_hit = 255; @@ -903,7 +913,7 @@ NSProjectile::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float planeNormal = trace_plane_normal; endPos = trace_endpos; - flRange -= trace_plane_dist; + flRange -= distance(vecPos, endPos); owner.dimension_solid = 254; owner.dimension_hit = 254; @@ -914,19 +924,23 @@ NSProjectile::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float trailparticles(particleeffectnum(m_partFXPath), world, vecPos, trace_endpos); } - if (trace_fraction >= 1.0f) + if (trace_fraction >= 1.0f) { return; + } /* water impact */ if (trace_endcontentsi & CONTENTBIT_WATER) { SurfData_ImpactOfNamedType("water", endPos, planeNormal); - _FireSingle(endPos + (v_forward * 2), vecAngles, flDamage / 2, flRange); + _FireSingle(endPos + ((vecAngles) * 2), vecAngles, flDamage / 2, flRange); + skipFX = true; } else if (trace_endcontentsi & CONTENTBIT_SLIME) { SurfData_ImpactOfNamedType("slime", endPos, planeNormal); - _FireSingle(endPos + (v_forward * 2), vecAngles, flDamage / 2, flRange); + _FireSingle(endPos + ((vecAngles) * 2), vecAngles, flDamage / 2, flRange); + skipFX = true; } else if (trace_endcontentsi & CONTENTBIT_LAVA) { SurfData_ImpactOfNamedType("lama", endPos, planeNormal); - _FireSingle(endPos + (v_forward * 2), vecAngles, flDamage / 2, flRange); + _FireSingle(endPos + ((vecAngles) * 2), vecAngles, flDamage / 2, flRange); + skipFX = true; } if (trace_ent.takedamage != DAMAGE_NO && trace_ent.iBleeds) { @@ -945,7 +959,7 @@ NSProjectile::_FireSingle(vector vecPos, vector vecAngles, float flDamage, float #endif /* impact per bullet */ - if (m_bDetonateOnWorld == true && trace_ent.iBleeds == 0) { + if (m_bDetonateOnWorld == true && trace_ent.iBleeds == 0 && skipFX == false) { StartSoundDef(m_sndExplode, CHAN_VOICE, true); if (m_strDecalGroup) @@ -990,6 +1004,18 @@ NSProjectile::_ThrustThink(void) endPos = ownerPos + (v_forward * 4096.0f); traceline(ownerPos, endPos, MOVE_NORMAL, projectileOwner); SetAngles(vectoangles(trace_endpos - GetOrigin())); + } else if (m_bTrackEnemy) { + + if (m_trackDelayTime > time) { + NSMonster monOwner = (NSMonster)owner; + vector angleToTarget = vectoangles(monOwner.m_eEnemy.origin - GetOrigin()); + angleToTarget[0] += random(-m_trackJitter[0],m_trackJitter[0]); + angleToTarget[1] += random(-m_trackJitter[1],m_trackJitter[1]); + angleToTarget[2] += random(-m_trackJitter[2],m_trackJitter[2]); + SetAngles(angleToTarget); + } + + m_trackDelayTime = time + m_trackDelay; } makevectors(GetAngles()); @@ -1113,7 +1139,7 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float ScheduleThink(_FuseEnded, m_flFuse - fuseOffset); } - if (m_flThrust != 0) { + if (m_flThrust != 0 || m_bTrackEnemy == true) { m_thrustHandler = NSTimer::TemporaryTimer(this, _ThrustThink, 0.0, true); } diff --git a/src/shared/NSRagdoll.h b/src/shared/NSRagdoll.h index 65790dd9..bbbbdc60 100644 --- a/src/shared/NSRagdoll.h +++ b/src/shared/NSRagdoll.h @@ -18,11 +18,15 @@ @ingroup baseclass */ -class NSRagdoll:NSRenderableEntity +class NSRagdoll:NSSurfacePropEntity { public: void NSRagdoll(void); + nonvirtual void CreateRagdoll(void); + + virtual void OnRemoveEntity(void); + #ifdef SERVER virtual void EvaluateEntity(void); virtual float SendEntity(entity,float); @@ -35,7 +39,7 @@ public: private: - float m_skelRagdoll; + float m_morphTime; }; diff --git a/src/shared/NSRagdoll.qc b/src/shared/NSRagdoll.qc index c250bad4..d270c581 100644 --- a/src/shared/NSRagdoll.qc +++ b/src/shared/NSRagdoll.qc @@ -17,7 +17,47 @@ void NSRagdoll::NSRagdoll(void) { - m_skelRagdoll = 0; + m_morphTime = 1.0f; +} + +void +NSRagdoll::OnRemoveEntity(void) +{ + skel_ragupdate(this, "cleardoll", 0); + + /* decouple */ + if (skeletonindex) { + skel_delete(skeletonindex); + skeletonindex = 0; + } + + modelindex = 0; +} + +void +NSRagdoll::CreateRagdoll(void) +{ + + skeletonindex = skel_create(modelindex); + skel_build(skeletonindex, this, modelindex, 0, 0, 0, 1); + +#if 0 + string dollString = GetPropData(PROPINFO_DOLL); + printf("Doll file:\n"); + printf(dollString); + printf("\n"); + + if (STRING_SET(dollString)) + skel_ragupdate(this, strcat("dollstring ", dollString), 0); + else +#else + if (fileExists(strcat(modelnameforindex(modelindex), ".doll"))) + skel_ragupdate(this, strcat("doll ", modelnameforindex(modelindex), ".doll"), 0); + else +#endif + skel_ragupdate(this, "doll models/rt2/human.doll", 0); + + skel_ragupdate(this, "animate 0", 0); } #ifdef SERVER @@ -168,6 +208,7 @@ NSRagdoll::ReceiveEntity void NSRagdoll::ReceiveEntity(float flNew, float flChanged) { + vector oldVelocity = velocity; READENTITY_COORD(origin[0], RDENT_CHANGED_ORIGIN_X) READENTITY_COORD(origin[1], RDENT_CHANGED_ORIGIN_Y) READENTITY_COORD(origin[2], RDENT_CHANGED_ORIGIN_Z) @@ -217,13 +258,12 @@ NSRagdoll::ReceiveEntity(float flNew, float flChanged) READENTITY_ANGLE(m_flBoneControl4, RDENT_CHANGED_CONTROLLER) READENTITY_ANGLE(m_flBoneControl5, RDENT_CHANGED_CONTROLLER) - movetype = MOVETYPE_PHYSICS; + if (flNew == false) { + velocity = oldVelocity; + } if (!skeletonindex && modelindex) { - skeletonindex = skel_create(modelindex); - skel_build(skeletonindex, this, modelindex, 0, 0, 0, 1); - skel_ragupdate(this, "doll models/rt2/human.doll", 0); - skel_ragupdate(this, "animate 0", 0); + CreateRagdoll(); } if (scale == 0.0) @@ -244,14 +284,18 @@ NSRagdoll::predraw(void) return (PREDRAW_NEXT); } - frame1time = time; - frame2time = time; - frame = 0; - frame2 = 1; + frame1time += frametime; + frame2time += frametime; lerpfrac = 0.0; skel_build(this.skeletonindex, this, this.modelindex, 0, 0, 0, 1); - skel_ragupdate(this, "", 0); + skel_ragupdate(this, "", m_morphTime); addentity(this); + + m_morphTime -= frametime; + + if (m_morphTime < 0.0f) + m_morphTime = 0.0f; + return (PREDRAW_NEXT); } @@ -260,14 +304,17 @@ NSRagdoll_Create(string modelFile) { NSRagdoll rag = spawn(NSRagdoll); rag.Spawn(); - rag.movetype = MOVETYPE_PHYSICS; + rag.SetMovetype(MOVETYPE_PHYSICS); rag.drawmask = MASK_ENGINE; + rag.SetSolid(SOLID_CORPSE); rag.SetOrigin(g_view.GetCameraOrigin()); - rag.SetModel("models/humans/group03/male_07.mdl"); - rag.skeletonindex = skel_create(rag.modelindex); - skel_build(rag.skeletonindex, rag, rag.modelindex, 0, 0, 0, 1); - skel_ragupdate(rag, "doll models/rt2/human.doll", 0); - skel_ragupdate(rag, "animate 0", 0); + if (STRING_SET(modelFile)) + rag.SetModel(modelFile); + else + rag.SetModel("models/police.mdl"); + + //rag.m_iPropData = PropData_ForModel(rag.model); + rag.CreateRagdoll(); } #endif diff --git a/src/shared/NSRenderableEntity.h b/src/shared/NSRenderableEntity.h index 6a61a7eb..b5635474 100644 --- a/src/shared/NSRenderableEntity.h +++ b/src/shared/NSRenderableEntity.h @@ -204,9 +204,9 @@ private: /* model events */ float m_flBaseTime; + float m_iNumBones; #ifdef CLIENT - float m_iNumBones; nonvirtual void _UpdateGeomset(); nonvirtual void _UpdateBoneCount(); #endif diff --git a/src/shared/NSRenderableEntity.qc b/src/shared/NSRenderableEntity.qc index 99c11180..08f6288a 100644 --- a/src/shared/NSRenderableEntity.qc +++ b/src/shared/NSRenderableEntity.qc @@ -60,6 +60,7 @@ void NSRenderableEntity::_UpdateGeomset(void) sprintf("geomset 0 %i\ngeomset 1 %i\ngeomset 2 %i\ngeomset 3 %i\n", firstBody, secondBody, thirdBody, fourthBody) ); } +#endif void NSRenderableEntity::_UpdateBoneCount(void) @@ -74,7 +75,6 @@ NSRenderableEntity::_UpdateBoneCount(void) skel_delete(skeletonindex); skeletonindex = 0; } -#endif /* ============ @@ -1014,10 +1014,10 @@ NSRenderableEntity::HandleAnimEvent(float flTimeStamp, int iCode, string strData break; default: #ifdef SERVER - int eDefEvents = tokenize(m_strModelEventCB); - //print(sprintf("%i\n", eDefEvents)); + bool success = false; - for (int i = 0; i < eDefEvents; i+=3) { + //print(sprintf("%i\n", eDefEvents)); + for (int i = 0; i < tokenize(m_strModelEventCB); i+=3) { int testCode = stoi(argv(i+0)); string testInput = argv(i+1); string testData = argv(i+2); @@ -1031,9 +1031,14 @@ NSRenderableEntity::HandleAnimEvent(float flTimeStamp, int iCode, string strData Input(this, testInput, strData); /* no parms passed. */ tokenize(m_strModelEventCB); /* ensure argv() is 'rewound'... */ + success = true; } } + if (success == true) { + return; + } + //print(sprintf("Received: %f %i %S\n", flTimeStamp, iCode, strData)); EntWarning("Unknown server model event: %f %i %S", flTimeStamp, iCode, strData); #else @@ -1118,10 +1123,54 @@ NSRenderableEntity::Restore(string strKey, string strValue) } } +void +NSRenderableEntity::Event_SpawnDefBone(string classDef, string boneName) +{ + _UpdateBoneCount(); + NSEntity rocket = Entity_CreateClass(classDef); + rocket.SetOrigin(GetOrigin()); + rocket.SetAngles(GetAngles()); + rocket.tag_entity = this; + rocket.tag_index = gettagindex(this, boneName); + rocket.owner = this; + EntLog("Spawned decl %S at bone %S (%v)", classDef, boneName, rocket.origin); +} + +void +NSRenderableEntity::Event_SpawnDefAttachment(string classDef, float attachmentID) +{ + _UpdateBoneCount(); + NSEntity rocket = Entity_CreateClass(classDef); + rocket.SetOrigin(GetOrigin()); + rocket.SetAngles(GetAngles()); + rocket.tag_entity = this; + rocket.tag_index = m_iNumBones + attachmentID; + rocket.owner = this; + EntLog("Spawned decl %S at attachment %f (%v)", classDef, attachmentID, rocket.origin); +} + void NSRenderableEntity::Input(entity eAct, string strInput, string strData) { switch (strInput) { + case "SpawnDefBone": +#ifdef SERVER + tokenize_console(strData); + Event_SpawnDefBone(argv(0), argv(1)); +#endif + break; + case "SpawnDefAttachment": +#ifdef SERVER + string declName; + string attachment; + float attachmentID; + tokenize_console(strData); + declName = argv(0); + attachment = argv(1); + attachmentID = stof(attachment); + Event_SpawnDefAttachment(declName, attachmentID); +#endif + break; case "Color": SetRenderColor(stov(strData)); break; diff --git a/src/shared/NSSurfacePropEntity.h b/src/shared/NSSurfacePropEntity.h index 218c591d..42f3af28 100644 --- a/src/shared/NSSurfacePropEntity.h +++ b/src/shared/NSSurfacePropEntity.h @@ -135,18 +135,6 @@ public: /** Returns the health the entity spawned with at map load */ nonvirtual float GetSpawnHealth(void); - /** Returns if the entity has prop data information set. */ - nonvirtual bool HasPropData(void) ; - /** Returns a variable type of information about the entity's prop data */ - nonvirtual __variant GetPropData(int); - /** Returns if the entity has surface data information set. */ - nonvirtual bool HasSurfaceData(void); - /** Returns a variable type of information about the entity's surface data */ - nonvirtual __variant GetSurfaceData(int); - /** Assigns the surface data of a given description onto this entity. */ - nonvirtual void SetSurfaceData(string); - /** Assigns the prop data of a given description onto this entity. */ - nonvirtual void SetPropData(string); /** Returns how many seconds have passed since we died. Will return -1 if not applicable. */ nonvirtual float TimeSinceDeath(void); @@ -159,6 +147,20 @@ public: nonvirtual vector GetBloodColor(void); #endif + + /** Assigns the surface data of a given description onto this entity. */ + nonvirtual void SetSurfaceData(string); + /** Assigns the prop data of a given description onto this entity. */ + nonvirtual void SetPropData(string); + /** Returns if the entity has prop data information set. */ + nonvirtual bool HasPropData(void) ; + /** Returns a variable type of information about the entity's prop data */ + nonvirtual __variant GetPropData(int); + /** Returns if the entity has surface data information set. */ + nonvirtual bool HasSurfaceData(void); + /** Returns a variable type of information about the entity's surface data */ + nonvirtual __variant GetSurfaceData(int); + #ifdef CLIENT /** Called every frame to render a fire effect, but will only do so if the entity is burning. */ virtual void RenderFire(void); @@ -170,6 +172,14 @@ private: PREDICTED_FLOAT(armor) PREDICTED_FLOAT_N(health) + /* Surface/PropKit */ + int m_iMaterial; + string m_strSurfData; + int m_iPropData; + string m_strPropData; + nonvirtual void _SurfaceDataFinish(void); + nonvirtual void _PropDataFinish(void); + #ifdef SERVER float max_armor; @@ -186,18 +196,10 @@ private: float m_oldHealth; vector m_vecBloodColor; - /* Surface/PropKit */ - int m_iMaterial; - string m_strSurfData; - int m_iPropData; - string m_strPropData; - float m_flDeathTime; bool m_bAutoAim; bool m_bTakesDamage; - nonvirtual void _SurfaceDataFinish(void); - nonvirtual void _PropDataFinish(void); nonvirtual void _UpdateTakedamage(void); #endif }; diff --git a/src/shared/NSSurfacePropEntity.qc b/src/shared/NSSurfacePropEntity.qc index 1f4a555f..95e1c2f5 100644 --- a/src/shared/NSSurfacePropEntity.qc +++ b/src/shared/NSSurfacePropEntity.qc @@ -201,30 +201,6 @@ NSSurfacePropEntity::GetArmor(void) return (armor); } -bool -NSSurfacePropEntity::HasPropData(void) -{ - return (m_iPropData != -1) ? true : false; -} - -__variant -NSSurfacePropEntity::GetPropData(int type) -{ - return Prop_GetInfo(m_iPropData, type); -} - -bool -NSSurfacePropEntity::HasSurfaceData(void) -{ - return (m_iMaterial != -1) ? true : false; -} - -__variant -NSSurfacePropEntity::GetSurfaceData(int type) -{ - return SurfData_GetInfo(m_iMaterial, type); -} - void NSSurfacePropEntity::ParentUpdate(void) { @@ -268,6 +244,7 @@ NSSurfacePropEntity::Damage(entity inflictor, entity attacker, NSDict damageDecl NSSurfacePropEntity ourAttacker = (NSSurfacePropEntity)attacker; EntLog("applying %d damage by %s", damagePoints, attacker.classname); + g_dmg_vecLocation = hitLocation; /* notify them */ if (isSentient(attacker)) { @@ -278,9 +255,15 @@ NSSurfacePropEntity::Damage(entity inflictor, entity attacker, NSDict damageDecl health = rint(health - damagePoints); if (health <= 0) { - Death(inflictor, attacker, (int)damagePoints, dmgDir, 0i); + /* apply knockback */ + float knockBack = damageDecl.GetFloat("knockback"); + if (knockBack >= 0) { + AddVelocity(dmgDir * knockBack); + } + + Death(inflictor, attacker, (int)damagePoints, dmgDir, damageDecl.GetInteger("hitbody")); } else if (damagePoints > 0) { - Pain(inflictor, attacker, (int)damagePoints, dmgDir, 0i); + Pain(inflictor, attacker, (int)damagePoints, dmgDir, damageDecl.GetInteger("hitbody")); } } } @@ -565,54 +548,6 @@ NSSurfacePropEntity::BreakModel(int damage, vector dir, int location) combat.RadiusDamage(origin, flExplodeRad, 0i, (int)flExplodeMag, this, ""); } } - -void -NSSurfacePropEntity::SetSurfaceData(string type) -{ - m_strSurfData = type; - _SurfaceDataFinish(); -} - -void -NSSurfacePropEntity::SetPropData(string type) -{ - m_strPropData = type; - _PropDataFinish(); -} - -void -NSSurfacePropEntity::_SurfaceDataFinish(void) -{ - SurfData_SetStage(m_strSurfData); - - if (STRING_SET(m_strSurfData)) { - m_iMaterial = SurfData_Finish(); - } else { - m_iMaterial = -1i; - } -} - -void -NSSurfacePropEntity::_PropDataFinish(void) -{ - PropData_SetStage(m_strPropData); - - if (STRING_SET(m_strPropData)) { - m_iPropData = PropData_Finish(); - } else { - m_iPropData = -1i; - } - - /* no surfdata? maybe the propdata has got one set. */ - if (m_iMaterial == -1i && m_iPropData != -1i) { - string propDataSurf = GetPropData(PROPINFO_SURFACEPROP); - - if (STRING_SET(propDataSurf)) { - SetSurfaceData(propDataSurf); - } - } -} - float NSSurfacePropEntity::TimeSinceDeath(void) { @@ -840,16 +775,85 @@ NSSurfacePropEntity_ReadEntity(bool isNew) } #endif +void +NSSurfacePropEntity::SetSurfaceData(string type) +{ + m_strSurfData = type; + _SurfaceDataFinish(); +} + +void +NSSurfacePropEntity::SetPropData(string type) +{ + m_strPropData = type; + _PropDataFinish(); +} + +bool +NSSurfacePropEntity::HasPropData(void) +{ + return (m_iPropData != -1) ? true : false; +} + +__variant +NSSurfacePropEntity::GetPropData(int type) +{ + return Prop_GetInfo(m_iPropData, type); +} + +bool +NSSurfacePropEntity::HasSurfaceData(void) +{ + return (m_iMaterial != -1) ? true : false; +} + +__variant +NSSurfacePropEntity::GetSurfaceData(int type) +{ + return SurfData_GetInfo(m_iMaterial, type); +} + +void +NSSurfacePropEntity::_SurfaceDataFinish(void) +{ + SurfData_SetStage(m_strSurfData); + + if (STRING_SET(m_strSurfData)) { + m_iMaterial = SurfData_Finish(); + } else { + m_iMaterial = -1i; + } +} + +void +NSSurfacePropEntity::_PropDataFinish(void) +{ + PropData_SetStage(m_strPropData); + + if (STRING_SET(m_strPropData)) { + m_iPropData = PropData_Finish(); + } else { + m_iPropData = -1i; + } + + /* no surfdata? maybe the propdata has got one set. */ + if (m_iMaterial == -1i && m_iPropData != -1i) { + string propDataSurf = GetPropData(PROPINFO_SURFACEPROP); + + if (STRING_SET(propDataSurf)) { + SetSurfaceData(propDataSurf); + } + } +} + void NSSurfacePropEntity::SetModel(string newModel) { NSRenderableEntity::SetModel(newModel); -#ifdef SERVER if (STRING_SET(model) && HasPropData() == false) { m_iPropData = PropData_ForModel(model); m_strPropData = model; _PropDataFinish(); } -#endif } diff --git a/src/shared/api.h b/src/shared/api.h index 4e1a9e49..dd068521 100644 --- a/src/shared/api.h +++ b/src/shared/api.h @@ -334,9 +334,15 @@ typedef struct @return The value in vector form. */ vector GetVector(string defName, string keyName); } entityDefAPI_t; - entityDefAPI_t entityDef; +typedef struct +{ + float Model(string); + float Sound(string); +} precacheAPI_t; +precacheAPI_t precache; + typedef string decl; typedef struct @@ -486,6 +492,9 @@ _shared_main(void) teams.SetUp = linkToSharedProgs("SHPF_teams_SetUp"); teams.SetSpawnPoint = linkToSharedProgs("SHPF_teams_SetSpawnPoint"); + precache.Model = linkToSharedProgs("SHPF_precache_Model"); + precache.Sound = linkToSharedProgs("SHPF_precache_Sound"); + weaponInfo.Type = linkToSharedProgs("SHPF_weaponInfo_Type"); weaponInfo.StartAmmo = linkToSharedProgs("SHPF_weaponInfo_StartAmmo"); weaponInfo.MaxAmmo = linkToSharedProgs("SHPF_weaponInfo_MaxAmmo"); diff --git a/src/shared/api.qc b/src/shared/api.qc index 76405949..56cff32b 100644 --- a/src/shared/api.qc +++ b/src/shared/api.qc @@ -770,8 +770,8 @@ spawnClass(string className, vector desiredPos) } newEntity.classname = className; - newEntity.Spawn(); newEntity.SetOrigin(desiredPos); + newEntity.Spawn(); #endif return (newEntity); @@ -920,3 +920,17 @@ SHPF_entityDef_GetVector(string declName, string keyName) { return stov(SHPF_entityDef_GetString(declName, keyName)); } + + +int +SHPF_precache_Model(string modelPath) +{ + precache_model(modelPath); + PropData_ForModel(modelPath); +} + +int +SHPF_precache_Sound(string modelPath) +{ + Sound_Precache(modelPath); +} diff --git a/src/shared/entityDef.h b/src/shared/entityDef.h index 4b51b54b..f5cb0cec 100644 --- a/src/shared/entityDef.h +++ b/src/shared/entityDef.h @@ -133,6 +133,8 @@ bool EntityDef_HasSpawnClass(string className); bool EntityDef_Precache(string); NSEntity EntityDef_SwitchClass(NSEntity target, string className); NSEntity Entity_CreateClass(string className); + +NSEntity EntityDef_NewClassname(string className); #endif /** @} */ // end of entitydef diff --git a/src/shared/entityDef.qc b/src/shared/entityDef.qc index fce6c5a3..b3d7bc26 100644 --- a/src/shared/entityDef.qc +++ b/src/shared/entityDef.qc @@ -372,8 +372,8 @@ EntityDef_PrepareEntity(entity target, int id) for (int x = 0; x < g_entDefCount; x++) { /* found the thing we're supposed to inherit */ if (g_entDefTable[x].entClass == g_entDefTable[id].inheritKeys) { - spawnWords = tokenize_console(g_entDefTable[x].spawnData); - for (int i = 0; i < spawnWords; i+= 2) { + + for (int i = 0; i < tokenize_console(g_entDefTable[x].spawnData); i+= 2) { targetEnt.SpawnKey(argv(i), argv(i+1)); } } @@ -381,14 +381,15 @@ EntityDef_PrepareEntity(entity target, int id) } /* now we load the field overrides from the entDef */ - spawnWords = tokenize_console(g_entDefTable[id].spawnData); - for (int i = 0; i < spawnWords; i+= 2) { - targetEnt.SpawnKey(argv(i), argv(i+1)); + for (int i = 0; i < tokenize_console(g_entDefTable[id].spawnData); i+= 2) { + string keyName = argv(i); + string setValue = argv(i+1); + + targetEnt.SpawnKey(keyName, setValue); } /* now we load our own spawndata, which starts and ends with braces */ - spawnWords = tokenize_console(g_lastSpawnData); - for (int i = 1; i < (spawnWords - 1); i+= 2) { + for (int i = 1; i < (tokenize_console(g_lastSpawnData) - 1); i+= 2) { /* ignore this, always */ if (argv(i) != "classname") { @@ -397,8 +398,7 @@ EntityDef_PrepareEntity(entity target, int id) } /* now after everything else is done, check our entityDef tweaks */ - spawnWords = tokenizebyseparator(g_entDefTable[id].tweakDefs, ";"); - for (int i = 0; i < spawnWords; i++) { + for (int i = 0; i < tokenizebyseparator(g_entDefTable[id].tweakDefs, ";"); i++) { string groupSegment = argv(i); //print(sprintf("group: %S\n", groupSegment)); @@ -410,31 +410,21 @@ EntityDef_PrepareEntity(entity target, int id) /* iterate through a bunch of different data to check our condition */ if (EntityDef_CheckCondition((NSEntity)target, id, keyWord, tweakCondition, keyValue)) { - int tweakGroups = tokenizebyseparator(g_entDefTable[id].tweakKeys, ";"); - //print(sprintf("%S passed the check\n", keyWord)); /* iterate through the ; key groups */ - for (int x = 0; x < tweakGroups; x++) { - int tweakSpawns = tokenize_console(argv(x)); - + for (int x = 0; x < tokenizebyseparator(g_entDefTable[id].tweakKeys, ";"); x++) { /* ignore any other key group */ if (x == i) { /* iterate through key/value pairs within the ; key groups */ - for (int y = 0; y < tweakSpawns; y+= 2) { + for (int y = 0; y < tokenize_console(argv(x)); y+= 2) { //print(sprintf("applying %S and %S\n", argv(y), argv(y+1))); targetEnt.SpawnKey(argv(y), argv(y+1)); targetEnt.m_strSpawnData = sprintf("%s TWEAK %S %S }", targetEnt.m_strSpawnData, argv(y), argv(y+1)); } } - - /* retokenize */ - tweakGroups = tokenizebyseparator(g_entDefTable[id].tweakKeys, ";"); } } - - /* retokenize our condition */ - spawnWords = tokenizebyseparator(g_entDefTable[id].tweakDefs, ";"); } /* now that that all methods have been called, we're ready to decide whether to continue this spawn */ @@ -457,8 +447,7 @@ EntityDef_PrepareEntity(entity target, int id) static void EntityDef_Precaches(int index) { - int spawnWords = tokenize_console(g_entDefTable[index].spawnData); - for (int i = 0; i < spawnWords; i+= 2) { + for (int i = 0; i < tokenize_console(g_entDefTable[index].spawnData); i+= 2) { string strKey = argv(i); string strValue = argv(i+1); @@ -476,12 +465,10 @@ EntityDef_Precaches(int index) EntityDef_Precaches(defID); } } - spawnWords = tokenize_console(g_entDefTable[index].spawnData); } /* handle soundDef events */ - spawnWords = tokenize(g_entDefTable[index].eventList); - for (int i = 0; i < spawnWords; i+=3) { + for (int i = 0; i < tokenize(g_entDefTable[index].eventList); i+=3) { int testCode = stoi(argv(i+0)); string testInput = argv(i+1); string testData = argv(i+2); @@ -516,6 +503,29 @@ EntityDef_Precache(string defName) return (true); } +NSEntity +EntityDef_NewClassname(string className) +{ + g_lastSpawnData = __fullspawndata; + + if not (className) { + return (__NULL__); + } + + for (int i = 0i; i < g_entDefCount; i++) { + if (className == g_entDefTable[i].entClass) { + if (time < 5.0) { + EntityDef_Precaches(i); + } + + NSLog("Spawning eDef %S", className); + return EntityDef_PrepareEntity(self, i); + } + } + + return (__NULL__); +} + NSEntity EntityDef_SpawnClassname(string className) { diff --git a/src/shared/player_pmove.qc b/src/shared/player_pmove.qc index a6297323..75f3450c 100644 --- a/src/shared/player_pmove.qc +++ b/src/shared/player_pmove.qc @@ -565,6 +565,12 @@ NSClientPlayer::Physics_Run(void) /* maxspeed changes when crouching, TODO: make this game-specific */ maxspeed = Physics_MaxSpeed(); +#ifdef SERVER + //printf("SERVER: %v; max: %f; fric: %f; grav: %f\n", input_movevalues, maxspeed, friction, gravity); +#else + //printf("CLIENT: %v; max: %f; fric: %f; grav: %f\n", input_movevalues, maxspeed, friction, gravity); +#endif + /* give us a chance to manipulate input_ globals before running physics */ Physics_InputPreMove(); @@ -586,13 +592,13 @@ NSClientPlayer::Physics_Run(void) Physics_Prone(); Physics_CheckJump(TRUE); -#ifdef CUSTOMPLAYERPHYSICS - /* QuakeC powered physics (slow, but more customizable) */ - PMoveCustom_RunPlayerPhysics(this); -#else - /* fast engine-side player physics */ - runstandardplayerphysics(this); -#endif + if (autocvar(pm_enginepmove, 0) > 0) { + /* fast engine-side player physics */ + runstandardplayerphysics(this); + } else { + /* QuakeC powered physics (slow, but more customizable) */ + PMoveCustom_RunPlayerPhysics(this); + } Physics_CheckJump(FALSE); diff --git a/src/shared/pmove_custom.qc b/src/shared/pmove_custom.qc index 1cdc06fc..054570a8 100644 --- a/src/shared/pmove_custom.qc +++ b/src/shared/pmove_custom.qc @@ -39,7 +39,7 @@ float PMoveCustom_Gravity(entity ent) { if (ent.gravity) { - return g_pmoveVars.g_gravity * ent.gravity; + return g_pmoveVars.g_gravity * ent.gravity; } else { return g_pmoveVars.g_gravity; } @@ -232,8 +232,8 @@ PMoveCustom_AccelLadder(float move_time, float premove, vector wish_dir, float w void PMoveCustom_AccelFriction(float move_time, float premove, vector wish_dir, float wish_speed) { - float flApplyFriction; - float flFriction; + float frictionMultiplier; + float retainSpeed; vector vecTemp; #ifdef SERVER @@ -248,11 +248,11 @@ PMoveCustom_AccelFriction(float move_time, float premove, vector wish_dir, float } #endif - flApplyFriction = g_pmoveVars.pm_friction; + frictionMultiplier = g_pmoveVars.pm_friction; /* per frame basis friction modifier */ if (self.friction != 0.0f) { - flApplyFriction /= self.friction; + frictionMultiplier /= self.friction; self.friction = 0.0f; } @@ -260,7 +260,7 @@ PMoveCustom_AccelFriction(float move_time, float premove, vector wish_dir, float if (self.velocity[0] || self.velocity[1]) { vecTemp = self.velocity; vecTemp[2] = 0; - flFriction = vlen(vecTemp); + retainSpeed = length(vecTemp); /* Next few lines of code assumes self is using player's hull, however it could be a monster who use differen hull size, therefore it is invalid, so we probably better of using mins/maxs, @@ -272,36 +272,37 @@ PMoveCustom_AccelFriction(float move_time, float premove, vector wish_dir, float // apply friction if (trace_fraction == 1.0) { - if (flFriction < g_pmoveVars.pm_stopspeed) { - flFriction = 1 - move_time * (g_pmoveVars.pm_stopspeed / flFriction) * flApplyFriction * g_pmoveVars.pm_edgefriction; + if (retainSpeed < g_pmoveVars.pm_stopspeed) { + retainSpeed = 1 - move_time * (g_pmoveVars.pm_stopspeed / retainSpeed) * frictionMultiplier * g_pmoveVars.pm_edgefriction; } else { - flFriction = 1 - move_time * flApplyFriction * g_pmoveVars.pm_edgefriction; + retainSpeed = 1 - move_time * frictionMultiplier * g_pmoveVars.pm_edgefriction; } } else { - if (flFriction < g_pmoveVars.pm_stopspeed) { - flFriction = 1 - move_time * (g_pmoveVars.pm_stopspeed / flFriction) * flApplyFriction; + if (retainSpeed < g_pmoveVars.pm_stopspeed) { + retainSpeed = 1 - move_time * (g_pmoveVars.pm_stopspeed / retainSpeed) * frictionMultiplier; } else { - flFriction = 1 - move_time * flApplyFriction; + retainSpeed = 1 - move_time * frictionMultiplier; } } - if (flFriction < 0) { + if (retainSpeed < 0) { self.velocity = [0,0,0]; } else { - self.velocity[0] = self.velocity[0] * flFriction; - self.velocity[1] = self.velocity[1] * flFriction; + self.velocity[0] = self.velocity[0] * retainSpeed; + self.velocity[1] = self.velocity[1] * retainSpeed; /* don't apply friction to horizontal movement... or else jumps get clamped */ if (self.flags & FL_JUMPRELEASED) - self.velocity[2] = self.velocity[2] * flFriction; + self.velocity[2] = self.velocity[2] * retainSpeed; } } // acceleration - flFriction = wish_speed - (self.velocity * wish_dir); - if (flFriction > 0) { - self.velocity += wish_dir * min(flFriction, g_pmoveVars.pm_accelerate * move_time * wish_speed); + retainSpeed = wish_speed - (self.velocity * wish_dir); + + if (retainSpeed > 0) { + self.velocity += wish_dir * min(retainSpeed, (g_pmoveVars.pm_accelerate * wish_speed) * move_time); } } @@ -309,7 +310,7 @@ void PMoveCustom_AccelNoclip(float move_time, float premove, vector wish_dir, float wish_speed) { float flApplyFriction; - float flFriction; + float retainSpeed; vector vecTemp; flApplyFriction = g_pmoveVars.pm_friction; @@ -323,45 +324,45 @@ PMoveCustom_AccelNoclip(float move_time, float premove, vector wish_dir, float w /* apply friction */ if (lengthSquared(self.velocity)) { vecTemp = self.velocity; - flFriction = vlen(vecTemp); + retainSpeed = vlen(vecTemp); - if (flFriction < g_pmoveVars.pm_stopspeed) { - flFriction = 1 - move_time * (g_pmoveVars.pm_stopspeed / flFriction) * flApplyFriction; + if (retainSpeed < g_pmoveVars.pm_stopspeed) { + retainSpeed = 1 - move_time * (g_pmoveVars.pm_stopspeed / retainSpeed) * flApplyFriction; } else { - flFriction = 1 - move_time * flApplyFriction; + retainSpeed = 1 - move_time * flApplyFriction; } - if (flFriction < 0) { + if (retainSpeed <= 0) { self.velocity = [0,0,0]; } else { - self.velocity = self.velocity * flFriction; + self.velocity = self.velocity * retainSpeed; } } // acceleration - flFriction = wish_speed - (self.velocity * wish_dir); - if (flFriction > 0) { - self.velocity += wish_dir * min(flFriction, g_pmoveVars.pm_noclipaccelerate * move_time * wish_speed); + retainSpeed = wish_speed - (self.velocity * wish_dir); + if (retainSpeed > 0) { + self.velocity += wish_dir * min(retainSpeed, (g_pmoveVars.pm_noclipaccelerate * wish_speed) * move_time); } } void PMoveCustom_AccelGravity(float move_time, float premove, vector wish_dir, float wish_speed) { - float flFriction; + float retainSpeed; /* apply gravity */ self.velocity[2] = self.velocity[2] - (PMoveCustom_Gravity(self) * move_time); if (wish_speed < 30) { - flFriction = wish_speed - (self.velocity * wish_dir); + retainSpeed = wish_speed - (self.velocity * wish_dir); } else { - flFriction = 30 - (self.velocity * wish_dir); + retainSpeed = 30 - (self.velocity * wish_dir); } - if (flFriction > 0) { + if (retainSpeed > 0) { float fric; - fric = min(flFriction, g_pmoveVars.pm_airaccelerate * wish_speed * move_time); + fric = min(retainSpeed, (g_pmoveVars.pm_airaccelerate * wish_speed) * move_time); self.velocity += wish_dir * fric; } } @@ -677,10 +678,6 @@ PMoveCustom_RunPlayerPhysics(entity target) entity oldself = self; self = target; - if (self.maxspeed <= 0) - self.maxspeed = 240; - - bool flying = ((target.movetype == MOVETYPE_NOCLIP) || (target.movetype == MOVETYPE_FLY)); if (flying == true) { @@ -694,26 +691,20 @@ PMoveCustom_RunPlayerPhysics(entity target) } } -#ifdef CUSTOMPLAYERPHYSICS /* call accelerate before and after the actual move, * with half the move each time. this reduces framerate dependence. * and makes controlling jumps slightly easier */ PMoveCustom_Acceleration(input_timelength / 2, TRUE); PMoveCustom_Move(); PMoveCustom_Acceleration(input_timelength / 2, FALSE); -#else - runstandardplayerphysics(target); -#endif /* NOTE: should clip to network precision here if lower than a float */ self.angles = input_angles; self.angles[0] *= -0.333; -#ifdef CUSTOMPLAYERPHYSICS /* activate any SOLID_TRIGGER entities, when not in noclip anyway */ if (self.movetype != MOVETYPE_NOCLIP) touchtriggers(); -#endif setorigin(self, self.origin); self = oldself; diff --git a/src/shared/propdata.qc b/src/shared/propdata.qc index ae580f4c..678ad069 100644 --- a/src/shared/propdata.qc +++ b/src/shared/propdata.qc @@ -399,7 +399,7 @@ PropData_ForModel(string modelname) /* HACK: We won't support ragdolls, for now. */ if (numSolids > 1) { - NSError("Only .phy files from Source are supported."); + NSError("Only non-ragdoll models are currently supported."); fclose(fh); return -1; } @@ -874,7 +874,7 @@ BreakModel_SpawnID(vector smins, vector smaxs, vector dir, float speed, int coun gib.velocity[2] += (random() - 0.5) * (speed * 0.25); gib.SetAngularVelocity([300,300,300]); gib.SetMovetype(MOVETYPE_BOUNCE); - gib.SetSolid(SOLID_NOT); + gib.SetSolid(SOLID_CORPSE); } else { gib.SetMovetype(MOVETYPE_PHYSICS); gib.SetSolid(SOLID_CORPSE); diff --git a/src/vgui/ui.qc b/src/vgui/ui.qc index c6c1c3ea..44900bf0 100644 --- a/src/vgui/ui.qc +++ b/src/vgui/ui.qc @@ -236,8 +236,10 @@ VGUIWidget::SizeChanged(vector vecOld, vector vecNew) void VGUIWidget::SetPos(vector vecNewPos) { + vector vecOld = m_vecOrigin; m_vecOrigin[0] = bound(0, vecNewPos[0], 9999.0); m_vecOrigin[1] = bound(0, vecNewPos[1], 9999.0); + PositionChanged(vecOld, m_vecOrigin); } vector @@ -262,10 +264,8 @@ void VGUIWidget::SetSize(vector vecNewSize) { vector vecOld = m_vecSize; - m_vecSize = vecNewSize; m_vecSize[0] = bound(m_vecMinSize[0], vecNewSize[0], m_vecMaxSize[0]); m_vecSize[1] = bound(m_vecMinSize[1], vecNewSize[1], m_vecMaxSize[1]); - SizeChanged(vecOld, m_vecSize); }