# Zwlib

 Note: This article needs to be cleaned up. Its information may be poorly-written, erroneous, incomplete, obsolete or irrelevant to the purpose of this wiki.
```/*

From http://zdoom.org/wiki/Other_useful_functions

Math
* abs
* pow
* round
* sqrt

Geo
* distance
* gettargetangle
* gettargetpitch

Info
* getactorclass
* getspawnid

Hud
* getaspectratio
* hudmessageonactor
* hudmessagetime
* printsprite

Misc
* acs_terminaterange
* syncspeed

*/

/* Math */

/// abs
/// This function can be used to return the absolute value of an integer.
function int abs (int x)
{
if (x < 0) return -x;
return x;
}

/// pow
/// This function computes n-th power of x.
function int pow (int x, int n)
{
if (n < 1)
return 1;
int y = x;
while (--n) y *= x;
return y;
}

/// sqrt
/// computes rounded square root of integer x
function int sqrt (int x)
{
int r;
x = x + 1 >> 1;
while (x > r) x -= r++;
return r;
}

/// round
/// This function implements rounding. Returns an int.
function int round (int fixednum)
{
int retamount = fixednum >> 16;
if (fixednum % 65536 > 32767) retamount++;
return retamount;
}

/// roundf
/// This function implements rounding. Returns a float.
function int roundf (int fixednum)
{
return round(number) << 16;
}

/* Geo */

/// distance
/// this function does all the necessary calculations to
/// return the distance (in grid units) between tid1 and tid2.
function int distance (int tid1, int tid2)
{
int x, y, z, d, r;
x = GetActorX(tid1) - GetActorX(tid2) >> 16;
y = GetActorY(tid1) - GetActorY(tid2) >> 16;
z = GetActorZ(tid2) - GetActorZ(tid2) >> 16;
d = x*x + y*y + z*z + 1 >> 1;
while (d > r) d -= r++;
return r;
}

/// gettargetangle
/// This function acts as an exstension to VectorAngle, it returns
/// the relative angle of a thing with tid2, from a thing with tid1.
function int gettargetangle (int tid1, int tid2)
{
int x, y;
x = GetActorX(tid2) - GetActorX(tid1);
y = GetActorY(tid2) - GetActorY(tid1);
return VectorAngle(x, y);
}

/// gettargetpitch
/// This function acts as an extension to VectorAngle, it returns
/// the relative pitch of a thing with tid2, from a thing with tid1.
/// This function requires the inclusion of the sqrt function.
function int gettargetpitch (int tid1, int tid2)
{
int x, y, z, xy;
x = GetActorX(tid2) - GetActorX(tid1) >> 16;
y = GetActorY(tid2) - GetActorY(tid1) >> 16;
z = GetActorZ(tid2) - GetActorZ(tid1);
xy = sqrt (x*x + y*y) << 16;
return VectorAngle(z, xy) - 0.25;
}

/* Info */

/// getactorclass
/// This function, along with the string array, returns the
/// class name for any Doom 1 & 2 spawnable thing in the form of a string.
str getactorclass_class = {"ShotgunGuy","ChaingunGuy","BaronOfHell",
"ZombieMan","DoomImp","Arachnotron","SpiderMastermind","Demon",
"Spectre","DoomImpBall","Clip","Shell","Cacodemon","Revenant",
"Bridge","ArmorBonus","Stimpack","Medikit","Soulsphere","Shotgun",
"Chaingun","RocketLauncher","PlasmaRifle","BFG","Chainsaw",
"SuperShotgun","Rock1","Rock2","Rock3","Dirt1","Dirt2","Dirt3",
"Dirt4","Dirt5","Dirt6","PlasmaBall","RevenantTracer","SGShard1",
"SGShard2","SGShard3","SGShard4","SGShard5","SGShard6","SGShard7",
"SGShard8","SGShard9","SGShard0","GreenArmor","BlueArmor","Cell",
"BlueCard","RedCard","YellowCard","YellowSkull","RedSkull","BlueSkull",
"ArchvileFire","StealthBaron","StealthHellKnight","StealthZombieMan",
"StealthShotgunGuy","LostSoul","Archvile","Fatso","HellKnight",
"Cyberdemon","PainElemental","WolfensteinSS","StealthArachnotron",
"StealthArchvile","StealthCacodemon","StealthChaingunGuy",
"StealthDemon","StealthDoomImp","StealthFatso","StealthRevenant",
"ExplosiveBarrel","CacodemonBall","Rocket","BFGBall",
"ArachnotronPlasma","Blood","BulletPuff","Megasphere",
"Infrared","ClipBox","RocketAmmo","RocketBox","CellPack","ShellBox",
"Backpack","Gibs","ColonGibs","SmallBloodPool","BurningBarrel",
"BrainStem","ScriptedMarine","HealthBonus","FatShot","BaronBall"};
function str getactorclass (int tid)
{
for (int i=0; i<105; i++)
if (ThingCountName (getactorclass_class[i], tid))
return getactorclass_class[i];
return 0;
}

/// getspawnid
/// This function returns the Spawn ID for a given TID. It can be useful for
/// making type or class specific decisions in a script.
int getspawnid_id = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 19, 20, 21, 22,
23, 24, 25, 27,28, 29, 30, 31, 32, 33, 41, 42, 43, 44, 45, 46, 47, 48, 49,
51, 53, 54, 55, 56,57, 58, 59, 60, 61, 62, 63, 68, 69, 75, 85, 86, 87, 88,
89, 90, 98, 100, 101, 102,103, 110, 111, 112, 113, 114, 115, 116, 117, 118,
119, 120, 121, 122, 123, 124, 125, 126, 127,128, 129, 130, 131, 132, 133,
134, 135, 136, 137, 138, 139, 140, 141, 143, 144, 146, 147, 148,149, 150,
151, 152, 153, 154};
function int getspawnid (int tid)
{
for (int i=0; i<104; i++)
if (ThingCount(getspawnid_id[i], tid))
return getspawnid_id[i];
return 0;
}

/* Hud */

/// getaspectratio
/// Returns the aspect ratio of the user's resolution by using nearly the same
/// method ZDoom uses internally. Requires the abs function.

#define ZW_ASPECT_4_3 1.3
#define ZW_ASPECT_5_4 1.25
#define ZW_ASPECT_16_9 1.7
#define ZW_ASPECT_16_10 1.6

function int getaspectratio(void)
{
int width = getcvar("vid_defwidth");
int height = getcvar("vid_defheight");
int nowidescreen = getcvar("vid_nowidescreen");
int tft = getcvar("vid_tft");
if(nowidescreen)
{
if(!tft)
return ZW_ASPECT_4_3;
if(fixedmul(height<<16, fixeddiv(5.0, 4.0)) == width<<16)
return ZW_ASPECT_5_4;
else
return ZW_ASPECT_4_3;
}
if(abs((abs(fixedmul(height<<16, fixeddiv(16.0, 9.0)))>>16) - width) < 10)
{
return ZW_ASPECT_16_9;
}
if(abs((abs(fixedmul(height<<16, fixeddiv(16.0, 10.0)))>>16) - width) < 60)
{
if((width == 320 && height == 200) || (width == 640 && height == 400))
return ZW_ASPECT_4_3;
return ZW_ASPECT_16_10;
}
if(fixedmul(height<<16, fixeddiv(5.0, 4.0))>>16 == width && tft)
{
return ZW_ASPECT_5_4;
}
return ZW_ASPECT_4_3;
}

/// hudmessageonactor
/// This function will place text or a sprite (depending on parameters passed)
/// at the onscreen position of an actor with the specified tid, as long as
/// it's in range (fixed mapunits).
function void hudmessageonactor(int tid, int range, str sprite, str text)
{
int dist, ang, vang, pitch, x, y;
int HUDX = 640;
int HUDY = 400;
int offset = 0;

if(sprite != -1)
{
setfont(sprite);
text = "A";
offset = 0.1;
}

sethudsize(HUDX, HUDY, 1);
x = getactorx(tid) - getactorx(0);
y = getactory(tid) - getactory(0);

vang = vectorangle(x,y);
ang = (vang - GetActorAngle(0) + 1.0) % 1.0;

if(((vang+0.125)%0.5) > 0.25) dist = fixeddiv(y, sin(vang));
else dist = fixeddiv(x, cos(vang));

if ((ang < 0.2 || ang > 0.8) && dist < range)
{
pitch = vectorangle(dist, getactorz(tid) - (getactorz(0) + 41.0));
pitch = (pitch + GetActorPitch(0) + 1.0) % 1.0;

x = HUDX/2 - ((HUDX/2) * sin(ang) / cos(ang));
y = HUDY/2 - ((HUDX/2) * sin(pitch) / cos(pitch));

hudmessage(s:text; HUDMSG_PLAIN, 1, CR_UNTRANSLATED, (x<<16)+offset,
(y<<16)+offset, 0);
}
else
hudmessage(s:" "; HUDMSG_PLAIN, 1, CR_UNTRANSLATED, 0, 0, 0);
}

/// hudmessagetime
/// This function is used to find how long a given hud message will take to
/// finish displaying. It is designed to be called within a delay function
/// immediately after the hud message command. (See examples)
#define ZW_TICUNIT     35.725
function int hudmessagetime(int type, int length, int typetime, int staytime,
{
Switch(type)
{
Case HUDMSG_PLAIN:
return fixedmul(staytime, ZW_TICUNIT) >> 16;
return fixedmul(staytime + fadetime, ZW_TICUNIT) >> 16;
Case HUDMSG_TYPEON:
return fixedmul(fixedmul(typetime, length << 16) + staytime + fadetime,
ZW_TICUNIT) >> 16;
return fixedmul(typetime + staytime + fadetime, ZW_TICUNIT) >> 16;
}
}

/// printsprite
/// This function draws the specified sprite to the screen at the given position.
function void printsprite(str sprite, int id, int x, int y, int delay)
{
SetFont(sprite);
HudMessage(s:"A"; 0, id, CR_UNTRANSLATED, x, y, delay);
}

/* Misc */

/// acs_terminaterange
/// This Function will terminate a range of Scripts, in order of what you put
/// in lo_script upto hi_script. Credit to SolarSnowFall for improvment.
function void acs_terminaterange (int lo_script, int hi_script, int map)
{
for (int i=lo_script; i<=hi_script; i++) acs_terminate(i, map);
}

/// This function acts as an extension to Spawn, used to spawn things in
/// circular patterns. It uses a MapSpot (or any other thing) as a base,
/// and will spawn the object at the appropriate angle and radius relative to
/// the MapSpot as the center. The radius is supplied in grid units, and angles
/// are supplied as vector angles.
function void spawnradius (str type, int spotid, int radius, int angle, int
newtid)
{
int x, y;
x = GetActorX(spotid) + radius * cos(angle);
y = GetActorY(spotid) + radius * sin(angle);
Spawn(type, x, y, GetActorZ(spotid), newtid, angle >> 8);
}

/// syncspeed
/// Synchronizes the travel time between two commands. For example,
/// if you wanted the ceiling to raise 20 units (with a speed of 8) in the
/// same time the floor lowers 6 units, you would do syncspeed(6, 20, 8).
function int syncspeed(int newdistance, int syncdistance, int syncspd)
{
int t = fixeddiv(syncdistance<<16, syncspd<<16);
int r = fixeddiv(newdistance<<16, t);
return r>>16;
}
```