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.
This commit is contained in:
Marco Cawthorne 2024-10-31 04:11:30 -07:00
parent b891015423
commit aa4b96f68c
29 changed files with 579 additions and 257 deletions

View file

@ -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)) {

View file

@ -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;

View file

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

View file

@ -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)
{

View file

@ -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");

View file

@ -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);
}

View file

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

View file

@ -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)

View file

@ -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;

View file

@ -26,5 +26,6 @@ public:
private:
string m_strImpactDecal;
float m_flPlaceTime;
};
#endif

View file

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

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

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

View file

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

View file

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

View file

@ -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;

View file

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

View file

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

View file

@ -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");

View file

@ -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);
}

View file

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

View file

@ -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)
{

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);
}