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

[WIP]DummyCaster

Status
Not open for further replies.
JASS:
library DummyCaster/*1.0
*************************************************************************************
*
*   Creates dummy casters for casting spells
*
*   Spells must have 0 manacost. Cast Range and cooldown is not necessary.
*   Supports Channeling spells as well as locking dummy channels to units.
*   Channeling spells, however, cannot be cancelled forcefully.
*   Channeling dummies are locked to their owning unit's position
*
*************************************************************************************
*
*   */ uses/*
*        */ MissileRecycler /* hiveworkshop.com/forums/jass-resources-412/system-missilerecycler-206086/
*        */ UnitIndexerGUI /*  hiveworkshop.com/forums/jass-resources-412/snippet-gui-unit-indexer-vjass-plugin-268592/
*        */ Table/*            hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
*
*   Recommended
*       OrderIds
*
*************************************************************************************
*
*   API
*
*   static method U2P takes integer abil, integer level,  integer order, unit origin, real x, real y returns nothing
*   - Creates a dummy unit on origin's position, targeting point (x, y)
*   - If the dummy is channeling, it will be locked to its owning unit 
*
*   static method U2W takes integer abil, integer level, integer order, unit origin, widget target returns nothing
*   - Creates a dummy unit on origin's position, targeting widgets
*   - If the dummy is channeling ,it will be locked to its owning unit
*
*   static method P2P takes integer abil, integer level, integer order, player p_owner, real x, real y, real tx, real ty returns nothing
*   - Creates a dummy unit on point (x, y), targeting point (tx, ty)
*
*   static method P2W takes integer abil, integer level, integer order, player p_owner, real x, real y, widget target returns nothing
*   - Creates a dummy unit on point (x, y), targeting widget
*
*   static method PImmediate takes integer abil, integer level, integer order, player p_owner, real x, real y, real facing returns nothing
*   - Creates a dummy on point and issues immediate order
*
*   static method UImmediate takes integer abil, integer level, integer order, unit origin returns nothing
*   - Creates a dummy locked on unit origin, issued immediate order
*
**************************************************************************************
*
*   Credits
*       Bribe for all the used libs
*
*************************************************************************************/
    globals
        private constant real TIMEOUT = 0.031250000
        
        private player DUMMY_OWNER = Player(13)
        private Table tb
    endglobals
    
    
    //native UnitAlive takes unit id returns boolean
    
    private module Init
        private static method onInit takes nothing returns nothing
            call init()
        endmethod
    endmodule
    struct DummyCaster
        private unit u
        private unit owner
        private boolean caster
        
        private static constant timer t = CreateTimer()
        
        private static thistype array n
        private static thistype array p
        
        private static method period takes nothing returns nothing
            local thistype this = n[0]
            loop
                exitwhen this == 0
                if UnitAlive(owner) then
                    call SetUnitX(u, GetUnitX(owner))
                    call SetUnitY(u, GetUnitY(owner))
                endif
                set this = n[this]
            endloop
        endmethod
        
        private method insert takes nothing returns nothing
            set n[this] = 0
            set p[this] = p[0]
            set n[p[0]] = this
            set p[0] = this
            
            if p[this] == 0 then
                call TimerStart(t, TIMEOUT, true, function thistype.period)
            endif
        endmethod
        
        private static method new takes real x, real y, real z, real facing, player owner, integer abil, integer level returns thistype
            local thistype this = allocate()
            set u = GetRecycledMissile(x, y, z, facing)
            set tb[GetHandleId(u)] = this
            if abil > 0 then
                call UnitAddAbility(u, abil)
            endif
            if level < 1 then
                set level = 1
            endif
            call SetUnitAbilityLevel(u, abil, level)
            if owner == null then
                set owner = DUMMY_OWNER
            endif
            call SetUnitOwner(u, owner, false)
            set caster = true
            return this
        endmethod
        
        static method U2P takes integer abil, integer level,  integer order, unit origin, real x, real y returns nothing
            local real ox
            local real oy
            local thistype this
            if UnitAlive(origin) then
                set ox = GetUnitX(origin)
                set oy = GetUnitY(origin)
                set this = new(ox, oy, GetUnitFlyHeight(origin), Atan2(y - oy, x - ox)*bj_RADTODEG, GetOwningPlayer(origin), abil, level)
                call insert()
                set owner = origin
                call IssuePointOrderById(u, order, x, y)
            endif
        endmethod
        
        static method U2W takes integer abil, integer level, integer order, unit origin, widget target returns nothing
            local real ox
            local real oy
            local real tx
            local real ty
            local thistype this
            if UnitAlive(origin) then
                set ox = GetUnitX(origin)
                set oy = GetUnitY(origin)
                set this = new(ox, oy, GetUnitFlyHeight(origin), Atan2(GetWidgetY(target) - oy, GetWidgetX(target) - ox)*bj_RADTODEG, GetOwningPlayer(origin), abil, level)
                call insert()
                set owner = origin
                call IssueTargetOrderById(u, order, target)
            endif
        endmethod
        
        static method P2P takes integer abil, integer level, integer order, player p_owner, real x, real y, real tx, real ty returns nothing
            call IssuePointOrderById(new(x, y, 0, Atan2(ty - y, tx - x)*bj_RADTODEG, p_owner, abil, level).u, order, tx, ty)
        endmethod
        
        static method P2W takes integer abil, integer level, integer order, player p_owner, real x, real y, widget target returns nothing
            call IssueTargetOrderById(new(x, y, 0, Atan2(GetWidgetY(target) - y, GetWidgetX(target) - x)*bj_RADTODEG, p_owner, abil, level).u, order, target)
        endmethod

        static method PImmediate takes integer abil, integer level, integer order, player p_owner, real x, real y, real facing returns nothing
            call IssueImmediateOrderById(new(x, y, 0, facing, p_owner, abil, level).u, order)
        endmethod
        
        static method UImmediate takes integer abil, integer level, integer order, unit origin returns nothing
            local thistype this = new(GetUnitX(origin), GetUnitY(origin), GetUnitFlyHeight(origin), GetUnitFacing(origin), GetOwningPlayer(origin), abil, level)
            call IssueImmediateOrderById(u, order)
            call insert()
            set owner = origin
        endmethod
        
        private static method onFinish takes nothing returns boolean
            local unit dc = GetTriggerUnit()
            local thistype this = tb[GetHandleId(dc)]
            if caster then
                set n[p[this]] = n[this]
                set p[n[this]] = p[this]
                if n[0] == 0 then
                    call PauseTimer(t)
                endif
                call UnitRemoveAbility(dc, GetSpellAbilityId())
                call RecycleMissile(dc)
                set caster = false
            endif
            return false
        endmethod
        
        private static method init takes nothing returns nothing
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_ENDCAST, function thistype.onFinish)
        endmethod
        implement Init
    endstruct
endlibrary

Will be accepting suggestions for an expansive API

Current problem:
- Code not tested yet, due to it hitting OP Limit
 
Last edited:
BUMP!

Important news

Updated library, now has documentation, clean some code and updated to be compatible on new UnitIndexer feature.

Currently, my problem is that I can't test the system due to the fact that it hits OP Limit in an unknown reason(it should have not). even just executing one of the methods in the API will cause it to hit OP Limit(everything stops executing when t[GetHandleId(u)] is executed)

In this case I NEED HELP! SOMEONE PLEASE TEST THIS and/or HELP ME FIX MY OP LIMIT PROBLEM
 
Status
Not open for further replies.
Top