seta gl_finish $gl_finish
seta v_kicktime $v_kicktime
seta r_subdivisions_tolerance $r_subdivisions_tolerance
+seta vid_gl20 $vid_gl20
+seta vid_gl13 $vid_gl13
// ticrate
//sys_ticrate 0.0166667
case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
case ENT_CLIENT_TURRET: ent_turret(); break;
- case ENT_CLIENT_MODEL: CSQCModel_Read(); break;
+ case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
default:
//error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
error(sprintf(_("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n"), self.enttype, num_for_edict(self), self.classname));
-
+.float isplayermodel;
// FEATURE: LOD
.float lodmodelindex0;
self.frame3 = self.csqcmodel_saveframe3;
self.frame4 = self.csqcmodel_saveframe4;
}
-void CSQCPlayer_FallbackFrame_PostUpdate(void)
+void CSQCPlayer_FallbackFrame_PostUpdate(float isnew)
{
self.csqcmodel_saveframe = self.frame;
self.csqcmodel_saveframe2 = self.frame2;
self.csqcmodel_saveframe3 = self.frame3;
self.csqcmodel_saveframe4 = self.frame4;
+
+ // hack for death animations: set their frametime to zero in case a
+ // player "pops in"
+ if(isnew)
+ {
+#define FIX_FRAMETIME(f,ft) \
+ switch(self.f) \
+ { \
+ case 0: \
+ case 1: \
+ self.ft = 0; \
+ break; \
+ }
+ FIX_FRAMETIME(frame, frame1time)
+ FIX_FRAMETIME(frame2, frame2time)
+ FIX_FRAMETIME(frame3, frame3time)
+ FIX_FRAMETIME(frame4, frame4time)
+ }
}
float CSQCPlayer_FallbackFrame(float f)
{
else
self.drawmask = MASK_NORMAL;
- if(isplayer)
+ if(self.isplayermodel) // this checks if it's a player MODEL!
{
CSQCPlayer_GlowMod_Apply();
CSQCPlayer_ForceModel_Apply(islocalplayer);
CSQCPlayer_FallbackFrame_Apply();
}
- if(!isplayer)
+ if(!isplayer) // this checks if it's a player SLOT!
CSQCModel_AutoTagIndex_Apply();
CSQCModel_Effects_Apply();
}
-void CSQCModel_Hook_PreUpdate(float isplayer, float islocalplayer)
+void CSQCModel_Hook_PreUpdate(float isnew, float isplayer, float islocalplayer)
{
+ // revert to values from server
CSQCModel_Effects_PreUpdate();
- if(isplayer)
+ if(self.isplayermodel)
{
- // revert to values from server
CSQCPlayer_FallbackFrame_PreUpdate();
CSQCPlayer_ForceModel_PreUpdate();
}
}
-void CSQCModel_Hook_PostUpdate(float isplayer, float islocalplayer)
+void CSQCModel_Hook_PostUpdate(float isnew, float isplayer, float islocalplayer)
{
- if(isplayer)
+ // is it a player model? (shared state)
+ self.isplayermodel = (substring(self.model, 0, 14) == "models/player/");
+
+ // save values set by server
+ if(self.isplayermodel)
{
- // save values set by server
CSQCPlayer_ForceModel_PostUpdate();
- CSQCPlayer_FallbackFrame_PostUpdate();
+ CSQCPlayer_FallbackFrame_PostUpdate(isnew);
}
CSQCModel_Effects_PostUpdate();
}
// add hook function calls here
#define CSQCMODEL_HOOK_PREUPDATE \
- CSQCModel_Hook_PreUpdate(isplayer, islocalplayer);
+ CSQCModel_Hook_PreUpdate(isnew, isplayer, islocalplayer);
#define CSQCMODEL_HOOK_POSTUPDATE \
- CSQCModel_Hook_PostUpdate(isplayer, islocalplayer);
+ CSQCModel_Hook_PostUpdate(isnew, isplayer, islocalplayer);
#define CSQCMODEL_HOOK_PREDRAW \
CSQCModel_Hook_PreDraw(isplayer, islocalplayer);
#define CSQCPLAYER_HOOK_POSTCAMERASETUP
self.csqcmodel_teleported = 0;
}
-void CSQCModel_Read()
+void CSQCModel_Read(float isnew)
{
float sf;
sf = ReadShort();
* IN THE SOFTWARE.
*/
-void CSQCModel_Read();
+void CSQCModel_Read(float isnew);
#define CSQCMODEL_IF(cond)
#define CSQCMODEL_ENDIF
self.pauseregen_finished = 0;
self.damageforcescale = 0;
self.death_time = 0;
- self.dead_frame = 0;
self.alpha = 0;
self.scale = 0;
self.fade_time = 0;
}
self.damageforcescale = 2;
self.death_time = 0;
- self.dead_frame = 0;
self.alpha = 0;
self.scale = 0;
self.fade_time = 0;
swampspd_mod = self.swamp_slowdown; //cvar("g_balance_swamp_moverate");
}
+ // conveyors: first fix velocity
+ if(self.conveyor.state)
+ self.velocity -= self.conveyor.movedir;
+
if(self.classname != "player")
{
maxspd_mod = autocvar_sv_spectator_speed_multiplier;
self.velocity = self.velocity * f;
else
self.velocity = '0 0 0';
+ /*
+ Mathematical analysis time!
+
+ Our goal is to invert this mess.
+
+ For the two cases we get:
+ v = v0 * (1 - frametime * (autocvar_sv_stopspeed / v0) * autocvar_sv_friction)
+ = v0 - frametime * autocvar_sv_stopspeed * autocvar_sv_friction
+ v0 = v + frametime * autocvar_sv_stopspeed * autocvar_sv_friction
+ and
+ v = v0 * (1 - frametime * autocvar_sv_friction)
+ v0 = v / (1 - frametime * autocvar_sv_friction)
+
+ These cases would be chosen ONLY if:
+ v0 < autocvar_sv_stopspeed
+ v + frametime * autocvar_sv_stopspeed * autocvar_sv_friction < autocvar_sv_stopspeed
+ v < autocvar_sv_stopspeed * (1 - frametime * autocvar_sv_friction)
+ and, respectively:
+ v0 >= autocvar_sv_stopspeed
+ v / (1 - frametime * autocvar_sv_friction) >= autocvar_sv_stopspeed
+ v >= autocvar_sv_stopspeed * (1 - frametime * autocvar_sv_friction)
+ */
}
// acceleration
if(self.flags & FL_ONGROUND)
self.lastground = time;
+ // conveyors: then break velocity again
+ if(self.conveyor.state)
+ self.velocity += self.conveyor.movedir;
+
self.lastflags = self.flags;
self.lastclassname = self.classname;
}
self.animstate_override = oldself.animstate_override;
self.animstate_looping = oldself.animstate_looping;
self.frame = oldself.frame;
- self.dead_frame = oldself.dead_frame;
self.pain_finished = oldself.pain_finished;
self.health = oldself.health;
self.armorvalue = oldself.armorvalue;
self.anim_runbackwards = animfixfps(self, '14 1 1');
self.anim_strafeleft = animfixfps(self, '15 1 1');
self.anim_straferight = animfixfps(self, '16 1 1');
- self.anim_dead1 = animfixfps(self, '17 1 1');
- self.anim_dead2 = animfixfps(self, '18 1 1');
+ //self.anim_dead1 = animfixfps(self, '17 1 1');
+ //self.anim_dead2 = animfixfps(self, '18 1 1');
self.anim_forwardright = animfixfps(self, '19 1 1');
self.anim_forwardleft = animfixfps(self, '20 1 1');
self.anim_backright = animfixfps(self, '21 1 1');
updateanim(self.weaponentity);
if (self.deadflag != DEAD_NO)
- {
- if (time > self.animstate_endtime)
- {
- if (self.maxs_z > 5)
- {
- self.maxs_z = 5;
- setsize(self, self.mins, self.maxs);
- }
- self.frame = self.dead_frame;
- }
return;
- }
if (!self.animstate_override)
{
{
// don't use any animations as a gib
self.frame = 0;
- self.dead_frame = 0;
// view just above the floor
self.view_ofs = '0 0 4';
else
self.respawn_countdown = -1; // do not count down
if (random() < 0.5)
- {
setanim(self, self.anim_die1, FALSE, TRUE, TRUE);
- self.dead_frame = self.anim_dead1_x;
- }
else
- {
setanim(self, self.anim_die2, FALSE, TRUE, TRUE);
- self.dead_frame = self.anim_dead2_x;
+ if (self.maxs_z > 5)
+ {
+ self.maxs_z = 5;
+ setsize(self, self.mins, self.maxs);
}
// set damage function to corpse damage
self.event_damage = PlayerCorpseDamage;
.float play_time;
.float death_time;
-.float dead_frame;
.float fade_time;
.float fade_rate;
.vector anim_runbackwards; // player running backward
.vector anim_strafeleft; // player shuffling left quickly
.vector anim_straferight; // player shuffling right quickly
-.vector anim_dead1; // player dead (must be identical to last frame of die1)
-.vector anim_dead2; // player dead (must be identical to last frame of die2)
+//.vector anim_dead1; // player dead (must be identical to last frame of die1)
+//.vector anim_dead2; // player dead (must be identical to last frame of die2)
.vector anim_forwardright; // player running forward and right
.vector anim_forwardleft; // player running forward and left
.vector anim_backright; // player running backward and right
typedef vector(entity player, entity spot, vector current) spawn_evalfunc_t;
.spawn_evalfunc_t spawn_evalfunc;
+
+.entity conveyor;
void spawnfunc_path_corner() { }
void spawnfunc_func_plat()
{
- if (!self.t_length)
- self.t_length = 80;
- if (!self.t_width)
- self.t_width = 10;
-
if (self.sounds == 0)
self.sounds = 2;
if (!self.speed)
self.speed = 150;
+ if (!self.lip)
+ self.lip = 16;
+ if (!self.height)
+ self.height = self.size_z - self.lip;
self.pos1 = self.origin;
self.pos2 = self.origin;
- self.pos2_z = self.origin_z - self.size_z + 8;
+ self.pos2_z = self.origin_z - self.height;
plat_spawn_inside_trigger (); // the "start moving" trigger
void conveyor_think()
{
- for(other = world; (other = findentity(other, groundentity, self)); )
+ entity e;
+
+ // set myself as current conveyor where possible
+ for(e = world; (e = findentity(e, conveyor, self)); )
+ e.conveyor = world;
+
+ if(self.state)
{
- if(!WarpZoneLib_BoxTouchesBrush(other.absmin + '0 0 -1', other.absmax + '0 0 -1', self, other))
- {
- other.flags &~= FL_ONGROUND;
- continue;
- }
- if(other.flags & FL_CLIENT) // doing it via velocity has quite some advantages
- {
- float f = 1 - frametime * autocvar_sv_friction;
- if(f > 0)
- other.velocity += self.movedir * self.speed * (1 / f - 1);
- }
- else
+ for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5); e; e = e.chain)
+ if(!e.conveyor.state)
+ if(e.movetype != MOVETYPE_NONE)
+ {
+ vector emin = e.absmin;
+ vector emax = e.absmax;
+ if(self.solid == SOLID_BSP)
+ {
+ emin -= '1 1 1';
+ emax += '1 1 1';
+ }
+ if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
+ if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
+ e.conveyor = self;
+ }
+
+ for(e = world; (e = findentity(e, conveyor, self)); )
{
- tracebox(other.origin, other.mins, other.maxs, other.origin + self.movedir * (self.speed * sys_frametime), MOVE_NORMAL, other);
+ if(e.flags & FL_CLIENT) // doing it via velocity has quite some advantages
+ continue; // done in SV_PlayerPhysics
+
+ // stupid conveyor code
+ tracebox(e.origin, e.mins, e.maxs, e.origin + self.movedir * sys_frametime, MOVE_NORMAL, e);
if(trace_fraction > 0)
- setorigin(other, trace_endpos);
+ setorigin(e, trace_endpos);
}
}
+
self.nextthink = time;
}
void conveyor_use()
{
- if(self.nextthink)
- self.nextthink = 0;
- else
- self.nextthink = time;
+ self.state = !self.state;
}
void conveyor_reset()
{
- if(self.spawnflags & 1)
- self.nextthink = time;
- else
- self.nextthink = 0;
+ self.state = (self.spawnflags & 1);
}
-void spawnfunc_func_conveyor()
+void conveyor_init()
{
- SetMovedir ();
- if not(InitMovingBrushTrigger())
- return;
- self.movetype = MOVETYPE_NONE;
if (!self.speed)
self.speed = 200;
+ self.movedir = self.movedir * self.speed;
self.think = conveyor_think;
+ self.nextthink = time;
IFTARGETED
{
self.use = conveyor_use;
conveyor_reset();
}
else
- self.nextthink = time;
+ self.state = 1;
+}
+
+void spawnfunc_trigger_conveyor()
+{
+ EXACTTRIGGER_INIT;
+ conveyor_init();
+}
+
+void spawnfunc_func_conveyor()
+{
+ SetMovedir();
+ InitMovingBrushTrigger();
+ self.movetype = MOVETYPE_NONE;
+ conveyor_init();
}
}
// CSQC
- self.SendFlags = TNSF_ANG;
+ self.SendFlags |= TNSF_ANG;
return;