1 float explosion_calcpush_getmultiplier(vector explosion_v, vector target_v)
2 {
3         float a;
4         a  = explosion_v * (explosion_v - target_v);
6         if(a <= 0)
7                 // target is too fast to be hittable by this
8                 return 0;
10         a /= (explosion_v * explosion_v);
11                 // we know we can divide by this, or above a would be == 0
13         return a;
14 }
16 #if 0
17 vector explosion_calcpush(vector explosion_v, float explosion_m, vector target_v, float target_m, float elasticity)
18 {
19         // solution of the equations:
20         //    v'                = v + a vp             // central hit
21         //    m*v'   + mp*vp'   = m*v + mp*vp          // conservation of momentum
22         //    m*v'^2 + mp*vp'^2 = m*v^2 + mp*vp^2      // conservation of energy (ELASTIC hit)
23         // -> a = 0                                    // case 1: did not hit
24         // -> a = 2*mp*(vp^2 - vp.v) / ((m+mp) * vp^2) // case 2: did hit
25         //                                             // non-elastic hits are somewhere between these two
27         // this would be physically correct, but we don't do that
28         return explosion_v * explosion_calcpush_getmultiplier(explosion_v, target_v) * (
29                 (1 + elasticity) * (
30                         explosion_m
31                 ) / (
32                         target_m + explosion_m
33                 )
34         ); // note: this factor is at least 0, at most 2
35 }
36 #endif
38 // simplified formula, tuned so that if the target has velocity 0, we get exactly the original force
39 vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor)
40 {
41         // if below 1, the formulas make no sense (and would cause superjumps)
42         if(speedfactor < 1)
43                 return explosion_f;
45 #if 0
46         float m;
47         // find m so that
48         //   speedfactor * (1 + e) * m / (1 + m) == 1
49         m = 1 / ((1 + 0) * speedfactor - 1);
50         vector v;
51         v = explosion_calcpush(explosion_f * speedfactor, m, target_v, 1, 0);
52         // the factor we then get is:
53         //   1
54         print(sprintf("MASS: %f\nv: %v -> %v\nENERGY BEFORE == %f + %f = %f\nENERGY AFTER >= %f\n",
55                 m,
56                 target_v, target_v + v,
57                 target_v * target_v, m * explosion_f * speedfactor * explosion_f * speedfactor, target_v * target_v + m * explosion_f * speedfactor * explosion_f * speedfactor,
58                 (target_v + v) * (target_v + v)));
59         return v;
60 #endif
61         return explosion_f * explosion_calcpush_getmultiplier(explosion_f * speedfactor, target_v);
62 }