Issue With a Spell

roXplosive

New Member
Reaction score
15
Well I made a structure for my reverse gravity spell I'm working on :

JASS:

struct FlyUnit          //structure for making a unit fly 
    private unit u              
    private real x
    private real y
    private real z
    private real BaseFlyHeight
    private integer HeightModified //how many times this unit has been moved upwards
    
    method Set takes unit target returns nothing
        set .u=target
        call BJDebugMsg(GetUnitName(.u))
        set .x=GetUnitX(.u)
        set .y=GetUnitY(.u)
        set .z=GetUnitFlyHeight(.u)
        set .BaseFlyHeight=.z
        set .HeightModified = 0
        call PauseUnit(.u,true)
        call SetUnitPathing( .u , false )
        call UnitAddAbility(.u,FlyAbilCode)
        call UnitRemoveAbility(.u,FlyAbilCode)
    endmethod
    
    method GetFlyHeightNumber takes nothing returns integer
        return .HeightModified
    endmethod
    
    method FlyHeight takes nothing returns real
        return .z-.BaseFlyHeight
    endmethod
    
    method Unit takes nothing returns unit
        return .u
    endmethod
    
    method Fly takes real NextHeight returns nothing
        set .z=NextHeight+.BaseFlyHeight
        set .HeightModified = .HeightModified + 1
       // call BJDebugMsg("fly "+R2S(.z)+" "+GetUnitName(.u))
        call SetUnitFlyHeight(.u,.z,FlyHeightRatio)
    endmethod
    
    method Destroy takes nothing returns nothing
        call SetUnitFlyHeight(.u,.BaseFlyHeight,FlyHeightRatio)
        call PauseUnit(.u , false )
        call SetUnitPathing(.u , true )
        set .u=null
    endmethod
    
endstruct


And later on any units antering in a reerse graity area will be sent flying :

JASS:

set g=GetUnitsInRangeOfLocMatching(BaseAoE+AoEincrement*lvl , center , Filter(function True))
loop
    set un=FirstOfGroup(g)
    if IsUnitEnemy ( un , pl ) and (not IsUnitInGroup(un , g2)) and (un!=null) then
        call GroupAddUnit(g2,un)
        call affected[FlyingUnits].Set(un)
        set FlyingUnits = FlyingUnits + 1
        call BJDebugMsg("Unit added "+I2S(FlyingUnits)+" "+GetUnitName(un))
    endif
exitwhen un==null
    call GroupRemoveUnit(g,un)
endloop


The problem is my array of local FlyingUnit variables only memorizes the last unit entering the reerse gravity field on all the positions . I mean all the unit u fields in the structure hae the same value . If someone knows where I'm reinenting the wheel please point up .

PS : got to change my keyboard since my "V" key gies me a hard time
 
Reaction score
86
Post the whole trigger for the 2nd trigger.

Also, this thread should be in the Jass Help forum, not this one.
 

roXplosive

New Member
Reaction score
15
Here you have it . I hope it's relevant

JASS:

scope RG initializer Init

globals
    private real basedamage = 75     //spell deals 75*spellvl damage
    private real BaseAoE = 100       //Base AoE
    private real AoEincrement = 50   //AoE increment per skill level
    private real flyduration = 0.5   //base fly duration
    private real StrBonusDamage = 1  //bonus damage from falling based on hero strength
    private real ArmorDamageIncrement = 3 //how much the bonus damage from strength is increased by armor in percents at all levels
    
    
    private integer BDRed = 0         //how much red is in the display for bonus falling damage
    private integer BDBlue = 255      //How much blue in the text tag
    private integer BDGreen = 0       //How much Green is in tettag color
    private real    BDVelocity = 60   
    private real    BDSize     = 10 
    private real    BDTransparency = 8
    private real    BDTextAngle   = 90
    private real    BDDuration   = 1.25
    private real    BDCutOffDurtn   = 2.5   
    
    private integer FlyAbilCode='A004'  //ability code for fly
    private integer AbilCode = 'A003'   //ability code for reverse gravity
    private integer AbilBuff = 'B000'   //the buff for reerse gravity
    private real    FlyHeightRatio = 10000  //rate of change in flight height
    private real    TimerWait   = 0.05  //how often do positions change 
    private real    BaseMaxHeight = 200   //How much will units go up per tick
endglobals

struct FlyUnit          //structure for making a unit fly 
    private unit u              
    private real x
    private real y
    private real z
    private real BaseFlyHeight
    private integer HeightModified //how many times this unit has been moved upwards
    
    method Set takes unit target returns nothing
        set .u=target
        call BJDebugMsg(GetUnitName(.u))
        set .x=GetUnitX(.u)
        set .y=GetUnitY(.u)
        set .z=GetUnitFlyHeight(.u)
        set .BaseFlyHeight=.z
        set .HeightModified = 0
        call PauseUnit(.u,true)
        call SetUnitPathing( .u , false )
        call UnitAddAbility(.u,FlyAbilCode)
        call UnitRemoveAbility(.u,FlyAbilCode)
    endmethod
    
    method GetFlyHeightNumber takes nothing returns integer
        return .HeightModified
    endmethod
    
    method FlyHeight takes nothing returns real
        return .z-.BaseFlyHeight
    endmethod
    
    method Unit takes nothing returns unit
        return .u
    endmethod
    
    method Fly takes real NextHeight returns nothing
        set .z=NextHeight+.BaseFlyHeight
        set .HeightModified = .HeightModified + 1
       // call BJDebugMsg("fly "+R2S(.z)+" "+GetUnitName(.u))
        call SetUnitFlyHeight(.u,.z,FlyHeightRatio)
    endmethod
    
    method Destroy takes nothing returns nothing
        call SetUnitFlyHeight(.u,.BaseFlyHeight,FlyHeightRatio)
        call PauseUnit(.u , false )
        call SetUnitPathing(.u , true )
        set .u=null
    endmethod
    
endstruct

private function True takes nothing returns boolean
    return true 
endfunction

private function ACondition takes nothing returns boolean
    return GetSpellAbilityId()==AbilCode
endfunction

private function Actions takes nothing returns nothing
local unit      caster = GetTriggerUnit()
local player    pl = GetOwningPlayer(caster)
local integer   lvl = GetUnitAbilityLevel(caster,AbilCode)
local location  center = GetSpellTargetLoc()
local real      MaxHeight = BaseMaxHeight * SquareRoot( lvl ) // determining the height units are tossed for eery skill level
local group     g = CreateGroup() //group for selecting units in AoE periodically
local group     g2 = CreateGroup()//group for retaining units affected by the ability
local FlyUnit   array affected
local integer   FlyingUnits = 0
local unit      un
local integer   i=0
local integer   j
local real      bonusdamage
local texttag   t

loop

//Actions for adding newly entered units in the AoE to the flying units array
set g=GetUnitsInRangeOfLocMatching(BaseAoE+AoEincrement*lvl , center , Filter(function True))
loop
    set un=FirstOfGroup(g)
    if IsUnitEnemy ( un , pl ) and (not IsUnitInGroup(un , g2)) and (un!=null) then
        call GroupAddUnit(g2,un)
        call affected[FlyingUnits].Set(un)
        set FlyingUnits = FlyingUnits + 1
        call BJDebugMsg("Unit added "+I2S(FlyingUnits)+" "+GetUnitName(un))
    endif
exitwhen un==null
    call GroupRemoveUnit(g,un)
endloop
//Actions for changing the fly height 
// I have decided to make the ascending units move faster towards the end of motion according to Sin func
    set j=0
    loop
     exitwhen j==FlyingUnits
     call BJDebugMsg("Unit "+I2S(j)+" "+GetUnitName(affected[j].Unit()))
     call affected[j].Fly(Sin((bj_PI/2)*(affected[j].GetFlyHeightNumber()*TimerWait)/(lvl*flyduration))*MaxHeight)
     set j = j + 1
    endloop
   
set i=i+1   
call TriggerSleepAction(TimerWait)  
exitwhen i*TimerWait>=flyduration*lvl

endloop

// Time to drop all the levitating units to the ground ; they will take damage depending on height
set j=0
loop
exitwhen j==FlyingUnits
    call UnitDamageTarget(caster, affected[j].Unit() , (affected[j].FlyHeight()*affected[j].FlyHeight())/(MaxHeight*MaxHeight)*lvl*basedamage , false , false , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
    //unit is damaged according to the square of it's height/maxheight multiplied by the spell's damage
    set bonusdamage = GetHeroStr(affected[j].Unit() , true )*StrBonusDamage*(1+(ArmorDamageIncrement/100)*TargetArmor(affected[j].Unit()))
    call UnitDamageTarget(caster,affected[j].Unit(), bonusdamage , false , false , ATTACK_TYPE_HERO , DAMAGE_TYPE_MAGIC , WEAPON_TYPE_WHOKNOWS)
    set t = CreateTextTagUnitBJ("+" + I2S(R2I(bonusdamage)), affected[j].Unit() , BDVelocity , BDSize, BDRed, BDGreen, BDBlue, BDTransparency)
    call SetTextTagVelocityBJ(t, BDVelocity , BDTextAngle)
    call SetTextTagPermanent(t, false)
    call SetTextTagLifespan(t, BDDuration)
    call affected[j].Destroy()
set j=j+1
endloop

endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local integer i=0
    set gg_trg_ReverseGravity = CreateTrigger(  )
    loop
        call TriggerRegisterPlayerUnitEvent(gg_trg_ReverseGravity , Player(i) , EVENT_PLAYER_UNIT_SPELL_EFFECT , Filter(function True))
    exitwhen i==15
    set i=i+1
    endloop
    call TriggerAddCondition(gg_trg_ReverseGravity , Condition(function ACondition))
    call TriggerAddAction( gg_trg_ReverseGravity, function Actions )
endfunction

endscope
 

roXplosive

New Member
Reaction score
15
I was thinking of that but Idk how to initialize a unit type variable beacause that's the issue as I see the problem .
 

roXplosive

New Member
Reaction score
15
I think since I have not edited the create() method is shouldn't have any actions in it but givving it a try obviously won't hurt . LOL it's alive . Thanks man . Now do you know how to use timers to set up periodic actions ? Because TriggerSleepAction() doesn't seem to work optimal .
 
Reaction score
86
well. i would use an attachment system, so try ABC or something of the sort. Then make a timer, make a function for the timer to call, store the unit array affected in another struct, then attach the struct to the timer and work from there.
 

roXplosive

New Member
Reaction score
15
Now I got a wonderful bug . :D whenever a flying unit dies I end up with units walking in the sky (the rest never fall down ) :)) . It's nice
 

roXplosive

New Member
Reaction score
15
Well here's the code . Sometimes it gived me a message like you tried to destroy a null variable of type ... I have to find a way to plant the buff I made on the afflicted units . Now I'm thinking of changing the number of waves (I based it off blizzard) but that means I will have to make it a dummy spell . Will do if I have to . Then I will check if a unit is already under the effect of this ability (has the buff) so they won't be affected by it twice and it would solve a bug . Left remaiming would be timing and changing the liftoff formula to something more realistic and maybe make them hover up there for a period .

JASS:

scope RG initializer Init

globals
    private real basedamage = 75     //spell deals 75*spellvl damage
    private real BaseAoE = 100       //Base AoE
    private real AoEincrement = 50   //AoE increment per skill level
    private real flyduration = 0.5   //base fly duration
    private real StrBonusDamage = 1  //bonus damage from falling based on hero strength
    private real ArmorDamageIncrement = 3 //how much the bonus damage from strength is increased by armor in percents at all levels
    
    
    private integer BDRed = 0         //how much red is in the display for bonus falling damage
    private integer BDBlue = 255      //How much blue in the text tag
    private integer BDGreen = 0       //How much Green is in tettag color
    private real    BDVelocity = 60   
    private real    BDSize     = 10 
    private real    BDTransparency = 8
    private real    BDTextAngle   = 90
    private real    BDDuration   = 1.25
    private real    BDCutOffDurtn   = 2.5   
    
    private integer FlyAbilCode='A004'  //ability code for fly
    private integer AbilCode = 'A003'   //ability code for reverse gravity
    private integer AbilBuff = 'B000'   //the buff for reerse gravity
    private real    FlyHeightRatio = 10000  //rate of change in flight height
    private real    TimerWait   = 0.05  //how often do positions change 
    private real    BaseMaxHeight = 200   //How much will units go up per tick
endglobals

struct FlyUnit          //structure for making a unit fly 
    private unit u              
    private real x
    private real y
    private real z
    private real BaseFlyHeight
    private integer HeightModified //how many times this unit has been moved upwards
    
    method Set takes unit target returns nothing
        set .u=target
        set .x=GetUnitX(.u)
        set .y=GetUnitY(.u)
        set .z=GetUnitFlyHeight(.u)
        set .BaseFlyHeight=.z
        set .HeightModified = 0
        call PauseUnit(.u,true)
        call SetUnitPathing( .u , false )
        call UnitAddAbility(.u,FlyAbilCode)
        call UnitRemoveAbility(.u,FlyAbilCode)
    endmethod
    
    method GetFlyHeightNumber takes nothing returns integer
        return .HeightModified
    endmethod
    
    method FlyHeight takes nothing returns real
        return .z-.BaseFlyHeight
    endmethod
    
    method Unit takes nothing returns unit
        return .u
    endmethod
    
    method Fly takes real NextHeight returns nothing
        set .z=NextHeight+.BaseFlyHeight
        set .HeightModified = .HeightModified + 1
        call SetUnitFlyHeight(.u,.z,FlyHeightRatio)
    endmethod
    
    method Destroy takes nothing returns nothing
        call BJDebugMsg("destroyed struct for "+GetUnitName(.u)+" normal z "+R2S(.BaseFlyHeight))
        call SetUnitFlyHeight(.u,.BaseFlyHeight,FlyHeightRatio)
        call PauseUnit(.u , false )
        call SetUnitPathing(.u , true )
        set .u=null
    endmethod
    
endstruct

private function True takes nothing returns boolean
    return true 
endfunction

private function ACondition takes nothing returns boolean
    return GetSpellAbilityId()==AbilCode
endfunction

private function Actions takes nothing returns nothing
local unit      caster = GetTriggerUnit()
local player    pl = GetOwningPlayer(caster)
local integer   lvl = GetUnitAbilityLevel(caster,AbilCode)
local location  center = GetSpellTargetLoc()
local real      MaxHeight = BaseMaxHeight * SquareRoot( lvl ) // determining the height units are tossed for eery skill level
local group     g = CreateGroup() //group for selecting units in AoE periodically
local group     g2 = CreateGroup()//group for retaining units affected by the ability
local FlyUnit   array affected
local integer   FlyingUnits = 0
local unit      un
local integer   i=0
local integer   j
local integer   k
local real      damage
local real      bonusdamage
local texttag   t

loop

//Actions for adding newly entered units in the AoE to the flying units array
set g=GetUnitsInRangeOfLocMatching(BaseAoE+AoEincrement*lvl , center , Filter(function True))
loop
    set un=FirstOfGroup(g)
    if IsUnitEnemy ( un , pl ) and (not IsUnitInGroup(un , g2)) and (un!=null) and GetWidgetLife(un)>.405 then
        call GroupAddUnit(g2,un)
        set affected[FlyingUnits]=FlyUnit.create()
        call affected[FlyingUnits].Set(un)
        set FlyingUnits = FlyingUnits + 1
    endif
exitwhen un==null
    call GroupRemoveUnit(g,un)
endloop
//Actions for changing the fly height 
// I have decided to make the ascending units move faster towards the end of motion according to Sin func
    set j=0
    loop
     exitwhen j==FlyingUnits    
     if GetWidgetLife(affected[j].Unit())>.405 then
        call affected[j].Fly(Sin((bj_PI/2)*(affected[j].GetFlyHeightNumber()*TimerWait)/(lvl*flyduration))*MaxHeight)
     else
        set k=j
        call affected[j].Destroy()
        call affected[j].destroy()
        loop
        exitwhen k==FlyingUnits
            set affected[j]=affected[j+1]
            set k=k+1
        endloop
        set FlyingUnits=FlyingUnits-1
     endif
     set j = j + 1
    endloop
   
set i=i+1   
call TriggerSleepAction(TimerWait)  
exitwhen i*TimerWait>=flyduration*lvl

endloop

// Time to drop all the levitating units to the ground ; they will take damage depending on height
set j=0
loop
exitwhen j==FlyingUnits
    set un=affected[j].Unit()
    set damage = (affected[j].FlyHeight()*affected[j].FlyHeight())/(MaxHeight*MaxHeight)*lvl*basedamage
    //unit is damaged according to the square of it's height/maxheight multiplied by the spell's damage
    set bonusdamage = GetHeroStr(affected[j].Unit() , true )*StrBonusDamage*(1+(ArmorDamageIncrement/100)*TargetArmor(affected[j].Unit()))
    call affected[j].Destroy()
    call affected[j].destroy()
    if GetWidgetLife(un)>.405 then
    call UnitDamageTarget(caster, un , damage , false , false , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS)
    call UnitDamageTarget(caster, un , bonusdamage , false , false , ATTACK_TYPE_HERO , DAMAGE_TYPE_MAGIC , WEAPON_TYPE_WHOKNOWS)
    set t = CreateTextTagUnitBJ("+" + I2S(R2I(bonusdamage)), un , BDVelocity , BDSize, BDRed, BDGreen, BDBlue, BDTransparency)
    call SetTextTagVelocityBJ(t, BDVelocity , BDTextAngle)
    call SetTextTagPermanent(t, false)
    call SetTextTagLifespan(t, BDDuration)
    endif
set j=j+1
endloop

endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local integer i=0
    set gg_trg_ReverseGravity = CreateTrigger(  )
    loop
        call TriggerRegisterPlayerUnitEvent(gg_trg_ReverseGravity , Player(i) , EVENT_PLAYER_UNIT_SPELL_EFFECT , Filter(function True))
    exitwhen i==15
    set i=i+1
    endloop
    call TriggerAddCondition(gg_trg_ReverseGravity , Condition(function ACondition))
    call TriggerAddAction( gg_trg_ReverseGravity, function Actions )
endfunction

endscope
 
General chit-chat
Help Users

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top