Resource Preloader

Scripts

9 years
edited 8 years
Useful snippet for preloading your map resources and avoiding duplicates in preloading.

Code (jass) Select
library ResourcePreloader /*v1.4


    */uses /*

    */BJObjectId            /* https://wc3modding.info/5038/bjobjectid/
    */optional Table        /* https://wc3modding.info/4611/snippet-new-table/
    */optional UnitRecycler /* https://wc3modding.info/5426/unitrecycler/

    *///! novjass

    |================|
    | Written by AGD |
    |================|

        [CREDITS]
/*          IcemanBo - for suggesting further improvements
            Silvenon - for the sound preloading method                            */


        |-----|
        | API |
        |-----|

            function PreloadUnit takes integer rawcode returns nothing/*
                - Assigns a certain type of unit to be preloaded

          */function PreloadItem takes integer rawcode returns nothing/*
                - Assigns a certain type of item to be preloaded

          */function PreloadAbility takes integer rawcode returns nothing/*
                - Assigns a certain type of ability to be preloaded

          */function PreloadEffect takes string modelPath returns nothing/*
                - Assigns a certain type of effect to be preloaded

          */function PreloadSound takes string soundPath returns nothing/*
                - Assigns a certain type of sound to be preloaded


          */function PreloadUnitEx takes integer start, integer end returns nothing/*
                - Assigns a range of unit rawcodes to be preloaded

          */function PreloadItemEx takes integer start, integer end returns nothing/*
                - Assigns a range of item rawcodes to be preloaded

          */function PreloadAbilityEx takes integer start, integer end returns nothing/*
                - Assigns a range of ability rawcodes to be preloaded


    *///! endnovjass

    //========================================================================================================//
    /* Do not try to change below this line if you're not so sure on what you're doing. Unless you want to
       change, check, or study the core of the system, it is not advised that you scroll any further.         */
    //========================================================================================================//

    private keyword S


    static if DEBUG_MODE then
        private function Debug takes string msg returns nothing
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "|CFFFFCC00[Resource Preloader]|R  " + msg)
        endfunction
    endif

    //============================================== TextMacros ==============================================//

    //! textmacro ASSIGN takes NAME, ARG, TYPE, INDEX, I
    function Preload$NAME$ takes $ARG$ what returns nothing
        static if LIBRARY_Table then
            if not S.tb[$I$].boolean[$INDEX$] then
                set S.tb[$I$].boolean[$INDEX$] = true
                call Do$NAME$Preload(what)
            debug else
                debug call Debug("|CFFFF0000Operation Cancelled :|R Entered $TYPE$ data was already preloaded")
            endif
        else
            if not LoadBoolean(S.tb, $I$, $INDEX$) then
                call SaveBoolean(S.tb, $I$, $INDEX$, true)
                call Do$NAME$Preload(what)
            debug else
                debug call Debug("|CFFFF0000Operation Cancelled :|R Entered $TYPE$ data was already preloaded")
            endif
        endif
    endfunction
    //! endtextmacro

    //! textmacro ASSIGNWITHRANGE takes NAME
    function Preload$NAME$Ex takes integer start, integer end returns nothing
        local BJObjectId this = BJObjectId(start)
        local BJObjectId last = BJObjectId(end)
        loop
            call Preload$NAME$(this)
            exitwhen this == last
            if this > last then
                set this = this.minus_1()
            else
                set this = this.plus_1()
            endif
        endloop
    endfunction
    //! endtextmacro

    //========================================================================================================//


    private function DoUnitPreload takes integer id returns nothing
        static if LIBRARY_UnitRecycler then
            call RecycleUnitEx(CreateUnit(Player(15), id, 0, 0, 0))
        else
            call RemoveUnit(CreateUnit(Player(15), id, 0, 0, 0))
        endif
    endfunction

    private function DoItemPreload takes integer id returns nothing
        call RemoveItem(UnitAddItemById(S.dummy, id))
    endfunction

    private function DoAbilityPreload takes integer id returns nothing
        if UnitAddAbility(S.dummy, id) and UnitRemoveAbility(S.dummy, id) then
        endif
    endfunction

    private function DoEffectPreload takes string path returns nothing
        call DestroyEffect(AddSpecialEffectTarget(path, S.dummy, "origin"))
    endfunction

    private function DoSoundPreload takes string path returns nothing
        local sound s = CreateSound(path, false, false, false, 10, 10, "")
        call SetSoundVolume(s, 0)
        call StartSound(s)
        call KillSoundWhenDone(s)
        set s = null
    endfunction

    //! runtextmacro ASSIGN("Unit", "integer", "unit", "what", "0")
    //! runtextmacro ASSIGN("Item", "integer", "item", "what", "1")
    //! runtextmacro ASSIGN("Ability", "integer", "ability", "what", "2")
    //! runtextmacro ASSIGN("Effect", "string", "effect", "StringHash(what)", "3")
    //! runtextmacro ASSIGN("Sound", "string", "sound", "StringHash(what)", "4")

    //! runtextmacro ASSIGNWITHRANGE("Unit")
    //! runtextmacro ASSIGNWITHRANGE("Item")
    //! runtextmacro ASSIGNWITHRANGE("Ability")

    //========================================================================================================//

    private module Init
        private static method onInit takes nothing returns nothing
            local rect bounds = GetWorldBounds()
            static if LIBRARY_Table then
                set tb = TableArray[5]
            endif
            set dummy = CreateUnit(Player(15), 'hpea', 0, 0, 0)
            call UnitAddAbility(dummy, 'AInv')
            call UnitAddAbility(dummy, 'Avul')
            call UnitRemoveAbility(dummy, 'Amov')
            call SetUnitY(dummy, GetRectMaxY(bounds) + 1000)
            call RemoveRect(bounds)
            set bounds = null
        endmethod
    endmodule

    private struct S extends array
        static if LIBRARY_Table then
            static TableArray tb
        else
            static hashtable tb = InitHashtable()
        endif
        static unit dummy
        implement Init
    endstruct


endlibrary
9 years
UPDATED


- Made Table optional
- Added UnitRecycler as an optional requirement
- Upon calling PreloadUnit(), if the unit is not a hero and UnitRecycler is found, the unit will be added to the unit stock instead. Otherwise, it goes with normal preloading.
- dummy unit's movement is disabled to prevent possible game crash.
- You can now preload at any time during the game instead of only during the map initialization
- Significantly optimized the code
- Removed the unnecessary custom function for checking preload duplicates
- Added Table to the library requirements
- Preloading does not anymore happen in a single phase at the GUI Map Initialization
- Resources are now preloaded at the instant you call the preload function
- Other changes