• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a faction for Warcraft 3 and enter Hive's 19th Techtree Contest: Co-Op Commanders! Click here to enter!
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 21st Texturing Contest: Upgrade is now concluded, time to vote for your favourite set of icons! Click here to vote!

Collision Detection using phoenix fire

Status
Not open for further replies.
Level 23
Joined
Jan 1, 2009
Messages
1,618
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,618
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