Spell Problem

Tyman2007

Ya Rly >.
Reaction score
74
This spell basically fires a missile provided there's a nearby mortar team. The problem is, the trigger works properly the first time, but the 2nd time i cast the spell, it launches the missile in the same place regardless of where i cast it.

Here's my trigger.

JASS:
library FireRocket initializer Init requires TimerUtils

    //Basic Configuration
    globals
        private constant integer ABIL_CODE = 'A000' //Rawcode of the Ability
        
        private constant boolean REQ_MT = true //Requires mortar team to be close?
        private constant real MT_DIST = 250 //Within what range of the mortar team?
        private constant integer MT_ID = 'hmtm' //Rawcode of Mortar Team
    endglobals
    
    //Missile Configuration
    globals
        private constant integer DUMM_CODE = 'h000' //Rawcode of the dummy unit
        private constant real WBC = 2 //Seconds to wait before the missile is launched
        private constant real INIT_DIST = 100 //Missile spawn distance from caster
        
        private constant real CALLBACK = 0.03125 //How often the move is repeated
        private constant real MOVE_DIST = 30 //Distance the missile moves per tick
        private constant real TOTAL_DIST = 700 //Distance of the spell
        
        private constant real TRIGGER_DIST = 30 //How sensitive the missile is (30 through 100 is good)
        private constant real DAMAGE = 150 //Damage done. Self explainatory.
        
        private constant real S_AREA = 250 //Small damage area
        private constant real M_AREA = 125 //Medium damage area
        private constant real F_AREA = 75 //Full damage area
    endglobals
    
    private constant function Degtorad takes nothing returns real
        return 3.1415926535897932384626433832 / 180
    endfunction
    
    private constant function Radtodeg takes nothing returns real
        return 180 / 3.1415926535897932384626433832
    endfunction
    
    private constant function filter takes nothing returns boolean
        return IsUnitType(GetFilterUnit(),UNIT_TYPE_DEAD) == false and /*
        */     GetUnitTypeId(GetFilterUnit()) == MT_ID
    endfunction
    
    private function GetUnitsInRange takes unit u returns group
        local group g = CreateGroup()
        call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), MT_DIST, function filter)
        return g
    endfunction

    private function GetUnitsInRange2 takes unit u, real r returns group
        local group g = CreateGroup()
        call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), r, function filter)
        return g
    endfunction
    
    private struct Data
        player p
        unit u
        unit d
        real r
        
        real x
        real y
        
        real x2
        real y2
        
        real x3
        real y3
        
        real f
        real cd
        
        static method create takes unit u returns Data
            local Data d = Data.allocate()
            
            set d.u = u
            set d.p = GetOwningPlayer(u)
        
            set d.x = GetUnitX(u)
            set d.y = GetUnitY(u)
            
            set d.x2 = d.x + INIT_DIST * Cos(d.f * Degtorad())
            set d.y2 = d.y + INIT_DIST * Sin(d.f * Degtorad())
            
            return d
        endmethod
        
        method destroy takes nothing returns nothing
            set .u = null
            set .p = null
            set .d = null
            set .r = 0
            
            set .x = 0
            set .y = 0
            set .x2 = 0
            set .y2 = 0
            set .x3 = 0
            set .y3 = 0
            set .f = 0
            set .cd = 0
        endmethod
    endstruct

    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == 'A000'
    endfunction
    
    
    private function CallBack takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local Data d = GetTimerData(t)
        
        set d.x = 0
        set d.y = 0
            
        set d.x2 = 0
        set d.y2 = 0
        
        set d.f = Radtodeg() * Atan2(GetSpellTargetY() - d.y, GetSpellTargetX() - d.x)
        
        if d.cd < TOTAL_DIST then
            set d.x = GetUnitX(d.d)
            set d.y = GetUnitY(d.d)
            
            set d.x2 = d.x + MOVE_DIST * Cos(d.f * Degtorad())
            set d.y2 = d.y + MOVE_DIST * Sin(d.f * Degtorad())
            
            call SetUnitX(d.d, d.x2)
            call SetUnitY(d.d, d.y2)
            set d.cd = d.cd + MOVE_DIST
        else
            call UnitDamagePoint(d.u, 0, S_AREA, GetUnitX(d.d), GetUnitY(d.d), DAMAGE/3, true, false, ATTACK_TYPE_SIEGE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            call UnitDamagePoint(d.u, 0, M_AREA, GetUnitX(d.d), GetUnitY(d.d), DAMAGE/3, true, false, ATTACK_TYPE_SIEGE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
            call UnitDamagePoint(d.u, 0, F_AREA, GetUnitX(d.d), GetUnitY(d.d), DAMAGE/3, true, false, ATTACK_TYPE_SIEGE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)            
            call KillUnit(d.d)
            call PauseUnit(d.u, false)
            call d.destroy()
            call ReleaseTimer(t)
        endif
    endfunction

    private function Actions takes nothing returns nothing
        local timer t = NewTimer()
        local unit u = GetTriggerUnit()
        local Data d = Data.create(u)
        local group g
        local boolean b
        
        set b = true
        if (REQ_MT) then
            globals
                private unit MT
            endglobals
            set g = GetUnitsInRange(d.u)
            set MT = FirstOfGroup(g)
            if MT == null then
                 set b = false
                 call BJDebugMsg("I can't find a mortar team!")
            else
                set b = true
                call BJDebugMsg("I've found a mortar team!")
            endif
        endif
        call TriggerSleepAction(.5)
        if b == true then
            call PauseUnit(d.u, true)
            call SetUnitAnimation(d.u, "stand")
            call BJDebugMsg("Why is b true?")
            
            if (REQ_MT) then
                call SetUnitAnimation(MT, "attack")
                call TriggerSleepAction(WBC)
            endif
            
            set d.d = CreateUnit(d.p, DUMM_CODE, d.x2, d.y2, d.f)
            call SetUnitX(d.d, d.x2)
            call SetUnitY(d.d, d.y2)
            
            call SetUnitAnimation(d.u, "attack")
        
            call SetTimerData(t, d)
            call TimerStart(t, CALLBACK, true, function CallBack)
        endif
    endfunction

    private function Init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( trig, Condition( function Conditions ) )
        call TriggerAddAction( trig, function Actions )
    endfunction

endlibrary


is there something I missed here?
Thanks to all who help :p

Optimization is not my key goal here until I fix whatever problem occurs. Static ifs are not working as I wanted them to.
 

Tyman2007

Ya Rly >.
Reaction score
74
well I tried it with the unit facing..

oops.. crap I didn't mean to use it in callback :p one second.

EDIT: HAHA it works! I just mis-placed some things that's all!

Thanks for the indirect help :p
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      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