- Joined
- Mar 24, 2013
- Messages
- 1,105
Hi all,
Saw someone post on this thread Debugging and I was reminded of the Handle Counter, however based on my reading the handle counter is supposed to go back down eventually. Mine is increasing marginally, it will increase by about 15 to 20 then drop to an increase of about 10 or so each time my spell is fired.
Can anyone take a look to see where I might be going wrong? I've also attached a test map.
Saw someone post on this thread Debugging and I was reminded of the Handle Counter, however based on my reading the handle counter is supposed to go back down eventually. Mine is increasing marginally, it will increase by about 15 to 20 then drop to an increase of about 10 or so each time my spell is fired.
Can anyone take a look to see where I might be going wrong? I've also attached a test map.
JASS:
library Space initializer init requires TimedEffect
globals
private unit array u
private effect array e
private real array d
private real array px
private real array py
private real array pulse
private boolean array b
private real array rAngle
private player array p
private integer index = 0
private integer index2 = 0
private unit array u2
private real array fireAngle
private constant real DISTANCE = 900./32.
private real array fireDuration
private group array fireGroup
private integer array counter
private constant integer SPX_COUNTER = 2
private constant string ROCKET_EFFECT = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl"
private constant real ROCKET_EFFECT_DURATION = .5
private constant string ROCKET_EFFECT_TARGET = "Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl"
private constant real ROCKET_DAMAGE = 300.
private constant real ROCKET_AOE_CHECK = 150.
private constant group TR_GROUP = CreateGroup()
private constant real TIMEOUT = .03125
private timer t = CreateTimer()
private timer t2 = CreateTimer()
private constant integer THUNDER_ROCKET = 'A000'
private constant real DURATION = 6.
private constant real EFFECT_JITTER_AOE = 625. // to avoid using Sqrt for efficency, multiple the jitter AOE by itself (25*25)
private constant string EFFECT = "Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl" //"Abilities\\Weapons\\Bolt\\BoltImpact.mdl" //"Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl""Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
private constant real OFFSET = 200.
private constant real OFFSET2 = 18.
private constant string PULSE_EFFECT = "Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"
private constant real PULSE_TIMEOUT = 1.
private constant real PULSE_AOE_CHECK = 200.
private constant real PULSE_EFFECT_SCALE = 2.4
private constant real PULSE_EFFECT_DURATION = .8
private constant real PULSE_DAMAGE = 150.
private constant real TRACK_DAMAGE = 5.
private constant real TRACK_AOE_CHECK = 100.
endglobals
function UnitAlive takes unit u returns boolean
return not IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0
endfunction
private function TRLoop2 takes nothing returns nothing
local integer i = 0
local real x
local real y
local real angle
local group g = TR_GROUP
local unit tU
loop
exitwhen i >= index2
set fireDuration[i] = fireDuration[i] - TIMEOUT
if fireDuration[i] <= 0. then
call SetUnitPropWindow(u2[i], GetUnitDefaultPropWindow(u2[i]))
call SetUnitPathing(u2[i], true)
call DestroyGroup(fireGroup[i])
set index2 = index2 - 1
set u2[i] = u2[index2]
set fireAngle[i] = fireAngle[index2]
set fireDuration[i] = fireDuration[index2]
set counter[i] = counter[index2]
set fireGroup[i] = fireGroup[index2]
set i = i - 1
if index2 == 0 then
call PauseTimer(t2)
endif
else
if GetUnitPropWindow(u2[i]) != 0. then
call SetUnitPropWindow(u2[i], 0.)
endif
set x = GetUnitX(u2[i])
set y = GetUnitY(u2[i])
if counter[i] <= 0 then
set counter[i] = SPX_COUNTER
call EffectApplyTimedLife(AddSpecialEffect(ROCKET_EFFECT, x, y), ROCKET_EFFECT_DURATION)
else
set counter[i] = counter[i] - 1
endif
set angle = DISTANCE * Cos(fireAngle[i])
set x = x + angle
set angle = DISTANCE * Sin(fireAngle[i])
set y = y + angle
call GroupEnumUnitsInRange(g, x, y, ROCKET_AOE_CHECK, null)
loop
set tU = FirstOfGroup(g)
exitwhen tU == null
call GroupRemoveUnit(g, tU)
if UnitAlive(tU) and IsUnitEnemy(tU, GetOwningPlayer(u2[i])) and not IsUnitInGroup(tU, fireGroup[i]) then
call GroupAddUnit(fireGroup[i], tU)
call EffectApplyTimedLife(AddSpecialEffect(ROCKET_EFFECT_TARGET, GetUnitX(tU), GetUnitY(tU)), ROCKET_EFFECT_DURATION)
call UnitDamageTarget(u[i], tU, ROCKET_DAMAGE, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
endif
endloop
call GroupClear(g)
// check and destroy trees/destructibles prior to moving
call TreeSearch(x,y, 0.)
if FreePathing(x,y) then
call SetUnitX(u2[i], x)
call SetUnitY(u2[i], y)
else
set fireDuration[i] = 0. // end early if unable to move.
endif
endif
set i = i + 1
endloop
set g = null
set tU = null
endfunction
private function TRFire takes unit u, real x, real y, real z returns nothing
local real x2
local real y2
set u2[index2] = u
call SetUnitPathing(u2[index2], false)
call SetUnitPropWindow(u2[index2], 0.)
set x2 = GetUnitX(u2[index2])
set y2 = GetUnitY(u2[index2])
set fireAngle[index2] = z
set fireDuration[index2] = 1.
set counter[index2] = 0
set fireGroup[index2] = CreateGroup()
set index2 = index2 + 1
if index2 == 1 then
call TimerStart(t2, TIMEOUT, true, function TRLoop2)
endif
endfunction
private function TRLoop takes nothing returns nothing
local integer i = 0
local group g = TR_GROUP
local real x
local real y
local real x2
local real y2
local real angle
local real angle2
local real dx
local real dy
local real dz
local unit tU
local boolean tB
local effect tE
loop
exitwhen i >= index
set d[i] = d[i] - TIMEOUT
set pulse[i] = pulse[i] - TIMEOUT
set x = BlzGetLocalSpecialEffectX(e[i])
set y = BlzGetLocalSpecialEffectY(e[i])
set x2 = x
set y2 = y
if b[i] == true then
set angle = rAngle[i]
else
set angle = Atan2(py[i]-y, px[i]-x)
set rAngle[i] = angle
endif
set angle2 = OFFSET2 * Cos(angle)
set x = x + angle2
set angle2 = OFFSET2 * Sin(angle)
set y = y + angle2
set dx = x2 - px[i]
set dy = y2 - py[i]
set dz = ((dx * dx) + (dy * dy)) * ((dx * dx) + (dy * dy))
if dz > EFFECT_JITTER_AOE or b[i] then
call BlzSetSpecialEffectX(e[i], x)
call BlzSetSpecialEffectY(e[i], y)
call BlzSetSpecialEffectHeight( e[i], 100.00 )
call BlzSetSpecialEffectOrientation(e[i], angle,0,0)
endif
if pulse[i] <= 0. then
set tE = AddSpecialEffect(PULSE_EFFECT, x,y)
call BlzSetSpecialEffectScale(tE, PULSE_EFFECT_SCALE)
call EffectApplyTimedLife(tE, PULSE_EFFECT_DURATION)
call GroupEnumUnitsInRange(g, x, y, PULSE_AOE_CHECK, null)
loop
set tU = FirstOfGroup(g)
exitwhen tU == null
call GroupRemoveUnit(g, tU)
if UnitAlive(tU) and IsUnitEnemy(tU, GetOwningPlayer(u[i])) then
call UnitDamageTarget(u[i], tU, PULSE_DAMAGE, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
endif
endloop
call GroupClear(g)
set pulse[i] = PULSE_TIMEOUT
endif
call GroupEnumUnitsInRange(g, x, y, TRACK_AOE_CHECK, null)
set tB = false
loop
set tU = FirstOfGroup(g)
exitwhen tU == null or tB == true
call GroupRemoveUnit(g, tU)
if tU == u[i] then
set tB = true
set d[i] = 0.
call TRFire(u[i], x, y, angle)
elseif UnitAlive(tU) and IsUnitEnemy(tU, GetOwningPlayer(u[i])) then
call UnitDamageTarget(u[i], tU, TRACK_DAMAGE, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
endif
endloop
call GroupClear(g)
if d[i] <= 0. then
call DestroyEffect(e[i])
set index = index - 1
set u[i] = u[index]
set p[i] = p[index]
set d[i] = d[index]
set e[i] = e[index]
set px[i] = px[index]
set py[i] = py[index]
set pulse[i] = pulse[index]
set b[i] = b[index]
set i = i - 1
if index == 0 then
call PauseTimer(t)
endif
endif
set i = i + 1
endloop
set g = null
set tU = null
set tE = null
endfunction
private function ThunderRocket takes nothing returns boolean
local real angle
local real angle2
local real angle3
local real x
local real y
if GetSpellAbilityId() == THUNDER_ROCKET then
set u[index] = GetTriggerUnit()
set p[index] = GetTriggerPlayer()
set d[index] = DURATION
set b[index] = false
set pulse[index] = PULSE_TIMEOUT
set rAngle[index] = 0.
set angle = GetUnitFacing(u[index])
set x = GetUnitX(u[index])
set y = GetUnitY(u[index])
set angle3 = angle * bj_DEGTORAD
set angle2 = OFFSET * Cos(angle3)
set x = x + angle2
set angle2 = OFFSET * Sin(angle3)
set y = y + angle2
set e[index] = AddSpecialEffect(EFFECT, x,y)
call BlzSetSpecialEffectOrientation(e[index], angle3,0,0)
set px[index] = x
set py[index] = y
call BlzSetSpecialEffectHeight( e[index], 50.00 )
set index = index + 1
if index == 1 then
call TimerStart(t, TIMEOUT, true, function TRLoop)
endif
endif
return false
endfunction
function ThunderRocketDetect takes nothing returns boolean
local player p1 = GetTriggerPlayer()
local integer i = 0
local real x
local real y
loop
exitwhen i >= index
if GetOwningPlayer(u[i]) == p1 then
set x = BlzGetTriggerPlayerMouseX()
set y = BlzGetTriggerPlayerMouseY()
if x == 0. and y == 0. then
// retain angle?
set b[i] = true
else
set px[i] = x
set py[i] = y
set b[i] = false
endif
endif
set i = i + 1
endloop
set p1 = null
return false
endfunction
private function init takes nothing returns nothing
local trigger t10 = CreateTrigger()
local trigger t11 = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t10, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t10, Condition(function ThunderRocket))
call TriggerRegisterPlayerMouseEventBJ( t11, Player(0), bj_MOUSEEVENTTYPE_MOVE )
call TriggerAddCondition(t11, Condition(function ThunderRocketDetect))
endfunction
endlibrary
JASS:
library TimedEffect
globals
private integer effectIndex = 0
private real array effectDuration
private effect array effects
private timer effectLoop = CreateTimer()
private constant real EFFECT_TIMEOUT = .05
endglobals
function EffectLoop takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= effectIndex
set effectDuration[i] = effectDuration[i] - EFFECT_TIMEOUT
if effectDuration[i] <= 0. then
call DestroyEffect(effects[i])
set effectIndex = effectIndex - 1
set effects[i] = effects[effectIndex]
set effectDuration[i] = effectDuration[effectIndex]
set i = i - 1
if effectIndex == 0 then
call PauseTimer(effectLoop)
endif
endif
set i = i + 1
endloop
endfunction
function EffectApplyTimedLife takes effect e, real timeout returns nothing
set effects[effectIndex] = e
set effectDuration[effectIndex] = timeout
set effectIndex = effectIndex + 1
if effectIndex == 1 then
call TimerStart(effectLoop, EFFECT_TIMEOUT, true, function EffectLoop)
endif
endfunction
endlibrary
JASS:
library TreeSearch initializer init
globals
private rect TREE_REGION
private real maxX
private real maxY
private real minX
private real minY
private real defaultDestRadius = 128.
private real maxDestRadius = defaultDestRadius * 2.
private string treeOrDebris = "attack"
private unit debrisKiller
private real tX
private real tY
private real tRadius
endglobals
private function KillTree takes nothing returns nothing
local real x
local real y
local destructable d = GetEnumDestructable()
if GetWidgetLife(d) > .405 and IssueTargetOrder(debrisKiller, treeOrDebris, d) then
set x = GetWidgetX(d) - tX
set y = GetWidgetY(d) - tY
if x*x + y*y <= tRadius then
call KillDestructable(d)
endif
endif
set d = null
endfunction
function TreeSearch takes real x, real y, real radius returns nothing
call SetUnitX(debrisKiller, x)
call SetUnitY(debrisKiller, y)
call PauseUnit(debrisKiller, false)
set tX = x
set tY = y
if radius == 0. then
call SetRect(TREE_REGION, 0., 0., maxDestRadius, maxDestRadius)
set radius = defaultDestRadius
else
call SetRect(TREE_REGION, 0., 0., radius*2, radius*2)
endif
set tRadius = radius*radius
call MoveRectTo(TREE_REGION, x, y)
call EnumDestructablesInRect(TREE_REGION, null, function KillTree)
call PauseUnit(debrisKiller, true)
endfunction
private function init takes nothing returns nothing
set TREE_REGION = GetWorldBounds()
set maxX = GetRectMaxX(TREE_REGION)
set maxY = GetRectMaxY(TREE_REGION)
set minX = GetRectMinX(TREE_REGION)
set minY = GetRectMinY(TREE_REGION)
set debrisKiller = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'ugho', 0,0, 270.)
call UnitAddAbility(debrisKiller, 'Aloc')
call ShowUnit(debrisKiller, false)
call PauseUnit(debrisKiller, true)
call SetRect(TREE_REGION, 0., 0., maxDestRadius, maxDestRadius)
endfunction
endlibrary
JASS:
library TerrainPathability initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//*
//******************************************************************************
//*
//* > function IsTerrainDeepWater takes real x, real y returns boolean
//* > function IsTerrainShallowWater takes real x, real y returns boolean
//* > function IsTerrainLand takes real x, real y returns boolean
//* > function IsTerrainPlatform takes real x, real y returns boolean
//* > function IsTerrainWalkable takes real x, real y returns boolean
//*
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//*
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//*
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//*
//* Variables that can be used from the library:
//* [real] TerrainPathability_X
//* [real] TerrainPathability_Y
//*
globals
private constant real MAX_RANGE = 10.
private constant integer DUMMY_ITEM_ID = 'wolg'
endglobals
globals
private item Item = null
private rect Find = null
private item array Hid
private integer HidMax = 0
public real X = 0.
public real Y = 0.
endglobals
function IsTerrainDeepWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
function IsTerrainShallowWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function IsTerrainLand takes real x, real y returns boolean
return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
endfunction
function IsTerrainPlatform takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function FreePathing takes real x, real y returns boolean
return not IsTerrainPathable(x,y, PATHING_TYPE_FLYABILITY)
endfunction
private function HideItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set Hid[HidMax] = GetEnumItem()
call SetItemVisible(Hid[HidMax], false)
set HidMax = HidMax + 1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
//Hide any items in the area to avoid conflicts with our item
call MoveRectTo(Find, x, y)
call EnumItemsInRect(Find ,null, function HideItem)
//Try to move the test item and get its coords
call SetItemPosition(Item, x, y) //Unhides the item
set X = GetItemX(Item)
set Y = GetItemY(Item)
static if LIBRARY_IsTerrainWalkable then
//This is for compatibility with the IsTerrainWalkable library
set IsTerrainWalkable_X = X
set IsTerrainWalkable_Y = Y
endif
call SetItemVisible(Item, false)//Hide it again
//Unhide any items hidden at the start
loop
exitwhen HidMax <= 0
set HidMax = HidMax - 1
call SetItemVisible(Hid[HidMax], true)
set Hid[HidMax] = null
endloop
//Return walkability
return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
private function Init takes nothing returns nothing
set Find = Rect(0., 0., 128., 128.)
set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
call SetItemVisible(Item, false)
endfunction
endlibrary