FrozenFortress: Frostbolt now only damages clonks.

stable-5.1
MimmoO 2010-12-09 14:31:59 +01:00
parent 59a09c3c3c
commit fbec8430aa
3 changed files with 90 additions and 4 deletions

View File

@ -1,2 +1,2 @@
Name=Frostbolzen-Schriftrolle
Description=Schleudere einen gefrorenen Blitz in die Gegnermenge.
Description=Schleudere einen gefrorenen Blitz in die Gegnermenge. Schädigt nur Clonks.

View File

@ -1,2 +1,2 @@
Name=Frostbolt Scroll
Description=Hurl a frozen bolt into your enemies.
Description=Hurl a frozen bolt into your enemies. Only hurts Clonks.

View File

@ -50,9 +50,9 @@ global func DoBlueExplosion(int x, int y, int level, object inobj, int cause_plr
BlueExplosionEffect(level, x, y);
}
// Damage in the objects, and outside.
BlastObjects(x + GetX(), y + GetY(), level, inobj, cause_plr, layer);
BlastObjectsBlue(x + GetX(), y + GetY(), level, inobj, cause_plr, layer);
if (inobj != container)
BlastObjects(x + GetX(), y + GetY(), level, container, cause_plr, layer);
BlastObjectsBlue(x + GetX(), y + GetY(), level, container, cause_plr, layer);
// Landschaft zerstören. Nach BlastObjects, damit neu freigesprengte Materialien nicht betroffen sind
if (!container)
@ -84,3 +84,89 @@ global func BlueExplosionEffect(int level, int x, int y)
}*/
return;
}
global func BlastObjectsBlue(int x, int y, int level, object container, int cause_plr, object layer)
{
var obj;
// Coordinates are always supplied globally, convert to local coordinates.
var l_x = x - GetX(), l_y = y - GetY();
// In a container?
if (container)
{
if (container->GetObjectLayer() == layer)
{
container->BlastObject(level, cause_plr);
if (!container)
return true; // Container could be removed in the meanwhile.
for (obj in FindObjects(Find_Container(container), Find_Layer(layer)))
if (obj)
obj->BlastObject(level, cause_plr);
}
}
else
{
// Object is outside.
// Damage objects at point of explosion.
for (var obj in FindObjects(Find_AtRect(l_x - 5, l_y - 5, 10,10), Find_NoContainer(), Find_Layer(layer), Find_Not(Find_ID(StoneDoor))))
if (obj) obj->BlastObject(level, cause_plr);
// TODO: -> Shockwave in own global func(?)
// Hurl objects in explosion radius.
var shockwave_objs = FindObjects(Find_Distance(level, l_x, l_y), Find_NoContainer(), Find_Layer(layer),
Find_Or(Find_Category(C4D_Object|C4D_Living|C4D_Vehicle), Find_Func("CanBeHitByShockwaves")), Find_Func("BlastObjectsShockwaveCheck", x, y));
var cnt = GetLength(shockwave_objs);
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.
{
// Object has special reaction on shockwave?
if (obj->~OnShockwaveHit(level, x, y))
continue;
// Living beings are hurt more.
var cat = obj->GetCategory();
if (cat & C4D_Living)
{
obj->DoEnergy(level / -2, false, FX_Call_EngBlast, cause_plr);
obj->DoDamage(level / 2, FX_Call_DmgBlast, cause_plr);
}
// Killtracing for projectiles.
if (cat & C4D_Object)
obj->SetController(cause_plr);
// Shockwave.
var mass_fact = 20, mass_mul = 100;
if (cat & C4D_Living)
{
mass_fact = 8;
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;
var vx, vy;
if (dx)
vx = Abs(dx) / dx * (100 * level - Abs(dx)) * shock_speed / level / mass_fact;
vy = (Abs(dy) - 100 * level) * shock_speed / level / mass_fact;
if (cat & C4D_Object)
{
// Objects shouldn't move too fast.
var ovx = obj->GetXDir(100), ovy = obj->GetYDir(100);
if (ovx * vx > 0)
vx = (Sqrt(vx * vx + ovx * ovx) - Abs(vx)) * Abs(vx) / vx;
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);
}
}
}
// Done.
return true;
}