wraithseeker
Tired.
- Reaction score
- 122
JASS:
library Knockback initializer Init requires DestructableLib, IsTerrainWalkable, GroupUtils, PUI
globals
private constant real TIME = 0.03 // The timer interval.
private constant real CHAINRADIUS = 100.00 // The radius a unit can get chained when near the unit target.
private constant real SPEEDFACTOR = 0.75 // How much speed will be reduced when a unit chains another unit.
private constant real RADIUS = 128.00 // The radius to check tree.
private constant real HEIGHTLEVEL = 200.00 // The default height level that stops chaining or killing trees when in the air.
private constant real FACTOR = 0.3333 // Or 0.25 for smoothness.
private constant string GROUND = "MDX\\Dust.mdx" // The effect for ground.
private constant string WATER = "MDX\\SlideWater.mdx" // The effect for water.
private constant string COLLISION = "MDX\\DustAndRocks.mdx" // The effect when at cliff
private constant string FLYING = "MDX\\TornadoMissile.mdx"// The effect when flying
private constant string ATTACHPOINT = "origin" // The attachment point for effects
endglobals
globals
private constant integer INVULNERABLE = 039;Avul039;
private constant integer FLYID = 039;Amrf039;
private rect TreeRect = null
private boolexpr TreeCheck = null
private boolexpr ChainFilter = null
private unit Target = null
private unit Source = null
private real MapMaxX = 0
private real MapMaxY = 0
private real MapMinX = 0
private real MapMinY = 0
private Knock D
endglobals
private function CheckTrees takes nothing returns boolean
return IsDestructableTree(GetFilterDestructable())
endfunction
private function Trees takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
private function ChainCheck takes nothing returns boolean
return Target != GetFilterUnit() and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(Source)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false and GetWidgetLife(GetFilterUnit()) > 0.405 and GetUnitAbilityLevel(GetFilterUnit(),INVULNERABLE) <= 0
endfunction
function ParabolaZ takes real h, real d, real x returns real
return (4 * h / d) * (d - x) * (x / d)
endfunction
private function IsPointOutside takes real x, real y returns boolean
return (x > MapMaxX or y > MapMaxY or x < MapMinX or y < MapMinY)
endfunction
public struct Knock
private static timer Timer = CreateTimer()
private static Knock array D
private static integer Count = 0
//! runtextmacro PUI()
unit source = null
unit target = null
integer mode = 0
group hit = null
real cos = 0
real sin = 0
real speed = 0
real decrement = 0
real distance = 0
real positionZ = 0
effect effects = null
boolean terrain = false
boolean trees = false
boolean chain = false
boolean fly = false
private method TerrainCheck takes nothing returns integer
local real x = GetUnitX(.target)
local real y = GetUnitY(.target)
if IsTerrainWalkable(x + 50.00 * .cos,y + 50.00 * .sin) == false then
return 3
else
if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
return 1
elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
return 2
endif
endif
return 0
endmethod
static method create takes unit source, unit target, real angle, real speed, real decrement, boolean tree,boolean chain, boolean fly returns Knock
local Knock d = Knock.allocate()
if target == null or source == null or speed == null or decrement == null then
debug call BJDebugMsg("Invalid Values!")
call d.destroy()
endif
set d.source = source
set d.target = target
set d.trees = tree
set d.fly = fly
set d.chain = chain
set d.hit = NewGroup()
set d.speed = speed * TIME
set d.decrement = decrement * TIME
set d.sin = Sin(angle)
set d.cos = Cos(angle)
set d.distance = -1 * speed * speed / (2 * -decrement / TIME)
set d.positionZ = 0
if d.fly then
call SetUnitPathing(d.target,false)
call UnitAddAbility(d.target,FLYID)
call UnitRemoveAbility(d.target,FLYID)
set d.effects = AddSpecialEffectTarget(FLYING,d.target,ATTACHPOINT)
endif
set d.mode = d.TerrainCheck()
if d.mode == 1 then
set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
elseif d.mode == 2 then
set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
elseif d.mode == 3 then
set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
endif
set Knock[target] = d
if Knock.Count == 0 then
call TimerStart(Knock.Timer,TIME,true,Knock.Periodic)
endif
set Knock.D[Knock.Count] = d
set Knock.Count = Knock.Count + 1
return d
endmethod
private method onDestroy takes nothing returns nothing
call DestroyEffect(.effects)
call ReleaseGroup(.hit)
call SetUnitFlyHeight(.target,0,0)
call SetUnitPathing(.target,true)
endmethod
private method action takes nothing returns boolean
local unit t = null
local real x = 0.00
local real y = 0.00
local real cx = 0.00
local real cy = 0.00
local integer mode = 0
local Knock d
set mode = .mode
set x = GetUnitX(.target)
set y = GetUnitY(.target)
set height = GetUnitFlyHeight(.target)
set .positionZ = .positionZ + .speed
if height >= HEIGHTLEVEL then
set .chain = false
set .trees = false
endif
if .speed <= 0 or IsPointOutside(x,y) then
return true
endif
if .trees then
call SetRect(TreeRect,x-RADIUS,y-RADIUS,x+RADIUS,y+RADIUS)
call EnumDestructablesInRect(TreeRect,TreeCheck,function Trees)
endif
if .fly then
call SetUnitFlyHeight(.target,ParabolaZ(FACTOR*.distance,.distance,.positionZ),0)
endif
set .mode = .TerrainCheck()
if .mode == 1 and (mode == 2 or mode == 3) then
call DestroyEffect(.effects)
set .effects = AddSpecialEffectTarget(GROUND,.target,ATTACHPOINT)
elseif .mode == 2 and (mode == 1 or mode == 3) then
call DestroyEffect(.effects)
set .effects = AddSpecialEffectTarget(WATER,.target,ATTACHPOINT)
elseif .mode == 3 and (mode == 1 or mode == 2) then
call DestroyEffect(.effects)
set .effects = AddSpecialEffectTarget(COLLISION,.target,ATTACHPOINT)
endif
if .chain == true then
call GroupEnumUnitsInRange(ENUM_GROUP,x,y,CHAINRADIUS,ChainFilter)
loop
set t = FirstOfGroup(ENUM_GROUP)
exitwhen t == null
if not IsUnitInGroup(t,.hit) then
set cx = GetUnitX(t)
set cy = GetUnitY(t)
call GroupAddUnit(.hit,t)
set d = Knock.create(.source,t,Atan2(cy-y,cx-x),(.speed/TIME)*SPEEDFACTOR,(.decrement/TIME),.trees,.chain,.fly)
call GroupAddUnit(.hit,.target)
set .D[.Count] = d
set .Count = .Count + 1
endif
call GroupRemoveUnit(ENUM_GROUP,t)
endloop
endmethod
private method Periodic takes nothing returns nothing
local integer i = 0
loop
exitwhen i < 0
if .D<i>.actions() then
set .Count = .Count - 1
if .Count > 0 then
set .D<i> = .D[.Count]
set i = i - 1
else
call PauseTimer(.Timer)
endif
set i = i + 1
endloop
endmethod
endstruct
function KnockbackStop takes unit target returns boolean
local Knock d = Knock[target]
if d != 0 then
call d.release()
set Knock.Count = Knock.Count - 1
if Knock.Count > 0 then
set Knocker<i> = Knocker[Count]
else
call PauseTimer(Knock.Timer)
endif
return true
endif
return false
endfunction
function IsKnockedBack takes unit target returns boolean
return Knock[target] != 0
endfunction
private function Init takes nothing returns nothing
set Timer = CreateTimer()
set TreeRect = Rect(0.00,0.00,1.00,1.00)
set TreeCheck = Filter(function CheckTrees)
set ChainFilter = Filter(function ChainCheck)
set MapMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
set MapMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
set MapMinX = GetRectMinX(bj_mapInitialPlayableArea)
set MapMinY = GetRectMinY(bj_mapInitialPlayableArea)
endfunction
endlibrary</i></i></i>
The one highlighted gives a syntax error saying D is not a member of my struct.
JASS:
set .D[.Count] = this
Any clues?