.float csqcmodel_framecount;
.float csqcmodel_isdead; // for utility code
-.float csqcmodel_deathtime; // for utility code
#define IS_DEAD_FRAME(f) ((f) == 0 || (f) == 1)
void CSQCPlayer_FallbackFrame_PreUpdate(void)
#define FIX_FRAMETIME(f,ft) \
if(IS_DEAD_FRAME(self.f)) \
{ \
- self.ft = 0; \
+ self.ft = self.death_time; \
}
FIX_FRAMETIME(frame, frame1time)
FIX_FRAMETIME(frame2, frame2time)
FIX_FRAMETIME(frame4, frame4time)
}
self.csqcmodel_isdead = IS_DEAD_FRAME(self.frame);
- if(self.csqcmodel_isdead)
- self.csqcmodel_deathtime = self.frame1time;
}
float CSQCPlayer_FallbackFrame(float f)
{
CSQCMODEL_PROPERTY(4, float, ReadByte, WriteByte, modelflags) \
CSQCMODEL_PROPERTY_SCALED(8, float, ReadByte, WriteByte, alpha, 254, -1, 254) \
CSQCMODEL_PROPERTY(16, float, ReadByte, WriteByte, skin) \
- CSQCMODEL_IF(isplayer) \
- CSQCMODEL_ENDIF \
+ CSQCMODEL_PROPERTY(32, float, ReadApproxPastTime, WriteApproxPastTime, death_time) \
CSQCMODEL_IF(!isplayer) \
- CSQCMODEL_PROPERTY(32, TAG_ENTITY_TYPE, ReadShort, WriteEntity, TAG_ENTITY_NAME) \
- CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_x, 255, 0, 255) \
- CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_y, 255, 0, 255) \
- CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_z, 255, 0, 255) \
+ CSQCMODEL_PROPERTY(64, TAG_ENTITY_TYPE, ReadShort, WriteEntity, TAG_ENTITY_NAME) \
+ CSQCMODEL_PROPERTY_SCALED(128, float, ReadByte, WriteByte, glowmod_x, 255, 0, 255) \
+ CSQCMODEL_PROPERTY_SCALED(128, float, ReadByte, WriteByte, glowmod_y, 255, 0, 255) \
+ CSQCMODEL_PROPERTY_SCALED(128, float, ReadByte, WriteByte, glowmod_z, 255, 0, 255) \
CSQCMODEL_ENDIF
// TODO get rid of colormod/glowmod here, find good solution for nex charge glowmod hack; also get rid of some useless properties on non-players that only exist for CopyBody
}
cvar_settemp_restore(); // this must be done LAST, but in any case
}
+
+#define APPROXPASTTIME_ACCURACY_REQUIREMENT 0.05
+#define APPROXPASTTIME_MAX (16384 * APPROXPASTTIME_ACCURACY_REQUIREMENT)
+#define APPROXPASTTIME_RANGE (64 * APPROXPASTTIME_ACCURACY_REQUIREMENT)
+// this will use the value:
+// 128
+// accuracy near zero is APPROXPASTTIME_MAX/(256*255)
+// accuracy at x is 1/derivative, i.e.
+// APPROXPASTTIME_MAX * (1 + 256 * (dt / APPROXPASTTIME_MAX))^2 / 65536
+#ifdef SVQC
+void WriteApproxPastTime(float dst, float t)
+{
+ float dt = t - time;
+
+ // warning: this is approximate; do not resend when you don't have to!
+ // be careful with sendflags here!
+ // we want: 0 -> 0.05, 1 -> 0.1, ..., 255 -> 12.75
+
+ // map to range...
+ dt = 256 * (dt / ((APPROXPASTTIME_MAX / 256) + dt));
+
+ // round...
+ dt = rint(bound(0, dt, 255));
+
+ WriteByte(dst, dt);
+}
+#endif
+#ifdef CSQC
+float ReadApproxPastTime()
+{
+ float dt = ReadByte();
+
+ // map from range...PPROXPASTTIME_MAX / 256
+ dt = (APPROXPASTTIME_MAX / 256) * (dt / (256 - dt));
+
+ return servertime + dt;
+}
+#endif
// generic shutdown handler
void Shutdown();
+
+#ifdef SVQC
+void WriteApproxPastTime(float dst, float t);
+#endif
+#ifdef CSQC
+float ReadApproxPastTime();
+#endif
self.pauseregen_finished = 0;
self.damageforcescale = 0;
self.death_time = 0;
+ self.respawn_time = 0;
self.alpha = 0;
self.scale = 0;
self.fade_time = 0;
}
self.damageforcescale = 2;
self.death_time = 0;
+ self.respawn_time = 0;
self.scale = 0;
self.fade_time = 0;
self.pain_frame = 0;
return;
else
{
- number = ceil(self.death_time - time);
+ number = ceil(self.respawn_time - time);
if(number <= 0)
return;
if(number <= self.respawn_countdown)
{
self.respawn_countdown = number - 1;
- if(ceil(self.death_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
+ if(ceil(self.respawn_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
AnnounceTo(self, strcat(ftos(number), ""));
}
}
float button_pressed, force_respawn;
if(self.personal && g_race_qualifying)
{
- if(time > self.death_time)
+ if(time > self.respawn_time)
{
- self.death_time = time + 1; // only retry once a second
+ self.respawn_time = time + 1; // only retry once a second
respawn();
self.impulse = 141;
}
}
else if (self.deadflag == DEAD_RESPAWNING)
{
- if(time > self.death_time)
+ if(time > self.respawn_time)
{
- self.death_time = time + 1; // only retry once a second
+ self.respawn_time = time + 1; // only retry once a second
respawn();
}
}
if(!waves)
waves = autocvar_g_respawn_waves;
if(waves)
- self.death_time = ceil((time + sdelay) / waves) * waves;
+ self.respawn_time = ceil((time + sdelay) / waves) * waves;
else
- self.death_time = time + sdelay;
- if((sdelay + waves >= 5.0) && (self.death_time - time > 1.75))
+ self.respawn_time = time + sdelay;
+ if((sdelay + waves >= 5.0) && (self.respawn_time - time > 1.75))
self.respawn_countdown = 10; // first number to count down from is 10
else
self.respawn_countdown = -1; // do not count down
+ self.death_time = time;
if (random() < 0.5)
setanim(self, self.anim_die1, FALSE, TRUE, TRUE);
else
//.float cnt2;
.float play_time;
+.float respawn_time;
.float death_time;
.float fade_time;
.float fade_rate;