• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] spell not working (pre1.24)

Status
Not open for further replies.
Level 13
Joined
May 11, 2008
Messages
1,198
so there's this spell that was made before 1.24
i thought i fixed it, and maybe i did.
but maybe i broke it? or maybe my map broke it.
well, here's the spell, does it seem ok?
i'm guessing it's just not compatible with GT
if that's the case i guess i got to find the original code
or my previous, supposedly correct fix of it
JASS:
//credit for this spell goes to Justify at hiveworkshop.com
//he made it originally, and i modified slightly it to make it to work for 1.24
//i also modified the spell to fit my map
//
//
//

library GlobalLib
    
    function SetUnitXY takes unit u, real x, real y returns nothing
        local real minx = GetRectMinX(bj_mapInitialPlayableArea)
        local real maxx = GetRectMaxX(bj_mapInitialPlayableArea)
        local real miny = GetRectMinY(bj_mapInitialPlayableArea)
        local real maxy = GetRectMaxY(bj_mapInitialPlayableArea)
        if (x < minx) then
            call SetUnitX(u, minx)
        elseif (x > maxx) then
            call SetUnitX(u, maxx)
        else
            call SetUnitX(u, x)
        endif
        if (y < miny) then
            call SetUnitY (u, miny)
        elseif (y > maxy) then
            call SetUnitY (u, maxy)
        else
            call SetUnitY (u, y)
        endif
    endfunction
    
endlibrary


scope PoisonousMushroom initializer I

private struct MushroomStruct
    unit mushroom
    unit caster
    integer skilllevel
    real duration
    boolean growing
endstruct

private struct MushroomMissleStruct
    unit missle
    real dist
    real speed
    real angle
    real tx
    real ty
endstruct

globals
    //You can find these IDs in the object editor by pressing CTRL+D
    private constant integer MushroomSpellID = 'A06C'  //Poisonous Mushroom (Spell)
    private constant integer DetonateSpellID = 'A06B' //Detonate (Spell)
    private constant integer MushroomUnitID = 'h00V' //Mushroom (Unit)
    private constant integer MushroomMissleID = 'h00W' //MushroomMissle (Unit), only important if MisslesBetweenExplosion = true
    
    //Settings for the spell
    private constant real GrowthTime = 30 //Growth time
    private constant real AreaOfEffectBase = 200 //Base area of effect
    private constant real AreaOfEffectAdd = 10 //Area of effect bonus per second
    private constant real AreaBaseLevelMultiplier = 0 //Base area + base area * multiplier*(skill level -1) = new base area, for example level 2: 400+1*400*(2-1) = 800, while it is still 400 with 0 as multiplier
    private constant real AreaAddLevelMultiplier = 0.5 //Same math then AreaBaseLevelMultiplier
    private constant real DamageBase = 0 //Base damage
    private constant real DamageAdd = 10 //Bonus damage per second
    private constant real DamageBaseLevelMultiplier = 0 //AreaBaseLevelMultiplier...
    private constant real DamageAddLevelMultiplier = 0.5 //AreaBaseLevelMultiplier...
    private constant real MinDistance = 300 //Minimum distance between two mushrooms
    private constant boolean ChainExplosion = true //Should an exploding mushrooms trigger other ones?
    private constant real ExplosionDelay = 0.5 //Delay between exploding mushrooms, if 0 the MisslesBetweenExplosion won't work!
    private constant real MaxChainDistance = 1000 //Maximum distance between two mushrooms for exploding per chainreaction
    private constant real MaxDetonateDistance = 1000 //Maximum distance for detonate
    //private constant integer MaxMushrooms = 10 //The maximum number of mushrooms at the same time
    private constant boolean NewExplodesOld = true //Should the 1. mushroom explode if to many are placed?
    private constant boolean ExplodeAfterTime = true //Should the mushroom explode automaticly after the GrowthTime?
    private constant boolean MisslesBetweenExplosion = true //Activates a missle, flying between caster/explosions
    
    //Sfx
    private constant string CasterArtPlace = "Abilities\\Spells\\NightElf\\ManaBurn\\ManaBurnTarget.mdl" //Caster animation while placing the mushroom
    private constant string CasterArtPlaceAttach = "origin" //Attachment point for CasterArtPlace
    private constant string ExplodeArtMushroom = "Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl" //Effect of the mushroom explosion 
    
    //Globals for the spell
    private MushroomStruct array MushroomData
    private MushroomMissleStruct array MushroomMissleData
    private timer MushroomTimer = CreateTimer()
    private integer MushroomCount = 0
    private integer MushroomMissleCount = 0
    private player TempOwner = null
endglobals
//i wrote this maxmushrooms function because i wanted to adjust the max per level
//interestingly enough he adjusts other stats per level but not this one.
//anyway, his way of adjusting the stats is different and i'm afraid i don't understand exactly
//how he does it so i just edited this one this way...
    private function MaxMushrooms takes nothing returns integer
    return 1 + (2*GetUnitAbilityLevel(GetTriggerUnit(), MushroomSpellID))//3,5,7,9
    endfunction
private function ExplodeEnemyDetection takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), TempOwner) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and GetWidgetLife(GetFilterUnit())>0.405
endfunction

private function GetNearestOwnedMushroom takes real x, real y, real distance, unit caster returns integer
    local MushroomStruct data
    local integer i = 0
    local real dx = 0
    local real dy = 0
    local real dist = 0
    local real mindist = distance
    local integer mindistid = MaxMushrooms()+1
    
    loop
        exitwhen i >= MushroomCount
        set data = MushroomData[i]
        if data.caster == caster then
            set dx = GetUnitX(data.mushroom)-x
            set dy = GetUnitY(data.mushroom)-y
            set dist = SquareRoot(dx*dx+dy*dy)
            if dist < mindist then
                set mindist = dist
                set mindistid = i
            endif
        endif
        set i = i+1
    endloop
    
    return mindistid
endfunction            

private function ExplodeMushroom takes integer MushroomCountID, real Delay, real sx, real sy returns nothing
    local integer i = MushroomCountID
    local integer j = 0
    local MushroomStruct data = MushroomData[i]
    local MushroomMissleStruct data2 = 0
    local real mx = GetUnitX(data.mushroom)
    local real my = GetUnitY(data.mushroom)
    local real x = 0
    local real y = 0
    local real aoe = AreaOfEffectBase*(1+(data.skilllevel-1)*AreaBaseLevelMultiplier)+AreaOfEffectAdd*data.duration*(1+(data.skilllevel-1)*AreaAddLevelMultiplier)
    local real damage = DamageBase*(1+(data.skilllevel-1)*DamageBaseLevelMultiplier)+DamageAdd*data.duration*(1+(data.skilllevel-1)*DamageAddLevelMultiplier)
    local real artperring = 0 
    local real rings = aoe/100
    local real dist = 0
    local group g = CreateGroup()
    local unit u = null
    local unit c = data.caster
    local player p = GetOwningPlayer(c)
    
    if MisslesBetweenExplosion and Delay > 0 then
        set data2 = MushroomMissleStruct.create()
        set data2.missle = CreateUnit(p, MushroomMissleID, sx, sy, GetRandomReal(0, 360))
        set x = mx-sx
        set y = my-sy
        set data2.dist = SquareRoot(x*x+y*y)
        set data2.speed = data2.dist/(Delay/0.025)
        set data2.angle = Atan2(sy-my, sx-mx)
        set data2.tx = mx
        set data2.ty = my
        set MushroomMissleData[MushroomMissleCount] = data2
        set MushroomMissleCount = MushroomMissleCount+1
    endif
    
    call TriggerSleepAction(Delay)
    
    loop
        exitwhen i >= MaxMushrooms()
        set MushroomData[i] = MushroomData[i+1]
        set i = i+1
    endloop
    
    set TempOwner = GetOwningPlayer(data.mushroom)
    call GroupEnumUnitsInRange(g, mx, my, aoe, Condition(function ExplodeEnemyDetection))
    call RemoveUnit(data.mushroom)
    call data.destroy()
    set MushroomCount = MushroomCount-1
    if MushroomCount == 0 then
        call PauseTimer(MushroomTimer)
    endif
    
    set i = 1
    loop
        exitwhen i >= rings
        set dist = i*100
        set artperring = 4+i
        loop
            exitwhen j >= artperring
            set x = mx+dist*Cos((360/artperring)*j*bj_DEGTORAD)
            set y = my+dist*Sin((360/artperring)*j*bj_DEGTORAD)
            call DestroyEffect(AddSpecialEffect(ExplodeArtMushroom, x, y))
            set j = j+1
        endloop
        set j = 0
        set i = i+1
    endloop
    
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call UnitDamageTarget(data.mushroom, u, damage, false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_POISON, WEAPON_TYPE_WHOKNOWS)
        call GroupRemoveUnit(g, u)
    endloop
    
    call DestroyGroup(g)
    set g = null
    
    if ChainExplosion then
        set i = GetNearestOwnedMushroom(mx, my, MaxChainDistance, c)
        if i != MaxMushrooms()+1 then
            call ExplodeMushroom(i, ExplosionDelay, mx, my)
        endif
    endif
    
    set c = null
endfunction

private function Detonate takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real ux = GetUnitX(u)
    local real uy = GetUnitY(u)
    local integer i = GetNearestOwnedMushroom(ux, uy, MaxDetonateDistance, u)
    if i != MaxMushrooms()+1 then
        call ExplodeMushroom(i, ExplosionDelay,ux, uy)
    endif
    set u = null
endfunction

private function GrowMushroom takes nothing returns nothing
    local MushroomStruct data = 0
    local MushroomMissleStruct data2 = 0
    local integer i = 0
    local real temp
    
    loop
        exitwhen i >= MushroomMissleCount
        set data2 = MushroomMissleData[i]
        set data2.dist = data2.dist-data2.speed
        if data2.dist > 0 then
            call SetUnitXY(data2.missle, data2.tx+data2.dist*Cos(data2.angle), data2.ty+data2.dist*Sin(data2.angle))
        else
            call KillUnit(data2.missle)
            set MushroomMissleData[i] = MushroomMissleData[MushroomMissleCount]
            set MushroomMissleCount = MushroomMissleCount-1
            call data2.destroy()
        endif            
        set i = i+1
    endloop
    
    set i = 0
    
    loop
        exitwhen i >= MushroomCount
        set data = MushroomData[i]
        if data.growing then
            set data.duration = data.duration+0.025
            set temp = data.duration/GrowthTime
            call SetUnitScale(data.mushroom, temp, temp, temp)
            if temp >= 2.5 then
                set data.growing = false
                if ExplodeAfterTime then
                    call ExplodeMushroom(i, 0, 0, 0)
                endif
            endif
        endif
        set i = i+1
    endloop
endfunction

private function PoisonousMushroom takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local player owner = GetOwningPlayer(caster)
    local location tl = GetSpellTargetLoc()
    local real lx = GetLocationX(tl)
    local real ly = GetLocationY(tl)
    local real dx = 0
    local real dy = 0
    local real dist = 0
    local integer i = 0
    local MushroomStruct data
    
    set i = GetNearestOwnedMushroom(lx, ly, MinDistance, caster)
    if i != MaxMushrooms()+1 then        
        call IssueImmediateOrder(caster, "stop" )
        call DisplayTextToPlayer(owner, 0, 0, "|cffffcc00There is already an other Poisonous Mushroom near the target point.|r")
        set caster = null
        return
    endif
    
    if MushroomCount >= MaxMushrooms()-1 then
        if NewExplodesOld then
            call ExplodeMushroom(0, ExplosionDelay, GetUnitX(caster), GetUnitY(caster))
        else
            call IssueImmediateOrder(caster, "stop" )
            call DisplayTextToPlayer(owner, 0, 0, "|cffffcc00There are already "+I2S(MaxMushrooms())+" Poisonous Mushrooms at the map.|r")
            set caster = null
            return
        endif
    endif
    
    call DestroyEffect(AddSpecialEffectTarget(CasterArtPlace, caster, CasterArtPlaceAttach))
    set data = MushroomStruct.create()
    set data.mushroom = CreateUnit(owner, MushroomUnitID, lx, ly, GetRandomReal(0, 360))
    set data.duration = 0
    set data.growing = true
    set data.skilllevel = GetUnitAbilityLevel(caster, MushroomSpellID)
    set data.caster = caster
    call SetUnitScale(data.mushroom, 0, 0, 0)
    
    if MushroomCount == 0 then
        call TimerStart(MushroomTimer, 0.025, true, function GrowMushroom)
    endif
    
    set MushroomData[MushroomCount] = data
    set MushroomCount = MushroomCount+1
    
    set caster = null
    call RemoveLocation(tl)
    set tl = null
endfunction

//===========================================================================
private function I takes nothing returns nothing
    call GT_AddStartsEffectAction(function PoisonousMushroom,MushroomSpellID)
    call GT_AddStartsEffectAction(function Detonate,DetonateSpellID)
    call XE_PreloadAbility( MushroomSpellID)
    call XE_PreloadAbility( DetonateSpellID)
endfunction

endscope
P.S. planting the mushroom works ok, but when it's time for it to explode, although the green webby thing goes and hits the mushroom bomb, nothing happens.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
I can't see anything strikingly wrong with it, but it's quite long. Typically the only thing that "breaks" pre-patch code is utility of the return bug. There are probably other examples that occur on rare occasions, but this is the main one.

Curious though, since I can't test the spell, what's wrong with it?
 
GT_AddStartsEffectAction

Is this some library?

http://www.thehelper.net/forums/showthread.php?t=123288

GTrigger system.

i'm guessing it's just not compatible with GT

Try it:
JASS:
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function myFunc))

If it does work, then you've fixed your problem. Else, it is something else. Try adding debug messages and see what pops-up (to see what is executed)
 
Level 13
Joined
May 11, 2008
Messages
1,198
thanks for the suggestion. anyway, actually the spell wasn't meant to be a condition to begin with...i tried changing the return in that first called function to return false and added return false at the end of the function, and also added return false to the end of the detonate function...which i sometimes accidently spell as dotanate...too much dota...lol.

anyways...adding back conditions like how i remember, i fixed the spell...

the main question though that is bothering me now is...can this spell work with GT?
if so, how? since it's an older spell, maybe the code can be revamped for it to work for GT. i'm not sure i understand the code so i'm afraid to try to rewrite the code, but i guess the attempt couldn't hurt. should i try it?


Code:
//credit for this spell goes to Justify at hiveworkshop.com
//he made it originally, and i modified slightly it to make it to work for 1.24
//i also modified the spell to fit my map
//
//
//

library GlobalLib
    
    function SetUnitXY takes unit u, real x, real y returns nothing
        local real minx = GetRectMinX(bj_mapInitialPlayableArea)
        local real maxx = GetRectMaxX(bj_mapInitialPlayableArea)
        local real miny = GetRectMinY(bj_mapInitialPlayableArea)
        local real maxy = GetRectMaxY(bj_mapInitialPlayableArea)
        if (x < minx) then
            call SetUnitX(u, minx)
        elseif (x > maxx) then
            call SetUnitX(u, maxx)
        else
            call SetUnitX(u, x)
        endif
        if (y < miny) then
            call SetUnitY (u, miny)
        elseif (y > maxy) then
            call SetUnitY (u, maxy)
        else
            call SetUnitY (u, y)
        endif
    endfunction
    
endlibrary


scope PoisonousMushroomz initializer I

private struct MushroomStruct
    unit mushroom
    unit caster
    integer skilllevel
    real duration
    boolean growing
endstruct

private struct MushroomMissleStruct
    unit missle
    real dist
    real speed
    real angle
    real tx
    real ty
endstruct

globals
    //You can find these IDs in the object editor by pressing CTRL+D
    private constant integer MushroomSpellID = 'A06C'  //Poisonous Mushroom (Spell)
    private constant integer DetonateSpellID = 'A06B' //Detonate (Spell)
    private constant integer MushroomUnitID = 'h00V' //Mushroom (Unit)
    private constant integer MushroomMissleID = 'h00W' //MushroomMissle (Unit), only important if MisslesBetweenExplosion = true
    
    //Settings for the spell
    private constant real GrowthTime = 30 //Growth time
    private constant real AreaOfEffectBase = 200 //Base area of effect
    private constant real AreaOfEffectAdd = 10 //Area of effect bonus per second
    private constant real AreaBaseLevelMultiplier = 0 //Base area + base area * multiplier*(skill level -1) = new base area, for example level 2: 400+1*400*(2-1) = 800, while it is still 400 with 0 as multiplier
    private constant real AreaAddLevelMultiplier = 0.5 //Same math then AreaBaseLevelMultiplier
    private constant real DamageBase = 0 //Base damage
    private constant real DamageAdd = 10 //Bonus damage per second
    private constant real DamageBaseLevelMultiplier = 0 //AreaBaseLevelMultiplier...
    private constant real DamageAddLevelMultiplier = 0.5 //AreaBaseLevelMultiplier...
    private constant real MinDistance = 300 //Minimum distance between two mushrooms
    private constant boolean ChainExplosion = true //Should an exploding mushrooms trigger other ones?
    private constant real ExplosionDelay = 0.5 //Delay between exploding mushrooms, if 0 the MisslesBetweenExplosion won't work!
    private constant real MaxChainDistance = 1000 //Maximum distance between two mushrooms for exploding per chainreaction
    private constant real MaxDetonateDistance = 1000 //Maximum distance for detonate
    //private constant integer MaxMushrooms = 10 //The maximum number of mushrooms at the same time
    private constant boolean NewExplodesOld = true //Should the 1. mushroom explode if to many are placed?
    private constant boolean ExplodeAfterTime = true //Should the mushroom explode automaticly after the GrowthTime?
    private constant boolean MisslesBetweenExplosion = true //Activates a missle, flying between caster/explosions
    
    //Sfx
    private constant string CasterArtPlace = "Abilities\\Spells\\NightElf\\ManaBurn\\ManaBurnTarget.mdl" //Caster animation while placing the mushroom
    private constant string CasterArtPlaceAttach = "origin" //Attachment point for CasterArtPlace
    private constant string ExplodeArtMushroom = "Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl" //Effect of the mushroom explosion 
    
    //Globals for the spell
    private MushroomStruct array MushroomData
    private MushroomMissleStruct array MushroomMissleData
    private timer MushroomTimer = CreateTimer()
    private integer MushroomCount = 0
    private integer MushroomMissleCount = 0
    private player TempOwner = null
endglobals
//i wrote this maxmushrooms function because i wanted to adjust the max per level
//interestingly enough he adjusts other stats per level but not this one.
//anyway, his way of adjusting the stats is different and i'm afraid i don't understand exactly
//how he does it so i just edited this one this way...
    private function MaxMushrooms takes nothing returns integer
    return 1 + (2*GetUnitAbilityLevel(GetTriggerUnit(), MushroomSpellID))//3,5,7,9
    endfunction
private function ExplodeEnemyDetection takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), TempOwner) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and GetWidgetLife(GetFilterUnit())>0.405
endfunction

private function GetNearestOwnedMushroom takes real x, real y, real distance, unit caster returns integer
    local MushroomStruct data
    local integer i = 0
    local real dx = 0
    local real dy = 0
    local real dist = 0
    local real mindist = distance
    local integer mindistid = MaxMushrooms()+1
    
    loop
        exitwhen i >= MushroomCount
        set data = MushroomData[i]
        if data.caster == caster then
            set dx = GetUnitX(data.mushroom)-x
            set dy = GetUnitY(data.mushroom)-y
            set dist = SquareRoot(dx*dx+dy*dy)
            if dist < mindist then
                set mindist = dist
                set mindistid = i
            endif
        endif
        set i = i+1
    endloop
    
    return mindistid
endfunction            

private function ExplodeMushroom takes integer MushroomCountID, real Delay, real sx, real sy returns nothing
    local integer i = MushroomCountID
    local integer j = 0
    local MushroomStruct data = MushroomData[i]
    local MushroomMissleStruct data2 = 0
    local real mx = GetUnitX(data.mushroom)
    local real my = GetUnitY(data.mushroom)
    local real x = 0
    local real y = 0
    local real aoe = AreaOfEffectBase*(1+(data.skilllevel-1)*AreaBaseLevelMultiplier)+AreaOfEffectAdd*data.duration*(1+(data.skilllevel-1)*AreaAddLevelMultiplier)
    local real damage = DamageBase*(1+(data.skilllevel-1)*DamageBaseLevelMultiplier)+DamageAdd*data.duration*(1+(data.skilllevel-1)*DamageAddLevelMultiplier)
    local real artperring = 0 
    local real rings = aoe/100
    local real dist = 0
    local group g = CreateGroup()
    local unit u = null
    local unit c = data.caster
    local player p = GetOwningPlayer(c)
    
    if MisslesBetweenExplosion and Delay > 0 then
        set data2 = MushroomMissleStruct.create()
        set data2.missle = CreateUnit(p, MushroomMissleID, sx, sy, GetRandomReal(0, 360))
        set x = mx-sx
        set y = my-sy
        set data2.dist = SquareRoot(x*x+y*y)
        set data2.speed = data2.dist/(Delay/0.025)
        set data2.angle = Atan2(sy-my, sx-mx)
        set data2.tx = mx
        set data2.ty = my
        set MushroomMissleData[MushroomMissleCount] = data2
        set MushroomMissleCount = MushroomMissleCount+1
    endif
    
    call TriggerSleepAction(Delay)
    
    loop
        exitwhen i >= MaxMushrooms()
        set MushroomData[i] = MushroomData[i+1]
        set i = i+1
    endloop
    
    set TempOwner = GetOwningPlayer(data.mushroom)
    call GroupEnumUnitsInRange(g, mx, my, aoe, Condition(function ExplodeEnemyDetection))
    call RemoveUnit(data.mushroom)
    call data.destroy()
    set MushroomCount = MushroomCount-1
    if MushroomCount == 0 then
        call PauseTimer(MushroomTimer)
    endif
    
    set i = 1
    loop
        exitwhen i >= rings
        set dist = i*100
        set artperring = 4+i
        loop
            exitwhen j >= artperring
            set x = mx+dist*Cos((360/artperring)*j*bj_DEGTORAD)
            set y = my+dist*Sin((360/artperring)*j*bj_DEGTORAD)
            call DestroyEffect(AddSpecialEffect(ExplodeArtMushroom, x, y))
            set j = j+1
        endloop
        set j = 0
        set i = i+1
    endloop
    
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call UnitDamageTarget(data.mushroom, u, damage, false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_POISON, WEAPON_TYPE_WHOKNOWS)
        call GroupRemoveUnit(g, u)
    endloop
    
    call DestroyGroup(g)
    set g = null
    
    if ChainExplosion then
        set i = GetNearestOwnedMushroom(mx, my, MaxChainDistance, c)
        if i != MaxMushrooms()+1 then
            call ExplodeMushroom(i, ExplosionDelay, mx, my)
        endif
    endif
    
    set c = null
endfunction
private function DetonateC takes nothing returns boolean
if GetSpellAbilityId() != DetonateSpellID then
return false
endif
return true
endfunction
private function Detonate takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real ux = GetUnitX(u)
    local real uy = GetUnitY(u)
    local integer i = GetNearestOwnedMushroom(ux, uy, MaxDetonateDistance, u)
    if i != MaxMushrooms()+1 then
        call ExplodeMushroom(i, ExplosionDelay,ux, uy)
    endif
    set u = null
endfunction

private function GrowMushroom takes nothing returns nothing
    local MushroomStruct data = 0
    local MushroomMissleStruct data2 = 0
    local integer i = 0
    local real temp
    
    loop
        exitwhen i >= MushroomMissleCount
        set data2 = MushroomMissleData[i]
        set data2.dist = data2.dist-data2.speed
        if data2.dist > 0 then
            call SetUnitXY(data2.missle, data2.tx+data2.dist*Cos(data2.angle), data2.ty+data2.dist*Sin(data2.angle))
        else
            call KillUnit(data2.missle)
            set MushroomMissleData[i] = MushroomMissleData[MushroomMissleCount]
            set MushroomMissleCount = MushroomMissleCount-1
            call data2.destroy()
        endif            
        set i = i+1
    endloop
    
    set i = 0
    
    loop
        exitwhen i >= MushroomCount
        set data = MushroomData[i]
        if data.growing then
            set data.duration = data.duration+0.025
            set temp = data.duration/GrowthTime
            call SetUnitScale(data.mushroom, temp, temp, temp)
            if temp >= 2.5 then
                set data.growing = false
                if ExplodeAfterTime then
                    call ExplodeMushroom(i, 0, 0, 0)
                endif
            endif
        endif
        set i = i+1
    endloop
endfunction

private function PoisonousMushroomC takes nothing returns boolean
if GetSpellAbilityId() != MushroomSpellID then
return false
endif
return true
endfunction
private function PoisonousMushroom takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local player owner = GetOwningPlayer(caster)
    local location tl = GetSpellTargetLoc()
    local real lx = GetLocationX(tl)
    local real ly = GetLocationY(tl)
    local real dx = 0
    local real dy = 0
    local real dist = 0
    local integer i = 0
    local MushroomStruct data
    
    set i = GetNearestOwnedMushroom(lx, ly, MinDistance, caster)
    if i != MaxMushrooms()+1 then        
        call IssueImmediateOrder(caster, "stop" )
        call DisplayTextToPlayer(owner, 0, 0, "|cffffcc00There is already an other Poisonous Mushroom near the target point.|r")
        set caster = null
        return
    endif
    
    if MushroomCount >= MaxMushrooms()-1 then
        if NewExplodesOld then
            call ExplodeMushroom(0, ExplosionDelay, GetUnitX(caster), GetUnitY(caster))
        else
            call IssueImmediateOrder(caster, "stop" )
            call DisplayTextToPlayer(owner, 0, 0, "|cffffcc00There are already "+I2S(MaxMushrooms())+" Poisonous Mushrooms at the map.|r")
            set caster = null
            return
        endif
    endif
    
    call DestroyEffect(AddSpecialEffectTarget(CasterArtPlace, caster, CasterArtPlaceAttach))
    set data = MushroomStruct.create()
    set data.mushroom = CreateUnit(owner, MushroomUnitID, lx, ly, GetRandomReal(0, 360))
    set data.duration = 0
    set data.growing = true
    set data.skilllevel = GetUnitAbilityLevel(caster, MushroomSpellID)
    set data.caster = caster
    call SetUnitScale(data.mushroom, 0, 0, 0)
    
    if MushroomCount == 0 then
        call TimerStart(MushroomTimer, 0.025, true, function GrowMushroom)
    endif
    
    set MushroomData[MushroomCount] = data
    set MushroomCount = MushroomCount+1
    
    set caster = null
    call RemoveLocation(tl)
    set tl = null
endfunction

//===========================================================================
private function I takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( t, Condition( function PoisonousMushroomC ) )
call TriggerAddAction(t,function PoisonousMushroom)
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition( t, Condition( function DetonateC ) )
call TriggerAddAction(t,function Detonate)
    //call GT_AddStartsEffectAction(function PoisonousMushroom,MushroomSpellID)
    //call GT_AddStartsEffectAction(function Detonate,DetonateSpellID)
    call XE_PreloadAbility( MushroomSpellID)
    call XE_PreloadAbility( DetonateSpellID)
endfunction

endscope

I can't see anything strikingly wrong with it, but it's quite long. Typically the only thing that "breaks" pre-patch code is utility of the return bug. There are probably other examples that occur on rare occasions, but this is the main one.

Curious though, since I can't test the spell, what's wrong with it?

yeah, i think the pre 1.24 concern is mostly that it's an older spell and i don't really understand it's use of structs and whatever.
 
Status
Not open for further replies.
Top