openclonk/planet/System.ocg/Helpers.c

190 lines
4.3 KiB
C

/*--
Helpers.c
Authors:
Some useful helper functions.
--*/
// the shortest direction (left/right) to turn from one angle to another
// (for example for homing projectiles or aiming)
global func GetTurnDirection(int from, int to)
{
var dir;
if(to < from)dir=to-from;
else dir=from-to;
var dif=360-from+to;
var dif2=360-to+from;
if(dif < 180)dir=+dif;
else
if(dif2 < 180)dir=-dif2;
return dir;
}
global func MessageWindow(string msg, int for_plr, id icon, string caption)
{
// Get icon.
if (!icon)
icon = GetID();
// Get caption.
if (!caption)
caption = GetName();
// Create msg window (menu).
var cursor = GetCursor(for_plr);
if (!cursor->CreateMenu(icon, cursor, 0, caption, 0, 2))
return false;
cursor->AddMenuItem(caption, nil, nil, 0, 0, msg);
return true;
}
global func RemoveAll(p)
{
var cnt;
if (GetType(p) == C4V_PropList) p = Find_ID(p); // RemoveAll(ID) shortcut
for (var obj in FindObjects(p, ...))
{
if (obj)
{
obj->RemoveObject();
cnt++;
}
}
return cnt;
}
global func SetBit(int old_val, int bit_nr, bool bit)
{
if (GetBit(old_val, bit_nr) != (bit != 0))
return ToggleBit(old_val, bit_nr);
return old_val;
}
global func GetBit(int value, int bit_nr)
{
return (value & (1 << bit_nr)) != 0;
}
global func ToggleBit(int old_val, int bit_nr)
{
return old_val ^ (1 << bit_nr);
}
global func DrawParticleLine (string particle, int x0, int y0, int x1, int y1, int prtdist, int a, int b0, int b1, int ydir)
{
// Right parameters?
if (!prtdist)
return 0;
// Calculate required number of particles.
var prtnum = Max(Distance(x0, y0, x1, y1) / prtdist, 2);
var i = prtnum;
// Create particles.
while (i >= 0)
{
var i1, i2, b;
i2 = i * 256 / prtnum;
i1 = 256 - i2;
b = ((b0 & 16711935) * i1 + (b1 & 16711935) * i2) >> 8 & 16711935
| ((b0 >> 8 & 16711935) * i1 + (b1 >> 8 & 16711935) * i2) & -16711936;
if (!b && (b0 | b1))
b++;
CreateParticle(particle, x0 + (x1 - x0) * i / prtnum, y0 + (y1 - y0) * i-- / prtnum, 0, ydir, a, b);
}
// Succes, return number of created particles.
return prtnum;
}
// Searches for an object, which can be obtained with the Acquire command.
global func GetAvailableObject (id def, object obj)
{
var crit = Find_And(Find_OCF(OCF_Available),
Find_InRect(-500, -250, 1000, 500),
Find_ID(def),
Find_OCF(OCF_Fullcon),
Find_Not(Find_OCF(OCF_OnFire)),
Find_Func("GetAvailableObjectCheck", GetOwner()),
Find_Not(Find_Container(obj)));
if (!obj)
SetLength(crit, GetLength(crit) - 1);
return FindObject(crit, Sort_Distance());
}
global func GetAvailableObjectCheck(int plr)
{
// Object is not connected to anything (for line construction kits)
if (FindObject (Find_ActionTarget(this), Find_Procedure(DFA_CONNECT)))
return false;
// Not chosen by another friendly clonk
var eff =GetEffect("IntNotAvailable", this);
if (eff && !Hostile(plr, eff.clonk->GetOwner()))
return false;
return true;
}
// Sets the MaxEnergy value of an object and does the necessary callbacks.
global func SetMaxEnergy(int value)
{
if (!this)
return;
value *= 1000;
var old_maxenergy = this.MaxEnergy;
this.MaxEnergy = value;
// Change current energy percentage wise and implicit callback.
DoEnergy(GetEnergy() * (value - old_maxenergy) / old_maxenergy);
return;
}
// Returns the MaxEnergy value of an object.
global func GetMaxEnergy()
{
if (!this)
return;
return this.MaxEnergy / 1000;
}
// Sets the MaxBreath value of an object and does the necessary callbacks.
global func SetMaxBreath(int value)
{
if (!this)
return;
var old_maxbreath = this.MaxBreath;
this.MaxBreath = value;
// Change current breath percentage wise and implicit callback.
DoBreath(GetBreath() * (value - old_maxbreath) / old_maxbreath);
return;
}
// Returns the MaxBreath value of an object.
global func GetMaxBreath()
{
if (!this)
return;
return this.MaxBreath;
}
// Makes an object gain Con until it is FullCon
global func StartGrowth(int value)
{
return AddEffect("IntGrowth", this, 1, 35, nil, nil, value);
}
global func StopGrowth()
{
return RemoveEffect("IntGrowth", this);
}
global func FxIntGrowthStart(object obj, effect, int temporary, int value)
{
if (!temporary) effect.growth = value;
}
global func FxIntGrowthTimer(object obj, effect)
{
if (obj->OnFire()) return;
obj->DoCon(effect.growth, 1000);
var done = obj->GetCon(1000) >= 1000;
return -done;
}