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=1d1f0bb9bd0f1bfee26d37846ad17085026bbdb4;hb=dcaa708cee1093798a651369d9fd46ad5074121e;hpb=b46fdcee5c729ccdf485d908803d06bbfdac2a8c;ds=sidebyside diff --git a/qcsrc/server/g_subs.qc b/qcsrc/server/g_subs.qc index 1d1f0bb9bd..79369b74b9 100644 --- a/qcsrc/server/g_subs.qc +++ b/qcsrc/server/g_subs.qc @@ -177,10 +177,51 @@ void SUB_CalcMoveDone (void) self.think1 (); } +void SUB_CalcMove_controller_think (void) +{ + entity oldself; + float traveltime; + float phasepos; + float nexttick; + vector delta; + vector veloc; + vector nextpos; + if(time < self.animstate_endtime) { + delta = self.destvec; + 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 = nexttick; + } else { + oldself = self; + self.owner.think = self.think1; + self = self.owner; + remove(oldself); + self.think(); + } +} + void SUB_CalcMove (vector tdest, float tspeed, void() func) { vector delta; float traveltime; + entity controller; if (!tspeed) objerror ("No speed is defined!"); @@ -206,9 +247,34 @@ void SUB_CalcMove (vector tdest, float tspeed, void() func) return; } - self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division + // 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 + '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; + + // the thinking is now done by the controller + self.think = SUB_Null; self.nextthink = self.ltime + traveltime; + + // invoke controller + self = controller; + self.think(); + self = self.owner; } void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeed, void() func) @@ -364,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); } @@ -380,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); } @@ -605,17 +671,16 @@ float angc (float a1, float a2) .float loddistance1; .float loddistance2; -vector NearestPointOnBox(entity box, vector org); 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) + else if(d == 2 || !self.lodmodelindex2) self.modelindex = self.lodmodelindex1; else // if(d == 3) self.modelindex = self.lodmodelindex2; @@ -668,7 +733,7 @@ void LODmodel_attach() } } - if(cvar("loddebug") < 0) + if(autocvar_loddebug < 0) { self.lodmodel1 = self.lodmodel2 = ""; // don't even initialize } @@ -695,7 +760,35 @@ void LODmodel_attach() } if(self.lodmodelindex1) - SetCustomizer(self, LOD_customize, LOD_uncustomize); + if not(self.SendEntity) + 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() @@ -707,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() @@ -721,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); } /* @@ -750,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; @@ -764,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