X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fg_subs.qc;h=79369b74b9553dbcca2c0859560d46341c7b6111;hp=a401b60bdc84b935d8cf9dc6e7c0109861039111;hb=dcaa708cee1093798a651369d9fd46ad5074121e;hpb=9fc8e2dac1a0d16239045f73c774377d0b192933;ds=sidebyside diff --git a/qcsrc/server/g_subs.qc b/qcsrc/server/g_subs.qc index a401b60bdc..79369b74b9 100644 --- a/qcsrc/server/g_subs.qc +++ b/qcsrc/server/g_subs.qc @@ -180,35 +180,34 @@ void SUB_CalcMoveDone (void) void SUB_CalcMove_controller_think (void) { entity oldself; - float movephase; float traveltime; float phasepos; + float nexttick; vector delta; vector veloc; + vector nextpos; if(time < self.animstate_endtime) { delta = self.destvec; - traveltime = self.animstate_endtime - self.animstate_starttime; - movephase = (time - self.animstate_starttime) / traveltime; - - //bprint(ftos(movephase)); - //bprint("\n"); - - // TODO: Don't mess with the velocity, instead compute where - // we want to be next tick and compute velocity from that - - veloc = delta * (1/traveltime); // QuakeC doesn't allow vector/float division - - // scale velocity with pi/2 so integrated over time we - // still have the original velocity - veloc = veloc * 1.5708; - - // scale velocity with sin(phase) - phasepos = movephase * 3.1416; // phase * pi - phasepos = sin(phasepos); - veloc = veloc * phasepos; - + nexttick = time + sys_frametime; + + if(nexttick < self.animstate_endtime) { + traveltime = self.animstate_endtime - self.animstate_starttime; + phasepos = (nexttick - self.animstate_starttime) / traveltime; // range: [0, 1] + phasepos = 3.14159265 + (phasepos * 3.14159265); // range: [pi, 2pi] + phasepos = cos(phasepos); // cos [pi, 2pi] is in [-1, 1] + phasepos = phasepos + 1; // correct range to [0, 2] + phasepos = phasepos / 2; // correct range to [0, 1] + nextpos = self.origin + (delta * phasepos); + + veloc = nextpos - self.owner.origin; + veloc = veloc * (1 / sys_frametime); // so it arrives for the next frame + + } else { + veloc = self.finaldest - self.owner.origin; + veloc = veloc * (1 / sys_frametime); // so it arrives for the next frame + } self.owner.velocity = veloc; - self.nextthink = time + 0.1; + self.nextthink = nexttick; } else { oldself = self; self.owner.think = self.think1; @@ -248,19 +247,27 @@ void SUB_CalcMove (vector tdest, float tspeed, void() func) return; } + // very short animations don't really show off the effect + // of controlled animation, so let's just use linear movement + if (traveltime < 0.15) + { + self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division + self.nextthink = self.ltime + traveltime; + return; + } + controller = spawn(); controller.classname = "SUB_CalcMove_controller"; controller.owner = self; controller.origin = self.origin; // starting point - controller.finaldest = tdest; // where do we want to end? + controller.finaldest = (tdest + '0 0 1'); // where do we want to end? Offset to overshoot a bit. controller.destvec = delta; controller.animstate_starttime = time; controller.animstate_endtime = time + traveltime; controller.think = SUB_CalcMove_controller_think; controller.think1 = self.think; - // let the controller handle the velocity compuation - //self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division + // the thinking is now done by the controller self.think = SUB_Null; self.nextthink = self.ltime + traveltime; @@ -423,13 +430,13 @@ void traceline_antilag_force (entity source, vector v1, vector v2, float nomonst } void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag) { - if (cvar("g_antilag") != 2 || source.cvar_cl_noantilag) + if (autocvar_g_antilag != 2 || source.cvar_cl_noantilag) lag = 0; traceline_antilag_force(source, v1, v2, nomonst, forent, lag); } void tracebox_antilag (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag) { - if (cvar("g_antilag") != 2 || source.cvar_cl_noantilag) + if (autocvar_g_antilag != 2 || source.cvar_cl_noantilag) lag = 0; tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, FALSE); } @@ -439,13 +446,13 @@ void WarpZone_traceline_antilag_force (entity source, vector v1, vector v2, floa } void WarpZone_traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag) { - if (cvar("g_antilag") != 2 || source.cvar_cl_noantilag) + if (autocvar_g_antilag != 2 || source.cvar_cl_noantilag) lag = 0; WarpZone_traceline_antilag_force(source, v1, v2, nomonst, forent, lag); } void WarpZone_tracebox_antilag (entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag) { - if (cvar("g_antilag") != 2 || source.cvar_cl_noantilag) + if (autocvar_g_antilag != 2 || source.cvar_cl_noantilag) lag = 0; tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, TRUE); } @@ -668,9 +675,9 @@ float LOD_customize() { float d; - if(cvar("loddebug")) + if(autocvar_loddebug) { - d = cvar("loddebug"); + d = autocvar_loddebug; if(d == 1) self.modelindex = self.lodmodelindex0; else if(d == 2 || !self.lodmodelindex2) @@ -726,7 +733,7 @@ void LODmodel_attach() } } - if(cvar("loddebug") < 0) + if(autocvar_loddebug < 0) { self.lodmodel1 = self.lodmodel2 = ""; // don't even initialize } @@ -757,6 +764,33 @@ void LODmodel_attach() SetCustomizer(self, LOD_customize, LOD_uncustomize); } +void ApplyMinMaxScaleAngles(entity e) +{ + if(e.angles_x != 0 || e.angles_z != 0 || self.avelocity_x != 0 || self.avelocity_z != 0) // "weird" rotation + { + e.maxs = '1 1 1' * vlen( + '1 0 0' * max(-e.mins_x, e.maxs_x) + + '0 1 0' * max(-e.mins_y, e.maxs_y) + + '0 0 1' * max(-e.mins_z, e.maxs_z) + ); + e.mins = -e.maxs; + } + else if(e.angles_y != 0 || self.avelocity_y != 0) // yaw only is a bit better + { + e.maxs_x = vlen( + '1 0 0' * max(-e.mins_x, e.maxs_x) + + '0 1 0' * max(-e.mins_y, e.maxs_y) + ); + e.maxs_y = e.maxs_x; + e.mins_x = -e.maxs_x; + e.mins_y = -e.maxs_x; + } + if(e.scale) + setsize(e, e.mins * e.scale, e.maxs * e.scale); + else + setsize(e, e.mins, e.maxs); +} + void SetBrushEntityModel() { if(self.model != "") @@ -766,10 +800,7 @@ void SetBrushEntityModel() InitializeEntity(self, LODmodel_attach, INITPRIO_FINDTARGET); } setorigin(self, self.origin); - if(self.scale) - setsize(self, self.mins * self.scale, self.maxs * self.scale); - else - setsize(self, self.mins, self.maxs); + ApplyMinMaxScaleAngles(self); } void SetBrushEntityModelNoLOD() @@ -780,10 +811,7 @@ void SetBrushEntityModelNoLOD() setmodel(self, self.model); // no precision needed } setorigin(self, self.origin); - if(self.scale) - setsize(self, self.mins * self.scale, self.maxs * self.scale); - else - setsize(self, self.mins, self.maxs); + ApplyMinMaxScaleAngles(self); } /* @@ -809,9 +837,7 @@ void InitTrigger() { // trigger angles are used for one-way touches. An angle of 0 is assumed // to mean no restrictions, so use a yaw of 360 instead. - if (self.movedir == '0 0 0') - if (self.angles != '0 0 0') - SetMovedir (); + SetMovedir (); self.solid = SOLID_TRIGGER; SetBrushEntityModel(); self.movetype = MOVETYPE_NONE; @@ -823,9 +849,7 @@ void InitSolidBSPTrigger() { // trigger angles are used for one-way touches. An angle of 0 is assumed // to mean no restrictions, so use a yaw of 360 instead. - if (self.movedir == '0 0 0') - if (self.angles != '0 0 0') - SetMovedir (); + SetMovedir (); self.solid = SOLID_BSP; SetBrushEntityModel(); self.movetype = MOVETYPE_NONE; // why was this PUSH? -div0