From: Rudolf Polzer Date: Mon, 28 Mar 2011 15:31:46 +0000 (+0200) Subject: Fix some bugs in here X-Git-Tag: xonotic-v0.5.0~305^2~20 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=f8f76acce46b329e8a9335ac001589b3f32d1891;p=xonotic%2Fxonotic-data.pk3dir.git Fix some bugs in here --- diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index fe46be10c..5d9627b84 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -128,7 +128,7 @@ float autocvar_crosshair_ring_reload_size; float autocvar_crosshair_size; float autocvar_ekg; float autocvar_fov; -float autocvar_g_balance_damage_pushspeedfactor; +float autocvar_g_balance_damagepush_speedfactor; float autocvar_g_balance_tuba_attenuation; float autocvar_g_balance_tuba_fadetime; float autocvar_g_balance_tuba_volume; diff --git a/qcsrc/client/damage.qc b/qcsrc/client/damage.qc index 21366ad7b..783f66759 100644 --- a/qcsrc/client/damage.qc +++ b/qcsrc/client/damage.qc @@ -57,7 +57,7 @@ void Ent_DamageInfo(float isNew) if(self.damageforcescale) if(vlen(thisforce)) { - self.move_velocity = self.move_velocity + self.damageforcescale * damage_explosion_calcpush(thisforce, self.move_velocity, autocvar_g_balance_damagepush_speedfactor); + self.move_velocity = self.move_velocity + damage_explosion_calcpush(self.damageforcescale * thisforce, self.move_velocity, autocvar_g_balance_damagepush_speedfactor); self.move_flags &~= FL_ONGROUND; } diff --git a/qcsrc/common/explosion_equation.qc b/qcsrc/common/explosion_equation.qc index 4d5eb5a7e..3a18e8010 100644 --- a/qcsrc/common/explosion_equation.qc +++ b/qcsrc/common/explosion_equation.qc @@ -1,54 +1,63 @@ -vector explosion_calcpush_nomultiplier(vector explosion_v, vector target_v) +float explosion_calcpush_getmultiplier(vector explosion_v, vector target_v) { - // solution of the equations: - // v' = v + alpha vp // central hit - // m*v' + mp*vp' = m*v + mp*vp // conservation of momentum - // m*v'^2 + mp*vp'^2 = m*v^2 + mp*vp^2 // conservation of energy (ELASTIC hit) - // -> alpha = 0 // case 1: did not hit - // -> alpha = 2*mp*(vp^2 - vp.v) / ((m+mp) * vp^2) // case 2: did hit - // // non-elastic hits are somewhere between these two - - float alpha; - alpha = explosion_v * (explosion_v - target_v); + float a; + a = explosion_v * (explosion_v - target_v); - if(alpha <= 0) + if(a <= 0) // target is too fast to be hittable by this - return '0 0 0'; - - alpha /= (explosion_v * explosion_v); - // now alpha is a multiplier - // we know we can divide by this, or above alpha would be == 0 - - return - explosion_v * alpha; + return 0; + + a /= (explosion_v * explosion_v); + // we know we can divide by this, or above a would be == 0 + + return a; } #if 0 vector explosion_calcpush(vector explosion_v, float explosion_m, vector target_v, float target_m, float elasticity) { // solution of the equations: - // v' = v + alpha vp // central hit - // m*v' + mp*vp' = m*v + mp*vp // conservation of momentum - // m*v'^2 + mp*vp'^2 = m*v^2 + mp*vp^2 // conservation of energy (ELASTIC hit) - // -> alpha = 0 // case 1: did not hit - // -> alpha = 2*mp*(vp^2 - vp.v) / ((m+mp) * vp^2) // case 2: did hit - // // non-elastic hits are somewhere between these two + // v' = v + a vp // central hit + // m*v' + mp*vp' = m*v + mp*vp // conservation of momentum + // m*v'^2 + mp*vp'^2 = m*v^2 + mp*vp^2 // conservation of energy (ELASTIC hit) + // -> a = 0 // case 1: did not hit + // -> a = 2*mp*(vp^2 - vp.v) / ((m+mp) * vp^2) // case 2: did hit + // // non-elastic hits are somewhere between these two // this would be physically correct, but we don't do that - return explosion_calcpush_nomultiplier(explosion_v, target_v, + return explosion_v * explosion_calcpush_getmultiplier(explosion_v, target_v) * ( (1 + elasticity) * ( explosion_m ) / ( target_m + explosion_m ) - ); + ); // note: this factor is at least 0, at most 2 } #endif // simplified formula, tuned so that if the target has velocity 0, we get exactly the original force vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor) { - if(speedfactor == 0) + // if below 1, the formulas make no sense (and would cause superjumps) + if(speedfactor < 1) return explosion_f; - return explosion_calcpush_nomultiplier(explosion_f * speedfactor, target_v) * (1.0 / speedfactor); + + float m; + +#if 0 + // find m so that + // speedfactor * (1 + e) * m / (1 + m) == 1 + m = 1 / ((1 + 0) * speedfactor - 1); + vector v; + v = explosion_calcpush(explosion_f * speedfactor, m, target_v, 1, 0); + // the factor we then get is: + // 1 + print(sprintf("MASS: %f\nv: %v -> %v\nENERGY BEFORE == %f + %f = %f\nENERGY AFTER >= %f\n", + m, + target_v, target_v + v, + target_v * target_v, m * explosion_f * speedfactor * explosion_f * speedfactor, target_v * target_v + m * explosion_f * speedfactor * explosion_f * speedfactor, + (target_v + v) * (target_v + v))); + return v; +#endif + return explosion_f * explosion_calcpush_getmultiplier(explosion_f * speedfactor, target_v) * (1.0 / speedfactor); } diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 2118694dc..579f67975 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -179,6 +179,7 @@ float autocvar_g_balance_curse_venom_rotrate; float autocvar_g_balance_curse_vulner_takedamage; float autocvar_g_balance_curse_weak_damage; float autocvar_g_balance_curse_weak_force; +float autocvar_g_balance_damagepush_speedfactor; float autocvar_g_balance_electro_combo_comboradius; float autocvar_g_balance_electro_combo_damage; float autocvar_g_balance_electro_combo_edgedamage; @@ -735,7 +736,6 @@ float autocvar_g_ctf_shield_max_ratio; float autocvar_g_ctf_shield_min_negscore; float autocvar_g_cts_finish_kill_delay; float autocvar_g_cts_selfdamage; -float autocvar_g_damagepush_speedfactor; float autocvar_g_deathglow; float autocvar_g_debug_bot_commands; float autocvar_g_domination_default_teams; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index fcd3d9bd1..29fc297d5 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -839,7 +839,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float if (vlen(force)) if (self.classname != "player" || time >= self.spawnshieldtime || g_midair) { - self.velocity = self.velocity + self.damageforcescale * damage_explosion_calcpush(force, self.velocity, autocvar_g_damagepush_speedfactor); + self.velocity = self.velocity + damage_explosion_calcpush(self.damageforcescale * force, self.velocity, autocvar_g_balance_damagepush_speedfactor); self.flags &~= FL_ONGROUND; UpdateCSQCProjectile(self); }