@name holoPhys

#1-Body Gravity
function entity createGBody(Index, Base:entity)
{
    local Offset = (randvec(-1, 1):normalized() * Base["radius", number])
    local H = holoCreate(Index, Base:pos() + Offset, vec(0.5))
    holoModel(Index, "hq_sphere")
    holoColor(Index, vec(255, 100, 0))
    holoDisableShading(Index, 1)
    
    H:setTrails(5, 0, 10, "effects/beam_generic01", vec(255), 255)
    
    #H["vel", vector] = Offset:cross(randvec(-1, 1)):normalized() * 5
    H["vel", vector] = Offset:cross(randvec(-1, 1)):normalized() * sqrt(2500/Base:pos():distance(holoEntity(Index):pos()))
    
    return H
}

function entity:bodyGravity(ForeignBody:entity, Gravity)
{
    local GravF = (Gravity / (ForeignBody:pos():distance(This:pos()) ^ 2))
    local GravD = (ForeignBody:pos() - This:pos()):normalized()
    
    This["vel", vector] = This["vel", vector] + (GravD * GravF)
}

function handleGBody(Index, Base:entity, Gravity)
{
    local H = holoEntity(Index)
    
    H:bodyGravity(Base, Gravity)
    
    holoPos(Index, H:pos() + H["vel", vector])
}

#######################################

#N-Body Gravity
function entity createNBody(Index, Base:entity)
{
    local Offset = (randvec(-1, 1):normalized() * Base["radius", number])
    local H = holoCreate(Index, Base:pos() + Offset)
    holoModel(Index, "hq_sphere")
    holoColor(Index, vec(255, 150, 150))
    
    H["mass", number] = random(300, 3000)
    
    holoScale(Index, vec(H["mass", number] / 500))
    
    H:setTrails(H["mass", number] / 40, 0, 3, "effects/beam_generic01", vec(255), 255)
    
    return H
}

function entity:bodyNGravity(ForeignBody:entity, Gravity)
{
    local GravF = (Gravity / (ForeignBody:pos():distance(This:pos()) ^ 2)) / This["mass", number]
    local GravD = (ForeignBody:pos() - This:pos()):normalized()
    
    This["vel", vector] = This["vel", vector] + (GravD * GravF)
    
    #Collision detection hacked in
    if(This:pos():distance(ForeignBody:pos()) < (This["mass", number] + ForeignBody["mass", number]) / (500 / 6))
    {
        while(perf() & (This:pos():distance(ForeignBody:pos()) < (This["mass", number] + ForeignBody["mass", number]) / (500 / 6)))
        {
            holoPos(holoIndex(This), This:pos() + (This:pos() - ForeignBody:pos()):normalized() * 5)
            holoPos(holoIndex(ForeignBody), ForeignBody:pos() + (ForeignBody:pos() - This:pos()):normalized() * 5)
        }
    }
}

function handleNBody(Index, Base:entity, Gravity, Count)
{
    local H = holoEntity(Index)
    
    for(I = 1, Count)
    {
        if(I != Index)
        {
            H:bodyNGravity(holoEntity(I), Gravity)
        }
    }
    
    holoPos(Index, H:pos() + H["vel", vector])
}

#######################################

#Momentum
function entity createMBody(Index, Pos:vector, Style:table)
{
    local H = holoCreate(Index, Pos, Style[1, array][1, vector], ang(), Style[1, array][2, vector], Style[1, array][3, string])
    
    holoDisableShading(1, Style[1, array][4, number])
    
    if(Style[2, array][1, string] != "no")
    {
        H:setTrails(Style[2, array][1, number], Style[2, array][2, number],
                    Style[2, array][3, number], Style[2, array][4, string],
                    Style[2, array][5, vector], Style[2, array][6, number])
    }
    
    return H
}

function handleMBody(Index, TargetPos:vector, ForceMult, Drag)
{
    local H = holoEntity(Index)
    
    local ApplyForce = (TargetPos - H:pos()) * ForceMult
    
    H["vel", vector] = (H["vel", vector] + ApplyForce) * Drag
    
    holoPos(Index, H:pos() + H["vel", vector])
}
