forked from Mirrors/openclonk
take into account container velocity in shockwaves
This ensures reliable flint jumping when using dynamite, ironbomb, powderkeg, etc.liquid_container
parent
19a3d43558
commit
92334f5f4c
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue