• 🏆 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!

Help with Luck Aura

Status
Not open for further replies.
This is the code taken from the link:

JASS:
scope LuckAura /*requires RegisterPlayerUnitEvent, Table, SpellEffectEvent*/

globals
    private Table lu //NEVER TOUCH THIS!
    private constant itemtype         ITEMID = ITEM_TYPE_ANY
    private constant real                AOE = 600 //Buff Effect or range, make sure that this matches the AOE of DUMMY_SPELL_ID
    private constant integer        SPELL_ID = 'A001' //Hero ability rawID
    private constant integer   DUMMY_SPELL_ID = 'A000' //Buff Aura rawID
    private constant integer        DUMMY_ID = 'h000' //Dummy Unit rawID
    private constant integer            BUFF = 'B000' //Buff Aura rawID     
endglobals

//===CONFIGURABLES:
private function GetDuration takes integer i returns real
    return 30. 
endfunction

private function GetChance takes integer i returns integer
    return 10 + i * 5
endfunction
//===END OF CONFIGURABLES

private function EnemyDies takes unit u, unit k returns nothing
    local unit first
    local integer level
    call GroupEnumUnitsInRange(bj_lastCreatedGroup,GetUnitX(k),GetUnitY(k),AOE,null)
    loop
        set first = FirstOfGroup(bj_lastCreatedGroup)
        exitwhen first==null
        if UnitAlive(first) and lu.has(GetHandleId(first)) then
            set level = lu[GetHandleId(first)]
            if GetRandomInt(1,100) <= GetChance(level) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
                if level==1 then
                    call CreateItem(ChooseRandomItemEx(ITEMID, 1), GetUnitX(u), GetUnitY(u))
                else
                    call CreateItem(ChooseRandomItemEx(ITEMID, GetRandomInt(1,level+1)), GetUnitX(u), GetUnitY(u))
                endif
            endif
        endif
        call GroupRemoveUnit(bj_lastCreatedGroup,first)
    endloop
endfunction

private function EnemyDiesCond takes nothing returns nothing
    if (GetUnitAbilityLevel(GetKillingUnit(), BUFF) > 0) and IsUnitEnemy(GetKillingUnit(),GetTriggerPlayer()) then 
        call EnemyDies(GetTriggerUnit(), GetKillingUnit())
    endif
endfunction

private struct Luck
    unit caster
    unit dummy
    real duration
   
    private static timer tim
    private static integer index = 0
    private static integer array indexAR 
    private static thistype DATA
   
    private static method looper takes nothing returns nothing
        local thistype this 
        local integer i = 0
        loop
            set i = i+1
            set this = indexAR[i]
            if .duration > 0 and UnitAlive(.caster) then
                set .duration = .duration - 0.5
                call SetUnitX(.dummy, GetUnitX(.caster))
                call SetUnitY(.dummy, GetUnitY(.caster))
            else
                call KillUnit(.dummy)
                call lu.remove(GetHandleId(.caster))
                set .caster = null
                set .dummy = null
                call .destroy()
                set indexAR[i] = indexAR[index]
                set indexAR[index] = this
                set i = i-1
                set index = index - 1
                if index==0 then
                    call PauseTimer(tim)
                    call DestroyTimer(tim)
                endif   
            endif           
            exitwhen i==index
        endloop
    endmethod
                                             
    private static method cast takes nothing returns nothing
        local thistype this
        local unit u = GetTriggerUnit()
        local timer t
        local integer timerID
        local integer casterID = GetHandleId(u)
        local integer level 
        local player p = GetTriggerPlayer()
        if not lu.has(casterID) then
            set this = allocate()
            set level = GetUnitAbilityLevel(u, SPELL_ID)
            set lu[casterID] = level
            set .caster = GetTriggerUnit()
            set .dummy = CreateUnit(p, DUMMY_ID, GetUnitX(u), GetUnitY(u), 0)           
            set .duration = GetDuration(level)
            if index==0 then
                set tim = CreateTimer()
                call TimerStart(tim, 0.5, true, function thistype.looper) 
            endif
            set index = index + 1
            set indexAR[index] = this
            call UnitAddAbility(dummy, DUMMY_SPELL_ID)
            call SetUnitAbilityLevel(dummy, DUMMY_SPELL_ID, level) 
        else
            call IssueImmediateOrder(u, "stop")
            static if LIBRARY_SimError then
                call SimError(p, "Can't be used yet!")
            endif
        endif
        set u = null
        set p = null
    endmethod
   
    private static method onInit takes nothing returns nothing
        call RegisterSpellEffectEvent(SPELL_ID, function thistype.cast)
        call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function EnemyDiesCond)
        set lu = Table.create()
    endmethod
endstruct

endscope

JASS-inizing Beam:

JASS:
// These variables have to created via the Variable Editor
globals
    hashtable udg_lu = null
    integer udg_LuckAura_ITEMID = ITEM_TYPE_ANY
    integer udg_LuckAura_SPELL_ID = 'A001' //Hero ability rawID
    integer udg_LuckAura_DUMMY_SPELL_ID = 'A000' //Buff Aura rawID
    integer udg_LuckAura_DUMMY_ID = 'h000' //Dummy Unit rawID
    integer udg_LuckAura_BUFF = 'B000' //Buff Aura rawID
    real udg_LuckAura_AOE = 600 //Buff Effect or range, make sure that this matches the AOE of DUMMY_SPELL_ID

    // JassHelper struct globals
    // Just kidding, these closely mimic them
    unit array udg_LuckAura_Luck_caster
    unit array udg_LuckAura_Luck_dummy
    real array udg_LuckAura_Luck_duration

    timer udg_LuckAura_Luck__tim = null
    integer udg_LuckAura_Luck__index = 0
    integer array udg_LuckAura_Luck_arr__indexAR
    integer udg_LuckAura_Luck__DATA = 0
endglobals

//===CONFIGURABLES:
function LuckAura__GetDuration takes integer i returns real
    return 30.
endfunction

function LuckAura__GetChance takes integer i returns integer
    return 10 + i * 5
endfunction
//===END OF CONFIGURABLES

function LuckAura__EnemyDies takes unit u, unit k returns nothing
    local unit first
    local integer level
    call GroupEnumUnitsInRange(bj_lastCreatedGroup,GetUnitX(k),GetUnitY(k),AOE,null)
    loop
        set first = FirstOfGroup(bj_lastCreatedGroup)
        exitwhen first==null
        if UnitAlive(first) and lu.has(GetHandleId(first)) then
            set level = LoadInteger(udg_lu, 0, GetHandleId(first))
            if GetRandomInt(1,100) <= LuckAura_GetChance(level) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
                if level==1 then
                    call CreateItem(ChooseRandomItemEx(udg_LuckAura_ITEMID, 1), GetUnitX(u), GetUnitY(u))
                else
                    call CreateItem(ChooseRandomItemEx(udg_LuckAura_ITEMIDITEMID, GetRandomInt(1,level+1)), GetUnitX(u), GetUnitY(u))
                endif
            endif
        endif
        call GroupRemoveUnit(bj_lastCreatedGroup,first)
    endloop
endfunction

function LuckAura_EnemyDiesCond takes nothing returns nothing
    local unit killer = GetKillingUnit()
    if (GetUnitAbilityLevel(killer, BUFF) > 0) and IsUnitEnemy(killer,GetTriggerPlayer()) then 
        call EnemyDies(GetTriggerUnit(), killer)
    endif
    set killer = null
endfunction

function LuckAura_Luck__looper takes nothing returns nothing
    local integer this 
    local integer i = 0
    loop
        set i = i+1
        set this = udg_LuckAura_Luck_arr__indexAR[i]
        if udg_LuckAura_Luck__duration[this] > 0 and UnitAlive(udg_LuckAura_Luck__caster[this]) then
            set udg_LuckAura_Luck__duration[this] > 0 = udg_LuckAura_Luck__duration[this] > 0 - 0.5
            call SetUnitX(udg_LuckAura_Luck__dummy[this], GetUnitX(udg_LuckAura_Luck__caster[this]))
            call SetUnitY(udg_LuckAura_Luck__dummy[this], GetUnitY(udg_LuckAura_Luck__caster[this]))
        else
            call KillUnit(udg_LuckAura_Luck__dummy[this])
            call RemoveSavedInteger(udg_lu, 0, GetHandleId(udg_LuckAura_Luck__caster[this]))
            set udg_LuckAura_Luck__caster[this] = null
            set udg_LuckAura_Luck__dummy[this] = null
            call LuckAura_Luck_gen__destroy(this)
            set indexAR[i] = indexAR[index]
            set indexAR[index] = this
            set i = i-1
            set index = index - 1
            if index==0 then
                call PauseTimer(tim)
            endif
        endif           
        exitwhen i==index
    endloop
endfunction
                                         
function LuckAura_Luck__cast takes nothing returns nothing
    local thistype this
    local unit u = GetTriggerUnit()
    local timer t
    local integer timerID
    local integer casterID = GetHandleId(u)
    local integer level 
    local player p = GetTriggerPlayer()
    if not HaveSavedInteger(udg_lu, 0, casterID) then
        set this = allocate()
        set level = GetUnitAbilityLevel(u, SPELL_ID)
        call SaveInteger(udg_lu, 0, casterID, level)
        set udg_LuckArray_Luck__caster[this] = GetTriggerUnit()
        set udg_LuckArray_Luck__dummy[this] = CreateUnit(p, DUMMY_ID, GetUnitX(u), GetUnitY(u), 0)           
        set udg_LuckArray_Luck__duration[this] = LuckAura__GetDuration(level)
        if index==0 then
            if udg_LuckAura_Luck__tim == null then
            set udg_LuckAura_Luck__tim = CreateTimer()
            endif
            call TimerStart(tim, 0.5, true, function LuckAura_Luck__looper) 
        endif
        set index = index + 1
        set indexAR[index] = this
        call UnitAddAbility(udg_LuckArray_Luck__dummy[this], DUMMY_SPELL_ID)
        call SetUnitAbilityLevel(udg_LuckArray_Luck__dummy[this], DUMMY_SPELL_ID, level) 
    else
        call IssueImmediateOrderById(u, 851972)
//#     static if LIBRARY_SimError then
//#         call SimError(p, "Can't be used yet!")
//#     else
            call DisplayTextToPlayer(p, 0, 0, "Can't be used yet!")
//#     endif
    endif
    set u = null
    set p = null
endfunction

function InitTrig_LuckAura takes nothing returns nothing
    set gg_trg_LuckAura = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_LuckAura, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_LuckAura, Condition(function LuckAura_EnemyDiesCond))
endfunction
 
Level 6
Joined
Aug 5, 2017
Messages
251
I did try inserting everything JASS-related: the dummy, the Luck Aura and its buff+another buff and the codes(Libraries+Luck Aura+Hashtable) and when I insert it into my map, I get errors about everything wrong with each code. When I mean every code, I mean EVERY one.
 
^^256 total ever made, at any given point in time.

I did try inserting everything JASS-related: the dummy, the Luck Aura and its buff+another buff and the codes(Libraries+Luck Aura+Hashtable) and when I insert it into my map, I get errors about everything wrong with each code. When I mean every code, I mean EVERY one.

Are you sure you copied everything, and only everything in the JASSified code, and that you're running the normal WorldEdit? The globals portion of the code has to be generated via Variable Editor in vanilla JASS but can be ignored in vJASS. Also, I forgot to initialize the hashtable with an InitHashtable() call (though I guess that you have already done the former, and the fix for the latter is setting udg_lu = InitHashtable() in the InitTrig_ function).

When copy-pasting the code, make a trigger called LuckAura and convert it to custom text.

I also forgot to declare UnitAlive in the Map Script portion of the Trigger Editor. To fix that, just declare the following function in the Map Script like this: native UnitAlive takes unit id returns boolean.

Also, I wrote that in NotePad, so that may have caused some issues to slip undetected.
 
Status
Not open for further replies.
Top