library MissileCollision /* v1.1
*************************************************************************************
*
* by mckill2009
*
*************************************************************************************
*
* An extremely simple missile projectile system that collides and damages on enemy units
* or blows on impact when desired distance is reached.
* The missile is recycle able so that it will not create different dummies everytime.
*
*************************************************************************************
*
* */ uses /*
*
* */ T32 /* http://www.thehelper.net/forums/showthread.php/132538-Timer32
* */ Dummy /* http://www.hiveworkshop.com/forums/jass-resources-412/system-dummy-213908/
*
************************************************************************************
*
* Credits
*
* Vexorian
* -----------------------
* For his DUMMY.mdx model
*
* Jesus4Lyf
* -----------------------
* For his Timer32 library
*
* Nesthaurus
* -----------------------
* For his Dummy library
*
************************************************************************************
*
* Installation:
* - Import the DUMMY.mdx model to your map
* - Copy the DummySfx unit from the object editor to your map and change the model to DUMMY.mdx
* - Copy ALL the Required Libraries and MissileCollicion folder to your map (except the DEMO)
* - Change the DUMMY_ID of the Dummy library to your imported DummySfx
*
************************************************************************************
*
* API:
* struct MC
* static method create takes player owningPlayer, real xWhere, real yWhere, string missileModel returns thistype
* - owningPlayer is the owner of the missile
* - xWhere and yWhere is the coordinate where the missile's origin or launched
*
* method setupCollision takes real aoe, real collision, string collisionEffect returns nothing
* - aoe is the area of effect damage when missile explodes
* - collision, missile will explode and deals damage if it collides with the first enemy unit in range
* - collisionEffect, the effect or eye candy of the explosion
*
* method setupDamage takes real damage, attacktype attackType, damagetype damageType returns nothing
* - damage, the damage when missile explodes
* - attackType and damageType is self explanatory
*
* method launch takes real facingInRadiants, real distance, real height, real speed returns nothing
* - facingInRadiants is the angle where the missile goes
* - distance is how far the missile traver
* - height and speed is the height of the missile and speed travel of the missile respectively
*
*
************************************************************************************
*/
private struct Delay
unit missile
real del
Dummy remove
endstruct
struct MC
private unit missile
private real aoeDamage
private real collision
private real distance
private real damage
private real height
private real speed
private real cos
private real sin
private string collisionEffect
private effect missileModel
private player pl
private attacktype atk
private damagetype dmg
private Dummy remove
private static group g = CreateGroup()
/*
*
* This block is used to delay the dummy to be recycled so that the effects will be
* visible from their origin attachment
*
*/
private static timer t = CreateTimer()
private static integer index = 0
private static integer array indexAR
private static method looper takes nothing returns nothing
local Delay this
local integer i = 0
loop
set i = i+1
set this = indexAR[i]
set this.del = this.del - 0.03125
if 0 > this.del then
call this.remove.destroy()
set this.missile = null
call this.destroy()
set indexAR[i] = indexAR[index]
set i = i - 1
set index = index - 1
if index==0 then
call PauseTimer(t)
endif
endif
exitwhen i==index
endloop
endmethod
private method delay takes nothing returns nothing returns nothing
local Delay m = Delay.create()
set m.missile = .missile
set m.del = 2.0
set m.remove = .remove
if index==0 then
call TimerStart(t, 0.03125, true, function thistype.looper)
endif
set index = index + 1
set indexAR[index] = m
endmethod
/*
*
* End of Delay block
*
*/
private method stop takes nothing returns nothing
call .delay()
call DestroyEffect(.missileModel)
set .missile = null
set .missileModel = null
call .stopPeriodic()
call .deallocate()
endmethod
private method damageThem takes real x, real y returns nothing
local unit first
if .collisionEffect!="" then
call DestroyEffect(AddSpecialEffectTarget(.collisionEffect, .missile, "origin"))
endif
call GroupEnumUnitsInRange(g, x, y, .aoeDamage, null)
loop
set first = FirstOfGroup(g)
exitwhen first==null
if not IsUnitType(first, UNIT_TYPE_DEAD) and IsUnitEnemy(first, .pl) then
if .atk==null or .dmg==null then
call UnitDamageTarget(.missile, first, .damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
else
call UnitDamageTarget(.missile, first, .damage, false, false, .atk, .dmg, null)
endif
endif
call GroupRemoveUnit(g, first)
endloop
call .stop()
endmethod
private method periodic takes nothing returns nothing
local unit first
local real xMissile = GetUnitX(.missile)
local real yMissile = GetUnitY(.missile)
if .distance > 0 then
set .distance = .distance - .speed
call SetUnitX(.missile, xMissile + .cos)
call SetUnitY(.missile, yMissile + .sin)
call GroupEnumUnitsInRange(g, xMissile, yMissile, .collision, null)
loop
set first = FirstOfGroup(g)
exitwhen first==null
if not IsUnitType(first, UNIT_TYPE_DEAD) and IsUnitEnemy(first, .pl) then
call .damageThem(xMissile, yMissile)
exitwhen true
endif
call GroupRemoveUnit(g, first)
endloop
else
call .damageThem(xMissile, yMissile)
endif
endmethod
implement T32x
/*
*
* API:
*
*/
static method create takes player owningPlayer, real xWhere, real yWhere, string missileModel returns thistype
local thistype this = allocate()
local Dummy d = Dummy.create(xWhere, yWhere, 0)
set .missile = d.unit
set .missileModel = AddSpecialEffectTarget(missileModel, .missile, "origin")
set .pl = owningPlayer
set .collisionEffect = ""
set .remove = d
if UnitAddAbility(.missile, 'Aloc') then
endif
return this
endmethod
method setupCollision takes real aoe, real collision, string collisionEffect returns nothing
set .aoeDamage = aoe
set .collision = collision
set .collisionEffect = collisionEffect
endmethod
method setupDamage takes real damage, attacktype attackType, damagetype damageType returns nothing
set .damage = damage
set .atk = attackType
set .dmg = damageType
endmethod
method launch takes real facingInRadiants, real distance, real height, real speed returns nothing
set .distance = distance
set .height = height
set .speed = speed
set .cos = speed * Cos(facingInRadiants)
set .sin = speed * Sin(facingInRadiants)
call SetUnitFlyHeight(.missile, height, 0)
call SetUnitFacing(.missile, facingInRadiants*bj_RADTODEG)
call .startPeriodic()
endmethod
endstruct
endlibrary