-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);
}
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;
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;