- Joined
- Mar 16, 2008
- Messages
- 941
hey guys.
Well, I was pretty bored for a few days and thought of some systems I could create.
I think all of you know that the wc3 collision engine sucks heavily. It only checks for a circle around a point which is located in the middle of the object/unit.
I thought of creating a hitbox system, allowing to create multiple parts of the unit, like legs, chest, the arms and so on. I had an idea and created a system, but I don't like it at all. It is unperformant and unbelievable heavy to configurate.
I just allow the user to add the coordinates of all edges...:
And, what do I want?
I'm asking for another way of doing this
Creating a (good) hitbox with this takes hours :/
EDIT: I don't know why the code isn't indentioned correctly, no matter how often I CnP it, it doesn't change anything
Well, I was pretty bored for a few days and thought of some systems I could create.
I think all of you know that the wc3 collision engine sucks heavily. It only checks for a circle around a point which is located in the middle of the object/unit.
I thought of creating a hitbox system, allowing to create multiple parts of the unit, like legs, chest, the arms and so on. I had an idea and created a system, but I don't like it at all. It is unperformant and unbelievable heavy to configurate.
I just allow the user to add the coordinates of all edges...:
JASS:
library HitboxSystem
private keyword Hitbox_Part
private keyword CollisionCheck
globals
private constant integer HITBOX_MAX_BODIES = 100
private constant integer HITBOX_MAX_FIELDS = 20
private constant integer HITBOX_MAX_ANIMATIONS = 100
private constant integer HITBOX_MAX_ANI_BODIES = 20
endglobals
private struct Hitbox_Body[HITBOX_MAX_BODIES]
private integer max_field = 0
private Hitbox_Part array fields[HITBOX_MAX_FIELDS]
method Addfield takes Hitbox_Part field returns nothing
set .fields[.max_field] = field
set .max_field = .max_field+1
endmethod
method CollisionCheckBody takes unit u1, Hitbox_Body body2, unit u2 returns boolean
local integer i = 0
loop
exitwhen i >= .max_field
if .fields[i].CollisionCheckPart(u1, body2, u2) then
return true
endif
set i = i+1
endloop
return false
endmethod
endstruct
private struct Hitbox_Part
private string name
private real x1
private real x2
private real y1
private real y2
private real z1
private real z2
static method create takes Hitbox_Body body, string name, integer x1, integer x2, integer y1, integer y2, integer z1, integer z2 returns Hitbox_Part
local Hitbox_Part field = Hitbox_Part.allocate()
set field.name = name
set field.x1 = x1
set field.x2 = x2
set field.y1 = y1
set field.y2 = y2
set field.z1 = z1
set field.z2 = z2
call body.Addfield(field)
return field
endmethod
method CollisionCheckPart takes unit u1, Hitbox_Part field, unit u2 returns boolean
local real x1 = GetUnitX(u1)+.x1
local real x2 = GetUnitX(u1)-.x2
local real y1 = GetUnitY(u1)+.y1
local real y2 = GetUnitY(u1)-.y2
local real z1 = GetUnitFlyHeight(u1)+.z1
local real z2 = GetUnitFlyHeight(u1)-.z2
local real x3 = GetUnitX(u2)+field.x1
local real x4 = GetUnitX(u2)-field.x2
local real y3 = GetUnitY(u2)+field.y1
local real y4 = GetUnitY(u2)-field.y2
local real z3 = GetUnitFlyHeight(u2)+field.z1
local real z4 = GetUnitFlyHeight(u2)-field.z2
return ((x1 <= x3 and x1 >= x4) or (x2 <= x3 and x2 >= x4)) and ((y1 <= y3 and y1 >= y4) or (y2 <= y3 and y2 >= y4)) and ((z1 <= z3 and z1 >= z4) or (z2 <= z3 and z2 >= z4))
endmethod
endstruct
private struct Hitbox_Animation[HITBOX_MAX_ANIMATIONS]
private string name
integer array hitbox[HITBOX_MAX_ANI_BODIES]
real array hitbox_delay[HITBOX_MAX_ANI_BODIES]
real end
integer max_box = 0
static method create takes string name, real end returns Hitbox_Animation
local Hitbox_Animation ani = Hitbox_Animation.allocate()
set ani.name = name
set ani.end = end
return ani
endmethod
method AddBody takes Hitbox_Body body, real delay returns nothing
set .hitbox[.max_box] = body
set .hitbox_delay[.max_box] = delay
set .max_box = .max_box+1
endmethod
endstruct
function CheckHitboxCollision takes integer body1, unit u1, integer body2, unit u2 returns boolean
return Hitbox_Body(body1).CollisionCheckBody(u1, Hitbox_Body(body2), u2)
endfunction
//Still in progress
function ReturnAnimatedHitboxTimed takes integer ani, real time returns integer
local Hitbox_Animation animation = Hitbox_Animation(ani)
local integer i = 0
if time >= animation.end then
return -1
endif
loop
exitwhen i >= animation.max_box
if animation.hitbox_delay[i] >= time then
return animation.hitbox[i]
endif
set i = i+1
endloop
return i-1
endfunction
//---------------
function AddHitboxAnimation takes integer ani, integer body, real delay returns nothing
call Hitbox_Animation(ani).AddBody(body, delay)
endfunction
function CreateHitboxAnimation takes string name, real end returns integer
return integer(Hitbox_Animation.create(name, end))
endfunction
function AddHitboxField takes integer body, string name, integer x1, integer x2, integer y1, integer y2, integer z1, integer z2 returns nothing
call Hitbox_Part.create(Hitbox_Part(body), name, x1, x2, y1, y2, z1, z2)
endfunction
function CreateHitbox takes nothing returns integer
return integer(Hitbox_Body.create())
endfunction
endlibrary
And, what do I want?
I'm asking for another way of doing this
Creating a (good) hitbox with this takes hours :/
EDIT: I don't know why the code isn't indentioned correctly, no matter how often I CnP it, it doesn't change anything