//made by hell gate
library UnitCollision initializer Init
globals
private hashtable UC_Hash
private constant integer Sphere = 1
private constant integer Cylinder = 2
private real MaxCollSize = 0.
private constant integer DummyId = 'h000' // your private dummy unit
endglobals
function GetUnitCollSizeSphere takes unit u returns real
return LoadReal( UC_Hash, GetUnitTypeId(u), 1)
endfunction
function GetUnitRadCylinder takes unit u returns real
return LoadReal( UC_Hash, GetUnitTypeId(u), 1)
endfunction
function GetUnitHeightCylinder takes unit u returns real
return LoadReal( UC_Hash, GetUnitTypeId(u), 2)
endfunction
function GetUnitType takes unit u returns integer
return LoadInteger(UC_Hash,GetUnitTypeId(u),0)
endfunction
function AddUnitCollisionSphere takes integer uID, real rad returns nothing
call SaveInteger(UC_Hash, uID, 0, Sphere)
call SaveReal(UC_Hash, uID, 1, rad)
if rad >= MaxCollSize then
set MaxCollSize =rad+.5
endif
endfunction
function AddUnitCollisionCylinder takes integer uID, real rad, real height returns nothing
local real x = SquareRoot((rad*rad)+(height*height))
call SaveInteger(UC_Hash, uID, 0, Cylinder)
call SaveReal(UC_Hash, uID, 1, rad)
call SaveReal(UC_Hash, uID, 2, height)
if x >= MaxCollSize then
set MaxCollSize = x+.5
endif
endfunction
function CheckForCollision takes real x, real y, real z, real size, player p returns boolean
local group g = CreateGroup()
local unit u = null
local real array r
local boolean b = false
local location p1
local location p2
call GroupEnumUnitsInRange( g, x, y, MaxCollSize, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null or b == true
if GetUnitTypeId(u)!= DummyId and GetUnitState(u,UNIT_STATE_LIFE) > 0.405 then
if GetUnitType(u) == Sphere then
set r[0] = x - GetUnitX(u)
set r[1] = y - GetUnitY(u)
set r[2] = SquareRoot(r[0] * r[0] + r[1] * r[1])
set p1 = GetUnitLoc(u)
set p2 = Location(x,y)
set r[3] = (GetUnitFlyHeight(u)+GetLocationZ(p1))-(z+GetLocationZ(p2))
set r[4] = SquareRoot(r[2] * r[2] + r[3] * r[3])
set b = ((r[4] <= GetUnitCollSizeSphere(u)+size) and GetOwningPlayer(u) != p)
call RemoveLocation(p1)
call RemoveLocation(p2)
elseif GetUnitType(u) == Cylinder then
set r[0] = x - GetUnitX(u)
set r[1] = y - GetUnitY(u)
set r[2] = SquareRoot(r[0] * r[0] + r[1] * r[1])
set p1 = GetUnitLoc(u)
set p2 = Location(x,y)
set r[3] = GetUnitFlyHeight(u)
set b = (r[2] <= GetUnitRadCylinder(u)+size and z+GetLocationZ(p2) > r[3]-size+GetLocationZ(p1) and z+GetLocationZ(p2) < r[3]+GetUnitHeightCylinder(u)+size+GetLocationZ(p1) and GetOwningPlayer(u) != p)
call RemoveLocation(p1)
call RemoveLocation(p2)
endif
endif
call GroupRemoveUnit(g,u)
set u = null
endloop
call DestroyGroup(g)
set g = null
set u = null
return b
endfunction
// extra function to damage units in range with the unit collision system
// (simpel edit from the check for collision function)
function DamageUnitInRange takes real x, real y, real z, real damage, real rad, unit damagedealer returns nothing
local group g = CreateGroup()
local unit u = null
local real array r
local location p1
local location p2
call GroupEnumUnitsInRange( g, x, y, MaxCollSize, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if GetUnitTypeId(u)!= DummyId and GetUnitState(u,UNIT_STATE_LIFE) > 0.405 then
if GetUnitType(u) == Sphere then
set r[0] = x - GetUnitX(u)
set r[1] = y - GetUnitY(u)
set r[2] = SquareRoot(r[0] * r[0] + r[1] * r[1])
set p1 = GetUnitLoc(u)
set p2 = Location(x,y)
set r[3] = (GetUnitFlyHeight(u)+GetLocationZ(p1))-(z+GetLocationZ(p2))
set r[4] = SquareRoot(r[2] * r[2] + r[3] * r[3])
if (r[4] <= GetUnitCollSizeSphere(u)+rad) and GetOwningPlayer(u) != GetOwningPlayer(damagedealer) then
call UnitDamageTarget(damagedealer, u, damage, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
call RemoveLocation(p1)
call RemoveLocation(p2)
elseif GetUnitType(u) == Cylinder then
set r[0] = x - GetUnitX(u)
set r[1] = y - GetUnitY(u)
set r[2] = SquareRoot(r[0] * r[0] + r[1] * r[1])
set p1 = GetUnitLoc(u)
set p2 = Location(x,y)
set r[3] = GetUnitFlyHeight(u)
if r[2] <= GetUnitRadCylinder(u)+rad and z+GetLocationZ(p2) > r[3]-rad+GetLocationZ(p1) and z+GetLocationZ(p2) < r[3]+GetUnitHeightCylinder(u)+rad+GetLocationZ(p1) and GetOwningPlayer(u) != GetOwningPlayer(damagedealer) then
call UnitDamageTarget(damagedealer, u, damage, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
call RemoveLocation(p1)
call RemoveLocation(p2)
endif
endif
call GroupRemoveUnit(g,u)
set u = null
endloop
call DestroyGroup(g)
set g = null
set u = null
endfunction
private function Init takes nothing returns nothing
set UC_Hash = InitHashtable()
call AddUnitCollisionSphere('h004',100)
call AddUnitCollisionSphere('h001',30)
call AddUnitCollisionSphere('h005',50)
call AddUnitCollisionSphere('h007',90)
call AddUnitCollisionCylinder('h002',50,45)
call AddUnitCollisionCylinder('h008',45,100)
call AddUnitCollisionCylinder('h006',100,240)
call AddUnitCollisionCylinder('h003',60,280)
call AddUnitCollisionCylinder('h009',12.5,35)
call AddUnitCollisionCylinder('h00A',14,35)
endfunction
endlibrary