From 92334f5f4c97ae371e44aa50bc43dd6105d93a6b Mon Sep 17 00:00:00 2001 From: Maikel de Vries Date: Sun, 24 Apr 2016 20:33:44 +0200 Subject: [PATCH] take into account container velocity in shockwaves This ensures reliable flint jumping when using dynamite, ironbomb, powderkeg, etc. --- planet/System.ocg/Explode.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/planet/System.ocg/Explode.c b/planet/System.ocg/Explode.c index e7c06f6f4..5e9ca82ce 100644 --- a/planet/System.ocg/Explode.c +++ b/planet/System.ocg/Explode.c @@ -197,7 +197,7 @@ global func ExplosionEffect(...) /*-- Blast objects & shockwaves --*/ // Damage and hurl objects away. -global func BlastObjects(int x, int y, int level, object container, int cause_plr, int damage_level, object layer, object no_blast) +global func BlastObjects(int x, int y, int level, object container, int cause_plr, int damage_level, object layer, object prev_container) { var obj; @@ -221,7 +221,7 @@ global func BlastObjects(int x, int y, int level, object container, int cause_pl container->BlastObject(damage_level, cause_plr); if (!container) return true; // Container could be removed in the meanwhile. - for (obj in FindObjects(Find_Container(container), Find_Layer(layer), Find_Exclude(no_blast))) + for (obj in FindObjects(Find_Container(container), Find_Layer(layer), Find_Exclude(prev_container))) if (obj) obj->BlastObject(damage_level, cause_plr); } @@ -231,14 +231,24 @@ global func BlastObjects(int x, int y, int level, object container, int cause_pl // Object is outside. var at_rect = Find_AtRect(l_x - 5, l_y - 5, 10, 10); // Damage objects at point of explosion. - for (var obj in FindObjects(at_rect, Find_NoContainer(), Find_Layer(layer), Find_Exclude(no_blast))) + for (var obj in FindObjects(at_rect, Find_NoContainer(), Find_Layer(layer), Find_Exclude(prev_container))) if (obj) obj->BlastObject(damage_level, cause_plr); // Damage objects in radius. - for (var obj in FindObjects(Find_Distance(level, l_x, l_y), Find_Not(at_rect), Find_NoContainer(), Find_Layer(layer), Find_Exclude(no_blast))) + for (var obj in FindObjects(Find_Distance(level, l_x, l_y), Find_Not(at_rect), Find_NoContainer(), Find_Layer(layer), Find_Exclude(prev_container))) if (obj) obj->BlastObject(damage_level / 2, cause_plr); - DoShockwave(x, y, level, cause_plr, layer); + + // Perform the shockwave at the location where the top level container previously was. + // This ensures reliable flint jumps for explosives that explode inside a crew member. + var off_x = 0, off_y = 0; + if (prev_container) + { + var max_offset = 300; + off_x = BoundBy(-prev_container->GetXDir(100), -max_offset, max_offset); + off_y = BoundBy(-prev_container->GetYDir(100), -max_offset, max_offset); + } + DoShockwave(x, y, level, cause_plr, layer, off_x, off_y); } // Done. return true; @@ -262,7 +272,7 @@ global func BlastObject(int level, int caused_by) return; } -global func DoShockwave(int x, int y, int level, int cause_plr, object layer) +global func DoShockwave(int x, int y, int level, int cause_plr, object layer, int off_x, int off_y) { // Zero-size shockwave if (level <= 0) return; @@ -282,9 +292,9 @@ global func DoShockwave(int x, int y, int level, int cause_plr, object layer) if (cnt) { // The hurl energy is distributed over the objects. - //Log("Shockwave objs %v (%d)", shockwave_objs, cnt); var shock_speed = Sqrt(2 * level * level / BoundBy(cnt, 2, 12)); for (var obj in shockwave_objs) + { if (obj) // Test obj, cause OnShockwaveHit could have removed objects. { var cat = obj->GetCategory(); @@ -302,8 +312,9 @@ global func DoShockwave(int x, int y, int level, int cause_plr, object layer) mass_mul = 80; } mass_fact = BoundBy(obj->GetMass() * mass_mul / 1000, 4, mass_fact); - var dx = 100 * (obj->GetX() - x) + Random(51) - 25; - var dy = 100 * (obj->GetY() - y) + Random(51) - 25; + // Determine difference between object and explosion center, take into account the offset. + var dx = 100 * (obj->GetX() - x) - off_x + Random(51) - 25; + var dy = 100 * (obj->GetY() - y) - off_y + Random(51) - 25; var vx, vy; if (dx) vx = Abs(dx) / dx * (100 * level - Abs(dx)) * shock_speed / level / mass_fact; @@ -317,10 +328,11 @@ global func DoShockwave(int x, int y, int level, int cause_plr, object layer) if (ovy * vy > 0) vy = (Sqrt(vy * vy + ovy * ovy) - Abs(vy)) * Abs(vy) / vy; } - //Log("%v v(%v %v) d(%v %v) m=%v l=%v s=%v", obj, vx,vy, dx,dy, mass_fact, level, shock_speed); obj->Fling(vx, vy, 100, true); } + } } + return; } global func DoShockwaveCheck(int x, int y, int cause_plr)