• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

Collision Detection using phoenix fire

Status
Not open for further replies.
Level 23
Joined
Jan 1, 2009
Messages
1,608
Someone here http://www.hiveworkshop.com/forums/lab-715/what-do-you-think-best-collision-detection-method-253285/ said it would be cool if someone made a script for it, so I tried it and it actually works favourably!

Supports 2 timeouts at the moment but could easily add more.
As it's not a fully fledged system I'm dropping it in the Lab (but it works).

And yes, using a simple enterRect event for adding units to the damageEvent.
Could probably be improved and you could use a unitindexer if you want.

Also you have to call init_CollisionDetection(boolean compileTime, int minCollisionSize, int maxCollisionSize) once at compiletime (with the boolean = true) and once ingame (with the boolean = false).
I know this sucks for a system, that's why it's here, just for fun.
If someone really wants it I can put it into a more general form.

Usage example:
Wurst:
let u = createUnit(vec2(0,0), 'hpea', angle(0))
u.registerOnHitCallback(128, (unit hit, unit hitter) -> begin
	if u == hitter
		hit.kill()
end)

//Remove later
u.removeOnHitCallback()

Creates a peasant that kills every unit it touches in a 128 radius.

System Code:
Wurst:
package CollisionDetection
import AbilityObjEditing
import MapBounds
import HashMap
import ObjectIdGenerator

int MAX_COLLISION_SIZE
int MIN_COLLISION_SIZE
int array fastIds
int array slowIds

HashMap<unit, CollisionCallback> callbackMap = new HashMap<unit, CollisionCallback>()

public abstract class CollisionCallback
	abstract function run(unit hit, unit hitter)
	
public function unit.registerOnHitCallback(CollisionCallback cc)
	callbackMap.put(this, cc)
	
public function unit.registerOnHitCallback(int radius, boolean fast, CollisionCallback cc )
	if radius < MIN_COLLISION_SIZE or radius > MAX_COLLISION_SIZE
		error("Radius out of Bounds")
	callbackMap.put(this, cc)
	var lvl = radius mod 4
	if lvl == 0
		lvl = 4
	if fast
		this..addAbility(fastIds[radius])..setAbilityLevel(fastIds[radius], lvl)
	else
		this..addAbility(slowIds[radius])..setAbilityLevel(slowIds[radius], lvl)
	
public function unit.removeOnHitCallback()
	destroy callbackMap.get(this)
	callbackMap.put(this, null)


trigger enterRect = CreateTrigger()
trigger damageTrig = CreateTrigger()

function unit.registerDamage()
	damageTrig.registerUnitEvent(this, EVENT_UNIT_DAMAGED)

public function init_CollisionDetection(boolean compileTime, int minCollisionSize, int maxCollisionSize)
	MAX_COLLISION_SIZE = maxCollisionSize
	MIN_COLLISION_SIZE = minCollisionSize
	if minCollisionSize mod 4 != 0
		error("minCollisionSize must be congruent to 0 mod 4")
	if maxCollisionSize mod 4 != 0
		error("maxCollisionSize must be congruent to 0 mod 4")
	for i = MIN_COLLISION_SIZE to MAX_COLLISION_SIZE
		fastIds[i] = ABIL_ID_GEN.next()
		fastIds[i+1] = fastIds[i]
		fastIds[i+2] = fastIds[i]
		fastIds[i+3] = fastIds[i]
		if c
			var def = new AbilityDefinitionPhoenixFire(fastIds[i])
			..setMissileArt("")..setMissileSpeed(0)..setEditorSuffix("(Collision Detection)")
			for j = 1 to 4
				def..setAreaofEffect(j, i+j * 1.)
				..setInitialDamage(j, 0)..setDamagePerSecond(j, 0)..setCooldown(j, 0.03)..setTargetsAllowed(j, "air,ground,notself")
		i += 3
		
		
	for i = MIN_COLLISION_SIZE to MAX_COLLISION_SIZE
		slowIds[i] = ABIL_ID_GEN.next()
		slowIds[i+1] = slowIds[i]
		slowIds[i+2] = slowIds[i]
		slowIds[i+3] = slowIds[i]
		if c
			var def = new AbilityDefinitionPhoenixFire(slowIds[i])
			..setMissileArt("")..setMissileSpeed(0)..setEditorSuffix("(Collision Detection)")
			for j = 1 to 4
				def..setAreaofEffect(j, i+j * 1.)
				..setInitialDamage(j, 0)..setDamagePerSecond(j, 0)..setCooldown(j, 0.25)..setTargetsAllowed(j, "air,ground,notself")
		i += 3
			
	if not c
		damageTrig.addAction(() -> begin
			let u = GetTriggerUnit()
			if u.hasAbility('Bpxf')
				u.removeAbility('Bpxf')
				var cc = callbackMap.get(u)
				let u2 = GetEventDamageSource()
				print(u2.getName())
				if cc != null
					cc.run(u, u2)
				cc = callbackMap.get(u2)
				if cc != null
					cc.run(u, u2)
					
		end)
		enterRect.registerEnterRegion(mapRegion, Filter(() -> GetFilterUnit().registerDamage()))
 
Level 23
Joined
Jan 1, 2009
Messages
1,608
Awesome as well cool, thanks for making one.

I would prefer a test map uploaded since I am a GUI'er. Sure I can read that, but I would like to see it in action too.

Edit: I made my mind up, I shall be making a GUI version of this idea.

hm sure. What would you like in the testmap?
Only some colliding units stresstest or spells?

e: there could be a debugmode that shows the missiles
 
Status
Not open for further replies.
Top