- Joined
- Aug 27, 2012
- Messages
- 362
Hey Hive, I have a problem with text tags in a spell I'm working on. It's basically Ogre Magi's Multicast from DotA, but more complex. Anyhow, I've gotten everything to work, except for one thing: it appears the text tags are not being removed properly. I've deduced this because in the beginning the text tags display properly; however after some time the text tags only appear for a brief moment, and then they don't even show up; only occasionally(i.e when it's the only text tag in the game). Based on this I can only conclude that I have reached the text tag limit. But this perplexes me because I'm sure I've properly removed my text tags: I set their lifespan and disabled their permanence; I've even nulled the local variable I've set it too. This is really puzzling, I've never had a problem with text tags leaking before.
Anyways here's the trigger(I only deal with text tags in the "Actions" function, I just posted the entire thing in case something else in the code is conflicting and causing errors):
Hopefully someone can help me with this, because I'm really stumped. Thanks!
Anyways here's the trigger(I only deal with text tags in the "Actions" function, I just posted the entire thing in case something else in the code is conflicting and causing errors):
JASS:
scope AetherealMastery initializer OnInit
//Set up global variables.
globals
private constant integer SPELL_ID = 'A0EY'
private constant integer SPELL_ID1 = 'A0EW'
private constant integer SPELL_ID2 = 'A0ES'
private constant integer SPELL_ID3 = 'A0EX'
private integer CASTS
private group GROUP = CreateGroup()
private unit CASTER
private unit array RANDOMU
private integer RANDOMI = 0
endglobals
//Set up the struct that will make the spell MUI.
private struct MC
unit u
integer cast
integer spell_id
integer lvl
real x
real y
unit target
method destroy takes nothing returns nothing
set this.u = null
set this.target = null
call this.deallocate()
endmethod
endstruct
//Filter all nearby enemies, assign them to unit array to be able to pick a random unit later.
private function FilterGroup takes nothing returns boolean
if UnitAlive(GetFilterUnit()) and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(CASTER)) and IsUnitVisible(GetFilterUnit(), GetOwningPlayer(CASTER)) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) then
set RANDOMI = RANDOMI + 1
set RANDOMU[RANDOMI] = GetFilterUnit()
endif
return false
endfunction
//Filter all nearby allies, assign them to unit array to be able to pick a random unit later.
private function FilterGroup2 takes nothing returns boolean
if UnitAlive(GetFilterUnit()) and IsUnitAlly(GetFilterUnit(), GetOwningPlayer(CASTER)) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) then
set RANDOMI = RANDOMI + 1
set RANDOMU[RANDOMI] = GetFilterUnit()
endif
return false
endfunction
//This function is confusing but I think u can ignore it; I only work with text tags in the next function.
private function Handler takes nothing returns nothing
local timer t = GetExpiredTimer()
local MC data = GetTimerData(t)
local unit d
local unit targ
//If all instances are finished, clean up the instance, else create a dummy to cast another instance of the spell:
if data.cast <= 0 then
call data.destroy()
call ReleaseTimer(t)
else
set data.cast = data.cast - 1
//If spell is Aether Flare, create dummy at target location so it will always be in range, regardless if caster moves. (No projectile, so don't need to create it at caster's location)
if data.spell_id != SPELL_ID3 then
set d = CreateUnit(GetOwningPlayer(data.u), 'h007', GetUnitX(data.u), GetUnitY(data.u), 0.)
else
set d = CreateUnit(GetOwningPlayer(data.u), 'h007', data.x, data.y, 0.)
endif
call UnitApplyTimedLife(d, 'BTLF', 1.)
//If spell is Aether Bolt, give dummy a version of the spell with a global cast range, so the dummy can still cast the spell even if the caster moves.
if data.spell_id != SPELL_ID1 then
call UnitAddAbility(d, data.spell_id)
call SetUnitAbilityLevel(d, data.spell_id, data.lvl)
else
call UnitAddAbility(d, 'A0F9')
call SetUnitAbilityLevel(d, 'A0F9', data.lvl)
endif
call SetUnitState(data.u, UNIT_STATE_MANA, GetUnitState(data.u, UNIT_STATE_MANA) - (GetUnitState(data.u, UNIT_STATE_MANA) * .1))
//Determines what spell we should be casting.
if data.spell_id == SPELL_ID1 then
//If target is dead we try to find another one in range.
if not UnitAlive(data.target) or data.target == null then
set CASTER = data.u
set RANDOMI = 0
//Adds all nearby enemies to unit group
call GroupEnumUnitsInRange(GROUP, GetUnitX(data.u), GetUnitY(data.u), 800., Filter(function FilterGroup))
if RANDOMI > 0 then
//Sets target to random unit from array we set before.
set targ = RANDOMU[GetRandomInt(1, RANDOMI)]
call IssueTargetOrder(d, "thunderbolt", targ)
set RANDOMI = 0
endif
else
call IssueTargetOrder(d, "thunderbolt", data.target)
endif
elseif data.spell_id == SPELL_ID2 then
//Decides if target already has max attack speed; if it does, find another ally to cast it on.
if AETHER_BUFF_LVL[GetUnitUserData(data.target)] >= 20 or not UnitAlive(data.target) or data.target == null then
set CASTER = data.u
set RANDOMI = 0
//Adds all nearby allies to unit group.
call GroupEnumUnitsInRange(GROUP, GetUnitX(data.u), GetUnitY(data.u), 900., Filter(function FilterGroup2))
if RANDOMI > 0 then
//Sets target to random unit from array we set before.
set targ = RANDOMU[GetRandomInt(1, RANDOMI)]
call IssueTargetOrder(d, "cripple", targ)
set RANDOMI = 0
endif
else
call IssueTargetOrder(d, "cripple", data.target)
endif
elseif data.spell_id == SPELL_ID3 then
call IssuePointOrder(d, "impale", data.x, data.y)
endif
call DestroyEffect(AddSpecialEffect("war3mapImported\\Stomp.mdx", GetUnitX(data.u), GetUnitY(data.u)))
//Restarts timer so we can cast another instance, if any are left. Else it will auto clean up the trigger.
call SetTimerData(t, data)
call TimerStart(t, .3, false, function Handler)
endif
set targ = null
set d = null
set t = null
endfunction
//This is where I create the text tag and set up the timer. I thought I cleaned up the text tag pretty thoroughly, but apparently not...
private function Actions takes nothing returns nothing
local timer t = NewTimer()
local MC data = MC.create()
local texttag tt = CreateTextTag()
local string text = "|cFF1C88E2M|r|cFF1A91E4u|r|cFF199AE6l|r|cFF17A3E7t|r|cFF16ACE9i|r|cFF14B5EBc|r|cFF12BEECa|r|cFF11C6EEs|r|cFF0FCFF0t|r|cFF0ED8F2 |r|cFF0CE1F4x|r" + "|cFF0BEAF5" + I2S(CASTS + 1) + "|r" + "|cFF09F3F7!|r"
set data.u = GetTriggerUnit()
set data.cast = CASTS
set data.spell_id = GetSpellAbilityId()
set data.lvl = GetUnitAbilityLevel(data.u, data.spell_id)
call SetTextTagText(tt, text, .024)
call SetTextTagPos(tt, GetUnitX(data.u), GetUnitY(data.u), 0.0)
call SetTextTagVelocity(tt, 0.0, 0.04)
call SetTextTagPermanent(tt, false)
call SetTextTagFadepoint(tt, 2.0)
call SetTextTagLifespan(tt, 2.0)
call SetTextTagVisibility(tt, true)
if data.spell_id == SPELL_ID1 or data.spell_id == SPELL_ID2 then
set data.target = GetSpellTargetUnit()
else
set data.x = GetSpellTargetX()
set data.y = GetSpellTargetY()
endif
call SetTimerData(t, data)
call TimerStart(t, .3, false, function Handler)
set tt = null
set t = null
set text = null
endfunction
private function Conditions takes nothing returns boolean
local integer chance
local integer lvl = GetUnitAbilityLevel(GetTriggerUnit(), SPELL_ID)
if (GetSpellAbilityId() == SPELL_ID1 or GetSpellAbilityId() == SPELL_ID2 or GetSpellAbilityId() == SPELL_ID3) and lvl >= 1 then
//Here we determine how many additional spell casts will happen, if any.
set chance = GetRandomInt(1, 100)
if chance <= lvl then
set CASTS = 4
call Actions()
return false
elseif chance <= lvl * 2 then
set CASTS = 3
call Actions()
return false
elseif chance <= lvl * 3 then
set CASTS = 2
call Actions()
return false
elseif chance <= lvl * 4 then
set CASTS = 1
call Actions()
return false
endif
endif
return false
endfunction
private function OnInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function Conditions))
endfunction
endscope
Hopefully someone can help me with this, because I'm really stumped. Thanks!
Last edited: