• 🏆 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] Ordering to cast doesn't work (PUI)

Status
Not open for further replies.
Level 2
Joined
Aug 4, 2008
Messages
7
JASS:
scope AutoCastSystem initializer I

globals
    private region R 
endglobals

private struct ACS
    //! runtextmacro PUI()
    integer array orderidN [3] 
    integer array orderidP [3]
    integer array orderidAOE [2]
    unit caster
endstruct

private function C1 takes nothing returns boolean
    return udg_Race[GetPlayerId(GetOwningPlayer(GetFilterUnit()))+1] == "HoMM" and GetUnitState(GetFilterUnit(), UNIT_STATE_MAX_MANA) > 1 and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == true
//    return udg_Race[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))+1] == "HoMM" and GetUnitState(GetTriggerUnit(), UNIT_STATE_MAX_MANA) > 1 and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true
endfunction

private function C3 takes nothing returns boolean
    //call BJDebugMsg("C3")
    return udg_Race[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))+1] == "HoMM" and GetUnitState(GetTriggerUnit(), UNIT_STATE_MAX_MANA) > 1
endfunction

private function C2 takes nothing returns boolean
    if IsUnitAnEnemy() == false then
    //call BJDebugMsg("false")
    else
    //call BJDebugMsg("true")
    endif
    return IsUnitAnEnemy() == false
endfunction

private function A2 takes nothing returns nothing
    local ACS dat = ACS[GetTriggerUnit()]
    local unit u
    local integer i = GetRandomInt(1, 2)
    call BJDebugMsg(GetUnitName(dat.caster) + "'s ACS is restored?")
    set udg_Player = GetOwningPlayer(GetTriggerUnit())
    call GroupEnumUnitsInRange(G, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 500, Condition(function IsUnitAnEnemy))
    set u = GetRandomUnit(G)
    call BJDebugMsg(GetUnitName(u) + " is the targeted unit (ACS)")
    //if IssueTargetOrder(dat.caster, "channel", u) == false then
    if IssueTargetOrderById(dat.caster, dat.orderidN[0], u) == false then
     call BJDebugMsg("1")
     if IssueTargetOrderById(dat.caster, dat.orderidN[1], u) == false then
      call BJDebugMsg("2")
      call IssueTargetOrderById(dat.caster, dat.orderidN[2], u)
     endif
    endif
    call GroupClear(G)
    call GroupEnumUnitsInRange(G, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 500, Condition(function C2))
    set u = GetRandomUnit(G)
    if IssueTargetOrderById(dat.caster, dat.orderidP[0], u) == false then
     call BJDebugMsg("1")
     if IssueTargetOrderById(dat.caster, dat.orderidP[1], u) == false then
      call BJDebugMsg("2")
      call IssueTargetOrderById(dat.caster, dat.orderidP[2], u)
     endif
    endif
    call GroupClear(G)
    call GroupEnumUnitsInRange(G, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 500, Condition(function IsUnitAnEnemy))
    set u = GetRandomUnit(G)
    if IssuePointOrderById(dat.caster, dat.orderidN[0], GetUnitX(u), GetUnitY(u)) == false then
     if IssuePointOrderById(dat.caster, dat.orderidN[1], GetUnitX(u), GetUnitY(u)) == false then
      call IssueTargetOrder(dat.caster, "attack", u)
     endif
    endif
    call GroupClear(G)
    set u = null
endfunction

private function A takes nothing returns nothing
    local ACS dat = ACS.create()
    set dat.caster = GetTriggerUnit()
    set ACS[dat.caster] = dat
    call BJDebugMsg(GetUnitName(dat.caster) + " now has ACS")
    if GetUnitTypeId(GetTriggerUnit()) == 'H029' then // Mage
     call BJDebugMsg("MAGE MAGE MAGE")
     set dat.orderidN[0] = 852600 // Fist of Wrath
     set dat.orderidP[0] = 852577 // Rigtheous Might
    elseif GetUnitTypeId(GetTriggerUnit()) == 'H02B' then // Storm Titan
     set dat.orderidAOE[0] = 852221 // Stormcaller
    elseif GetUnitTypeId(GetTriggerUnit()) == 'H03C' then // Djinn Sultan
     set dat.orderidN[0] = 852600 // RandomCB
     set dat.orderidP[0] = 852600 // RandomCB
    elseif GetUnitTypeId(GetTriggerUnit()) == 'H02Y' then // Shadow Matriarch
     set dat.orderidP[0] = 852577 // Rightous Might
     set dat.orderidN[0] = 852149 // Vulnerability
     set dat.orderidN[1] = 852135 // Slow
     set dat.orderidN[2] = 852181 // Confusion
    elseif GetUnitTypeId(GetTriggerUnit()) == 'H036' then // Pit Lord
     set dat.orderidN[0] = 852149 // Vulnerability
     set dat.orderidAOE[0] = 852223 // Fireball
     set dat.orderidAOE[1] = 852495 // Meteor Shower
    endif
endfunction


//===========================================================================
private function I takes nothing returns nothing
    local trigger t = CreateTrigger()
    set R = CreateRegion()
    call RegionAddRect(R, bj_mapInitialPlayableArea)
    call TriggerRegisterEnterRegion(t, R, Condition(function C1))
    call TriggerAddAction(t, function A)
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitTargetAcquired(t)
    call TriggerAddCondition(t, Condition(function C3))
    call TriggerAddAction(t, function A2)
endfunction

endscope

I'm trying to create an autocasting system for a race of my maul map.
For testing purposes, only a few units are in it yet.
The problem is, ordering never works.

SOMETIMES, it works once (the first time an enemy nears the unit, and my unit notices it, and then casts a spell), but after that, no matter how many enemies come, only the "<unit>'s ACS is restored" text appears, and numbers not.

Thanks for help in advance.
 
Level 5
Joined
Aug 27, 2007
Messages
138
A struct is an array. Last time I checked, you couldn't have arrays in structs.

Anyway... I don't really know too much about the syntax of macros and some of this looks a little crazy, so I'm having a lot of difficulty reading it.

How are you passing the structs from function A to function A2?

Edit: I read up a little... I understand the dynamic arrays and the whole arrays-in-struct thing, but my last question still applies.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
How are you passing the structs from function A to function A2?

That is taken care by PUI( or in this case the Pui macro):
A:set ACS[dat.caster] = dat
A2:local ACS dat = ACS[GetTriggerUnit()]

But there is no need for PUI here. Or for most of this. It resembles nuking a fly.
Will post code in a bit.

Edit:
Ordering all the spells at once isn't a good idea.
 
Level 2
Joined
Aug 4, 2008
Messages
7
I used to have one without PUI, only ABC, it periodically ordered the hero to do the same (ordering to cast everything at once). It worked decently well, but I don't want them to throw spells around in between waves.
If you have any better idea to do this, please tell me what it is. :)
Thank you in advance.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
This is my suggestion.
JASS:
scope AutoCastSystem initializer I

private function C3 takes nothing returns boolean
    //call BJDebugMsg("C3")
    return udg_Race[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))+1] == "HoMM" and GetUnitState(GetTriggerUnit(), UNIT_STATE_MAX_MANA) > 1
endfunction
private function C2 takes nothing returns boolean
    return not IsUnitAnEnemy()
endfunction

private function A2 takes nothing returns nothing
    local unit u
    local group G
    local unit t = GetAttacker()
    local integer utype=GetUnitTypeId(t)
    set udg_Player = GetOwningPlayer(t)
    call GroupEnumUnitsInRange(G, GetUnitX(t), GetUnitY(t), 500, Condition(function IsUnitAnEnemy))
    set u = GetRandomUnit(G)
    if utype == 'H029' then // Mage
        call IssueTargetOrderById(t, 852600 , u)
        call GroupEnumUnitsInRange(G, GetUnitX(t), GetUnitY(t), 500, Condition(function C2))
        set u = GetRandomUnit(G)
        call IssueTargetOrderById(t,852577, u)  // Rigtheous Might
    elseif utype == 'H02B' then // Storm Titan
        call IssuePointOrderById(t, 852221, GetUnitX(u), GetUnitY(u))
    elseif utype == 'H03C' then // Djinn Sultan
        call IssueTargetOrderById(t, 852600, u) // RandomCB
        call GroupEnumUnitsInRange(G, GetUnitX(t), GetUnitY(t), 500, Condition(function C2))
        set u = GetRandomUnit(G)
        call IssueTargetOrderById(t, 852600, u) // RandomCB
    elseif utype == 'H02Y' then // Shadow Matriarch
        call IssueTargetOrderById(t, 852149, u)
        set u =GetRandomUnit(G)
        call IssueTargetOrderById(t, 852135, u)
        set u =GetRandomUnit(G)
        call IssueTargetOrderById(t, 852181, u)
        call GroupEnumUnitsInRange(G, GetUnitX(t), GetUnitY(t), 500, Condition(function C2))
        set u =GetRandomUnit(G)
        call IssueTargetOrderById(t, 852577, u)
    elseif utype == 'H036' then // Pit Lord
        call IssueTargetOrderById(t, 852149, u)
        set u = GetRandomUnit(G)
        call IssuePointOrderById(t, 852223, GetUnitX(u), GetUnitY(u))
        set u = GetRandomUnit(G)
        call IssuePointOrderById(t, 852495, GetUnitX(u), GetUnitY(u))
    endif
    call GroupClear(G)
    set u = null
    set t = null
endfunction


//===========================================================================
private function I takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition(t, Condition(function C3))
    call TriggerAddAction(t, function A2)
endfunction

endscope
 
Last edited:
Level 2
Joined
Aug 4, 2008
Messages
7
No good captn'!
Firstly, unit attacked event is not good, there are some other triggers that fire on unit attacked events, and this let's them have that effect without actually attacking. But this is not a horrible thing.

Secondly, I guess you haven't noticed:

For testing purposes, only a few units are in it yet.

There are going to be like 3 times more unit types, and in theory there can be hundreds of them on the map, in the same time.

So please go with my PUI - like one instead, and find out why the handle fails. Thank you anyway!. :)
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
No good captn'!
Firstly, unit attacked event is not good, there are some other triggers that fire on unit attacked events, and this let's them have that effect without actually attacking. But this is not a horrible thing.

Secondly, I guess you haven't noticed:



There are going to be like 3 times more unit types, and in theory there can be hundreds of them on the map, in the same time.

So please go with my PUI - like one instead, and find out why the handle fails. Thank you anyway!. :)

Using WEU is not a good idea - it tends to corrupt maps. Also the special WEU triggers(and events) are buggy.

With both events almost the same thing happens ( as long as the spells have cooldowns). Except that unit acquires will fire only once per target.

But you are right though - with ifs it is kinda slow. Still no need for using PUI that way. Will post later.

Edit:

JASS:
scope AutoCastSystem initializer I
globals
    private string array fun
    private unit at
    private unit u
endglobals
private function C3 takes nothing returns boolean
    return udg_Race[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))+1] == "HoMM" and GetUnitState(GetTriggerUnit(), UNIT_STATE_MAX_MANA) > 1
endfunction
private function C2 takes nothing returns boolean
    return not IsUnitAnEnemy()
endfunction
private function C1 takes nothing returns boolean
    return udg_Race[GetPlayerId(GetOwningPlayer(GetFilterUnit()))+1] == "HoMM" and GetUnitState(GetFilterUnit(), UNIT_STATE_MAX_MANA) > 1 and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) == true
endfunction
function Mage takes nothing returns nothing
    call GroupEnumUnitsInRange(G, GetUnitX(at), GetUnitY(at), 500, Condition(function C2))
    set u = GetRandomUnit(G)
    call IssueTargetOrderById(at, 852600 , u)
    call GroupEnumUnitsInRange(G, GetUnitX(at), GetUnitY(at), 500, Condition(function C2))
    set u = GetRandomUnit(G)
    call IssueTargetOrderById(at,852577, u) // Rigtheous Might
endfunction
function Storm_Titat takes nothing returns nothing
    call GroupEnumUnitsInRange(G, GetUnitX(at), GetUnitY(at), 500, Condition(function C2))
    set u = GetRandomUnit(G)
    call IssuePointOrderById(at, 852221, GetUnitX(u), GetUnitY(u))
endfunction
function Djinn_Sultan takes nothing returns nothing
    call GroupEnumUnitsInRange(G, GetUnitX(at), GetUnitY(at), 500, Condition(function C2))
    set u = GetRandomUnit(G)
    call IssueTargetOrderById(at, 852600, u) // RandomCB
    call GroupEnumUnitsInRange(G, GetUnitX(at), GetUnitY(at), 500, Condition(function C2))
    set u = GetRandomUnit(G)
    call IssueTargetOrderById(at, 852600, u) // RandomCB
endfunction
function Shadow_Matriarch takes nothing returns nothing
    call GroupEnumUnitsInRange(G, GetUnitX(at), GetUnitY(at), 500, Condition(function C2))
    set u = GetRandomUnit(G)
    call IssueTargetOrderById(at, 852149, u)
    set u =GetRandomUnit(G)
    call IssueTargetOrderById(at, 852135, u)
    set u =GetRandomUnit(G)
    call IssueTargetOrderById(at, 852181, u)
    call GroupEnumUnitsInRange(G, GetUnitX(at), GetUnitY(at), 500, Condition(function C2))
    set u =GetRandomUnit(G)
    call IssueTargetOrderById(at, 852577, u)
endfunction
function Pit_Lord takes nothing returns nothing
    call GroupEnumUnitsInRange(G, GetUnitX(at), GetUnitY(at), 500, Condition(function C2))
    set u = GetRandomUnit(G)
    call IssueTargetOrderById(at, 852149, u)
    set u = GetRandomUnit(G)
    call IssuePointOrderById(at, 852223, GetUnitX(u), GetUnitY(u))
    set u = GetRandomUnit(G)
    call IssuePointOrderById(at, 852495, GetUnitX(u), GetUnitY(u))
endfunction
private function A2 takes nothing returns nothing
    if(fun[GetUnitIndex(GetTriggerUnit())]!=null) then
        set at=GetAttacker()
        call ExecuteFunc(fun[GetUnitIndex(GetTriggerUnit())])
    endif
endfunction
private function A takes nothing returns nothing
    local unit t = GetTriggerUnit()
    local integer utype=GetUnitTypeId(t)
    if utype == 'H029' then // Mage
        set fun[GetUnitIndex(t)]="Mage"
    elseif utype == 'H02B' then // Storm Titan
        set fun[GetUnitIndex(t)]="Storm_Titan"
    elseif utype == 'H03C' then // Djinn Sultan
        set fun[GetUnitIndex(t)]="Djinn_Sultan"
    elseif utype == 'H02Y' then // Shadow Matriarch
        set fun[GetUnitIndex(t)]="Shadow_Matriarch"
    elseif utype == 'H036' then // Pit Lord
        set fun[GetUnitIndex(t)]="Pit_Lord"
    endif
endfunction


//===========================================================================
private function I takes nothing returns nothing
    local trigger t = CreateTrigger()
    set R = CreateRegion()
    call RegionAddRect(R, bj_mapInitialPlayableArea)
    call TriggerRegisterEnterRegion(t, R, Condition(function C1))
    call TriggerAddAction(t, function A)
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition(t, Condition(function C3))
    call TriggerAddAction(t, function A2)
endfunction

endscope
 
Last edited:
Level 2
Joined
Aug 4, 2008
Messages
7
What WEU are you talking about? Who mentioned WEU?
Jesus, this place is horrible.
All you are doing is recommending worse and worse ways to do this.

Doesn't matter, tomorrow I can go back to thnet, and get some decent help there.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
What WEU are you talking about? Who mentioned WEU?
Jesus, this place is horrible.
All you are doing is recommending worse and worse ways to do this.

Doesn't matter, tomorrow I can go back to thnet, and get some decent help there.

call TriggerRegisterAnyUnitTargetAcquired(t)

That ain't a standart function. Thus I presumed you use World Editor Unlimited.

Please explain why my last suggestion is worse than the previous, as it is an impoved version of it.


Help is a two way process. One cannot do anything for someone who just keep saying "No!", without hearing nor (trying to) understanding the other.
 
Status
Not open for further replies.
Top