@name functions
if(first())
{
    function number entity:cm()
    {
        local Mass = 0
        foreach(I, K:entity = This:getConstraints())
        {
            Mass+=K:mass()
        }
        return This:mass()+Mass
    }
    
    function number angle:nearBy(A:angle, R)
    {
        return inrange(angnorm(round(This-A)), ang(-R), ang(R))
    }
    
    function entity:goto(V:vector)
    {
        This:applyForce(((V-This:pos())*10-This:vel())*This:mass())
    }
    
    function entity:turnTo(Tarang:angle)
    {
        local V = This:toLocal(rotationVector(quat(Tarang)/quat(This))+This:pos())
        This:applyTorque((100*V - 30*This:angVelVector())*This:inertia()/3)
    }
    
    function entity:applySlow(V:vector)
    {
        This:applyForce((V-This:pos())*0.175*This:mass())
    }
    
    function ikS(Dist, I1, I2, Src:vector, End:vector)
    {
        local D = Src-End
        local L = min(D:length(), Dist)
        local A1 = D:toAngle()
        local A2 = ang(-asin(L/Dist), 0, 0)
        holoAng(I1, A1+A2)
        holoAng(I2, A1-A2)
    }
    
    function number cosine(A, B, C)
    {
        return acos((A^2 + B^2 - C^2) / (2*A*B))
    }
    
    function ik(L1, L2, Hip:entity, Foot:vector, Chassis:entity, I1, I2)
    {    
        local Axis = Chassis:toLocalAxis(Foot - Hip:pos())
        local Angle = Axis:toAngle():setRoll(-bearing(Hip:pos(), Chassis:angles(), Foot))
        local Dist = min(Axis:length(), L1 + L2)
        local Quat = quat(Angle) * qRotation(vec(0, 90 + cosine(Dist, L1, L2), 0))
        
        holoAng(I1, Chassis:toWorld(Quat:toAngle()))
        holoAng(I2, Hip:toWorld(ang(cosine(L2, L1, Dist) + 180, 0, 0)))
    }
    
    function ik3([Ent Hip Knee Ankle]:entity, FootPos:vector, [L1 L2 L3 FirstSegmentAdjustAngle]:number)  {
        local Total = L1 + L2 + L3
        #-Hip
            local Bearing = -bearing(Hip:pos(), Ent:angles(), FootPos)
            local Angle = Ent:toLocalAxis(FootPos - Hip:pos()):toAngle():setRoll(Bearing)
            local Offset = Total - abs(min(Hip:pos():distance(FootPos), Total))
            local Quat = quat(Angle) * qRotation(vec(0, -Offset + FirstSegmentAdjustAngle, 0))
            holoAng(holoIndex(Hip), Ent:toWorld(slerp(quat(Hip), Quat, 1):toAngle()))
        #-Second
            local Distance = min(Knee:pos():distance(FootPos), L2+L3)
            local Axis = Hip:toLocalAxis(Knee:pos() - FootPos)
            local Atan = atan(-Axis:z(), Axis:x()) + cosine(L3, L2, Distance) + 90
            holoAng(holoIndex(Knee), Hip:toWorld(ang(Atan, 0, 0)))
        #-Third
            holoAng(holoIndex(Ankle), Knee:toWorld(ang(cosine(Distance, L2, L3), 0, 0)))
    }
    #kinemize(E, Hip [ENTITY OF HOLOGRAM NOT INDEX], Knee[ENTITY OF HOLOGRAM NOT INDEX], Ankle[ENTITY OF HOLOGRAM NOT INDEX], Foot:toWorld(vec(0, 0, 0)))

    function vector bezier4([Source CurvePoint1 CurvePoint2 CurvePoint3 CurvePoint4 End]:vector, Progress)
    {
        return ((1 - Progress)^5 * Source) + (5*Progress*(1-Progress)^4 * CurvePoint1) + (10*Progress^2*(1 - Progress)^3 * CurvePoint2) + (10*Progress^3*(1 - Progress)^2 * CurvePoint3) + (5*Progress^4*(1 - Progress)*CurvePoint4) + (Progress^5 * End)
    }
    
    function vector bezier3([Source CurvePoint1 CurvePoint2 CurvePoint3 End]:vector, Progress) #Quartic Bezier
    {
        local Ti = 1-Progress
        local Q0 = mix(Source, CurvePoint1, Ti)
        local Q1 = mix(CurvePoint1, CurvePoint2, Ti)
        local Q2 = mix(CurvePoint2, CurvePoint3, Ti)
        local Q3 = mix(CurvePoint3, End, Ti)
        
        local R0 = mix(Q0, Q1, Ti)
        local R1 = mix(Q1, Q2, Ti)
        local R2 = mix(Q2, Q3, Ti)
        
        local S0 = mix(R0, R1, Ti)
        local S1 = mix(R1, R2, Ti)
        
        local T = mix(S0, S1, Ti)
        return T
    }
    
    function vector bezier2(Src:vector, End:vector, CurvePoint1:vector, CurvePoint2:vector, Progress:number)
    {
        local M1 = mix(mix(End, CurvePoint2, Progress), mix(CurvePoint2, CurvePoint1, Progress), Progress)
        local M2 = mix(mix(CurvePoint2, CurvePoint1, Progress), mix(CurvePoint1, Src, Progress), Progress)
        return mix(M1, M2, Progress)
    }
    
    function vector bezierS(Src:vector, End:vector, CurvePoint:vector, Progress:number)
    {
        return mix(mix(Src, CurvePoint, Progress), mix(CurvePoint, End, Progress), Progress)
    }
    
    function number entity:interceptR(T:vector)
    {
        local DifPos = T-This:pos()
        local DifVel = This:eye()
        return acosr(DifVel:normalized():dot(DifPos:normalized()))*180/pi()<90 ? sinr(acosr(DifVel:normalized():dot(DifPos:normalized())))*DifPos:length() : 0
    }
    
    function vector entity:interceptP(T:vector, R:number#[Radius]#)
    {
        local DifPos = T-This:pos()
        local DifVel = This:eye()
        return This:interceptR(T)<R&&acosr(DifVel:normalized():dot(DifPos:normalized()))*180/pi()<90 ? DifVel:normalized()*(DifPos:length()-R)+This:shootPos() : T+vec(0, 0, 200)
    }
	
    function number array:validate(E:entity)
    {
        if(!This:count())
        {
            return 0
        }
        
        foreach(I, TE:entity = This)
        {
            if(TE == E)
            {
                return I
            }
        }
        
        return 0
    }
}
