1. Melee Mapping contest #3 - Poll is up! Vote for the best 4v4 melee maps!
    Dismiss Notice
  2. The 30th edition of the Modeling Contest is finally up! The Portable Buildings need your attention, so come along and have a blast!
    Dismiss Notice
  3. We have a new contest going on right now! Join the 11th Music Contest! You are to make a Cinematic modern sound-track for this contest, so come and compete with other people for fun.
    Dismiss Notice

[vJASS] DisableAutocast

Discussion in 'Submissions' started by busterkomo, Jan 4, 2019.

  1. busterkomo

    busterkomo

    Joined:
    Jun 17, 2007
    Messages:
    1,420
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    Sometimes it can be useful to disable the auto-casting of certain abilities. For example, you may have a custom Searing Arrows ability that has a cooldown. Unfortunately, the auto-casting of it does not properly trigger the cooldown (and I believe has other issues relating to things like range). I haven't written vJASS in ~8 years, so maybe my approach is terrible or outdated, but it seems fine to me.

    This API is simple:
    Code (vJASS):
    function DisableAutocast takes integer activateOrder, integer deactivateOrder returns nothing

    where 'activateOrder' is the order id to enable auto-casting, and 'deactivateOrder' is the order to turn it off. For example,
    Code (vJASS):
    call DisableAutocast(852067, 852068)
     
    prevents Inner Fire from being autocast.


    Code (vJASS):

    library DisableAutocast initializer Init requires TimerUtils, Table

    globals
        private Table table
    endglobals

    private struct DisableData
        unit u
        integer deactivateOrder

        static method create takes unit u, integer deactivateOrder returns DisableData
            local DisableData this = DisableData.allocate()

            set this.u = u
            set this.deactivateOrder = deactivateOrder

            return this
        endmethod
    endstruct

    private function Callback takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local DisableData d = GetTimerData(t)
        call IssueImmediateOrderById(d.u, d.deactivateOrder)
        call ReleaseTimer(t)
        call d.destroy()

        set t = null
    endfunction

    private function Actions takes nothing returns nothing
        local timer t
        local DisableData d
        local integer orderId = GetIssuedOrderId()

        if table.exists(orderId) then
            set t = NewTimer()
            set d = DisableData.create(GetTriggerUnit(), table[orderId])
            call SetTimerData(t, d)
            call TimerStart(t, 0., false, function Callback)
            set t = null
        endif
    endfunction

    function DisableAutocast takes integer activateOrder, integer deactivateOrder returns nothing
        set table[activateOrder] = deactivateOrder
    endfunction

    public function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_ORDER)
        call TriggerAddAction(t, function Actions)
        set table = Table.create()
    endfunction

    endlibrary
     
     
  2. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,268
    Resources:
    0
    Resources:
    0
    You should include some documentation, especially some information and links about the required libraries, even if they are common ones in this case.
    The table library you are using is outdated. You should use this one: [Snippet] New Table
    It has a backwards compatibility snippet, but for new resources one should use the new table.

    It would be nice to be able to use order strings as well. You could follow the JASS naming convention for orders and have DisableAutocast and DisableAutocastById.


    There are 2 side effects when you use this. The unit is being stopped and all its orders are canceled. Usually toggling autocast is instant and does not interrupt orders.
    Other currently active autocast effects are turned off.

    Does this have use outside of arrow abilities? Other autocast abilities can usually be emulated by using some non-autocast ability and a dummy ability to apply the effect.

    Arrow abilities allow you to attack from further away, if you cast them manually and cast range is greater than the attack range of the unit.