• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Need help with struct usage for MUI spell

Status
Not open for further replies.
Level 12
Joined
Oct 16, 2010
Messages
680
okay , so I've already done this with globals worked properly
but I'm gone use it in my orpg so i have to make it MUI

I don't really familiar with structs atm , so I'm not sure about how to do it.

JASS:
library AimedShot initializer begin

struct aimedshot
    unit arrow
    unit castunit
    unit targunit
    real clocx
    real clocy
    real tlocx
    real tlocy
    real alocx
    real alocy
    timer tmr
    
    method Distance takes real x1, real y1, real x2, real y2 returns real
        return SquareRoot(Pow(x2-x1,2)+Pow(y2-y1,2))
    endmethod
    
    method GetX takes nothing returns real
        set .alocx = .alocx - ((.clocx-.tlocx)/((.Distance(.clocx,.clocy,.tlocx,.tlocy)/2500.)/0.03))
        return .alocx
    endmethod
    
    method GetY takes nothing returns real
        set .alocy = .alocy - ((.clocy-.tlocy)/((.Distance(.clocx,.clocy,.tlocx,.tlocy)/2500.)/0.03))
        return .alocy
    endmethod
    
    method RekLoop takes nothing returns nothing
        local location loc = Location(GetX(),GetY())
        call SetUnitPositionLoc(.arrow,loc)
        call RemoveLocation(loc)
        set loc = null
        if .Distance(.clocx,.clocy,.tlocx,.tlocy) > .Distance(.clocx,.clocy,.alocx,.alocy) then
             //... this should be the part when the method calls itself
        else
            
        endif
    endmethod
    
    method Init takes integer pn returns nothing
        set .castunit = GetTriggerUnit()
        set .targunit = GetSpellTargetUnit()
        set .clocx = GetUnitX(.castunit)
        set .clocy = GetUnitY(.castunit)
        set .tlocx = GetUnitX(.targunit)
        set .tlocy = GetUnitY(.targunit)
        set .alocx = .clocx
        set .alocy = .clocy
        set .tmr = CreateTimer()
    endmethod
    
endstruct

private function kilo takes nothing returns nothing
    local integer x = 0
    local unit arrow = CreateUnitAtLoc(GetLocalPlayer(),'h001',GetUnitLoc(GetTriggerUnit()),GetUnitFacing(GetTriggerUnit()))
    local aimedshot as = aimedshot.create()
    call SetUnitUserData(arrow,as)
    loop
        exitwhen GetLocalPlayer() == Player(x)
        set x = x + 1
    endloop
    call as.Init(x)
    call TimerStart(as.tmr,0.03,false,as.RekLoop)
endfunction

private function ft takes nothing returns boolean
    return GetSpellAbilityId() == 'A00U'
endfunction

private function begin takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer a = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(a),EVENT_PLAYER_UNIT_SPELL_CAST,null)
        set a = a + 1
        exitwhen a > 7
    endloop
    call TriggerAddAction(t,function kilo)
    call TriggerAddCondition(t,Condition(function ft))
endfunction

endlibrary

This is what i've done so far but don't know how to use
methods with timer
call TimerStart(as.tmr,0.03,false,as.RekLoop) fails:/
Or should i do it in another way?
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
For this spell I would recommend something like T32. Basically this does the timer work for you. You just need to have a method named periodic that contains your periodic stuff and call startPeriodic/stopPeriodic when you need to. You also need to have implement T32x in your struct.

Your timer call failed because RekLoop is a method instead of a static method. Methods implicity take in the struct as an argument which makes it fail in TimerStart since it requires a function with no arguments. Static methods don't do that.

Some other things to note:
You can override the static method create so that you don't need to call another method to initialize the members. The static method create can take any number of arguments and must return your struct type.
JASS:
    static method create takes integer pn returns thistype // thistype is basically the same as writing your struct's type without needing to care about what it's actually called
        local thistype this = thistype.allocate()
        set .castunit = GetTriggerUnit()
        set .targunit = GetSpellTargetUnit()
        set .clocx = GetUnitX(.castunit)
        set .clocy = GetUnitY(.castunit)
        set .tlocx = GetUnitX(.targunit)
        set .tlocy = GetUnitY(.targunit)
        set .alocx = .clocx
        set .alocy = .clocy
        set .tmr = CreateTimer()
        return this
    endmethod

    ...

    call aimedshot.create()
Don't use locations, use coordinates instead.
Use EVENT_PLAYER_UNIT_SPELL_EFFECT for the trigger event.
 
Lender, you should combine conditions/actions instead of separatig them. Additionaly, while using vJass, modules prove to be great initializers. TriggerRegisterAnyUnitEvent shoudlnt' be inlined, it's one of those good BJ (although you're using that event for just 7 players). Anyways:
JASS:
private function ft takes nothing returns boolean
    return GetSpellAbilityId() == 'A00U'
endfunction

private function kilo takes nothing returns nothing
    local integer x = 0
    local unit arrow = CreateUnitAtLoc(GetLocalPlayer(),'h001',GetUnitLoc(GetTriggerUnit()),GetUnitFacing(GetTriggerUnit()))
    local aimedshot as = aimedshot.create()
    call SetUnitUserData(arrow,as)
    loop
        exitwhen GetLocalPlayer() == Player(x)
        set x = x + 1
    endloop
    call as.Init(x)
    call TimerStart(as.tmr,0.03,false,as.RekLoop)
endfunction
->>
JASS:
private function ft takes nothing returns boolean
    local integer x=0
    local unit u
    if GetSpellAbilityId() == 'A00U'
        set u = GetTriggerUnit()
        set bj_lastCreatedUnit = CreateUnit(GetTriggerPlayer(),'h001', GetUnitX(u), GetUnitY(u), 0)
        // rest
        set u = null
    endif
    return false
endfunction

// At initialize just:
    call TriggerAddCondition(t,Filter(function ft))
0,03 ->> 0,03125 in jass;
Creating unit for GetLocalPlyaer(); ain't it insta desync?
Instead of locations, focus on coordinates, they are faster.
Your struct should extend array, to avoid trash code, but I'm sure you have to acumulate the basic knowledge first, to be ready for advanced tricks.
 
Status
Not open for further replies.
Top