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

Disarmament v1.1

READ FIRST: Link


Introduction

There are some resources on hive which have a good idea, but are not implemented very good.
I want to re-create some of them from which I think are useful. I will mark the original author as co-author.
That's one of these resources.

Credits to ukn0wnD3str0y3r, from who's submission I have the idea.
The original implementation: www.hiveworkshop.com/threads/disarm-system-v1-0-4.260483/

Information

A snippet to temporary disable a unit's attack.

Triggers

Note:
The system is written in JASS, but it can be used easily with GUI. Test the map for a demonstration.

JASS:
library Disarmament  /* v1.1

    Information
    ¯¯¯¯¯¯¯¯¯¯¯

        A snippet to temporary disable a unit's attack.
        Also provides you a set and get function to have more managing powers.
        The system does not work with units which already have the cargo ability. See "Applied method".
 
        It's for JASS users, but it's also GUI compatible. See Config a few lines later.
 
 
    Applied method
    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
 
        The system will temporary add 'Abun' (orc-cargo) ability to a unit to disabled it's attack.
        Therefore it won't work for units which already have the 'Abun' ability by default.
 
 
    Credits:
    ¯¯¯¯¯¯¯¯
 
        Credits to ukn0wnD3str0y3r, from who's submission I have the idea.
        The original implementation: hiveworkshop.com/threads/disarm-system-v1-0-4.260483/
 
        Resources:
 
            - Bribe
            - Vexorian
 

*/ requires /*

        */ Table        /* hiveworkshop.com/threads/snippet-new-table.188084/
        */ TimerUtils   /* wc3c.net/showthread.php?t=101322
 

    struct Disarmament
 
 
        Usage:
            static method getDuration takes unit u returns real
            static method setDuration takes unit u, real duration returns boolean
 
                - negative duration means infinite, for both "set" and "get"
                - duration "0" means instant removal
                - "setDuration" won't do nothing and return "false" if the unit already has the cargo ability.
         
            static method isUnitDisarmed takes unit u returns boolean
 
 
        Code registration (will run when the time expires):
 
            static method register takes boolexpr be returns triggercondition
            static method unregister takes triggercondition t returns nothing
 
        readonly:
 
            unit
                (the unit to refer to in registarted code.
                  e.g.: call KillUnit(Disarmament.unit)
           
 
*/
//================= Config ======================//

    globals
        private constant boolean GUI    = true      // allows to work with the GUI variables
                                                    // look at "GUI Demo" folder for an example.
    endglobals

 
//=============== End  Config ======================//


    struct Disarmament extends array

        private static Table TABLE
        public static unit unit
        private static constant trigger t = CreateTrigger()
        private static constant integer DISARM_ID = 'Abun'
        private static constant group GROUP = CreateGroup()
        private static method callback takes nothing returns nothing
     
            local timer clock = GetExpiredTimer()
            local integer clockId = GetHandleId(clock)
            local unit u = thistype.TABLE.unit[clockId]
            local integer unitId = GetHandleId(u)
     
            call UnitRemoveAbility(u, DISARM_ID)
            call GroupRemoveUnit(GROUP, u)
            static if GUI then
                set udg_DA_Unit = u
                set udg_DA_Event = 1
                set udg_DA_Event = 0
            endif
            set thistype.unit = u
            call TriggerEvaluate(thistype.t)
     
            call thistype.TABLE.handle.remove(unitId)
            call thistype.TABLE.handle.remove(clockId)
            call ReleaseTimer(clock)
            set u = null
        endmethod
 
        static method getDuration takes unit u returns real
            if thistype.TABLE.timer.has(GetHandleId(u)) then
                // common return value
                return TimerGetRemaining(thistype.TABLE.timer[GetHandleId(u)])
            else
                // no timer exists, because the value is negative (infinite duration)
                return thistype.TABLE.real[GetHandleId(u)]
            endif
        endmethod
 
        static method setDuration takes unit u, real duration returns boolean
            local integer parentKey = GetHandleId(u)
            local timer clock = thistype.TABLE.timer[parentKey]
     
            if not (duration != 0) then
     
                if thistype.TABLE.real.has(parentKey) then
                    call thistype.TABLE.real.remove(parentKey)
                endif
         
                if (clock != null) then
                    call thistype.TABLE.handle.remove(parentKey)
                    call thistype.TABLE.handle.remove(GetHandleId(clock))
                    call ReleaseTimer(clock)
                endif
         
                if UnitAddAbility(u, DISARM_ID) or IsUnitInGroup(u, GROUP) then
                    call UnitRemoveAbility(u, DISARM_ID)
                    call GroupRemoveUnit(GROUP, u)
             
                    static if GUI then
                        set udg_DA_Unit = u
                        set udg_DA_Event = 1
                        set udg_DA_Event = 0
                    endif
                    set thistype.unit = u
                    call TriggerEvaluate(thistype.t)
                    return true
                else
         
                    // The system should not do anything if the unit already has cargo ability but is not even registered here.
             
                    debug call BJDebugMsg("[ERRROR] Disarmament: Units with cargo ability are not allowed to be registered.")
             
                    return false
                endif
         
            else
                if not UnitAddAbility(u, DISARM_ID) and not IsUnitInGroup(u, GROUP) then
             
                    // Else we would later remove the Disarm ability, even the unit already had it before it was registered.
             
                    debug call BJDebugMsg("[ERRROR] Disarmament: Units with cargo ability are not allowed to be registered.")
         
                    return false
                endif
            endif
 
            call GroupAddUnit(GROUP, u)
     
            if (duration > 0) then
         
                if (clock == null) then
                    set clock = NewTimer()
                    set thistype.TABLE.timer[parentKey] = clock
                    set thistype.TABLE.unit[GetHandleId(clock)] = u
                endif
         
                // In case it had a permanent flag before we need to remove the saved value
         
                if thistype.TABLE.real.has(parentKey) then
                    call thistype.TABLE.real.remove(parentKey)
                endif
         
                call TimerStart(clock, duration, false, function thistype.callback)
         
            else

        //      If a timer exists we don't need it at this point anymore
        //           (infinite duration)
 
                if (clock != null) then
                    call thistype.TABLE.handle.remove(parentKey)
                    call thistype.TABLE.handle.remove(GetHandleId(clock))
                    call ReleaseTimer(clock)
                endif
             
        //      instead, we just attach the duration to the unit
         
                set thistype.TABLE.real[parentKey] = duration
         
            endif
            return true
        endmethod
 
        static if GUI then
            private static method setData takes nothing returns nothing
                call setDuration(udg_DA_Unit, udg_DA_Duration)
                set udg_DA_IsUnitDisarmed = IsUnitInGroup(udg_DA_Unit, GROUP)
            endmethod
     
            private static method getData takes nothing returns nothing
                set udg_DA_Duration = getDuration(udg_DA_Unit)
                set udg_DA_IsUnitDisarmed = IsUnitInGroup(udg_DA_Unit, GROUP)
            endmethod
     
            private static method init takes nothing returns nothing
                set udg_DA_GetData = CreateTrigger()
                set udg_DA_SetData = CreateTrigger()
                call TriggerAddAction(udg_DA_GetData, function thistype.getData)
                call TriggerAddAction(udg_DA_SetData, function thistype.setData)
                call ReleaseTimer(GetExpiredTimer())
            endmethod
        endif
 
        private static method onInit takes nothing returns nothing
            static if GUI then
                call TimerStart(NewTimer(), 0, false, function thistype.init)
            endif
            set TABLE = Table.create()
        endmethod
 
        static method register takes boolexpr be returns triggercondition
            return TriggerAddCondition(thistype.t, be)
        endmethod
 
        static method unregister takes triggercondition tc returns nothing
            call TriggerRemoveCondition(thistype.t, tc)
        endmethod
 
        static method isUnitDisarmed takes unit u returns boolean
            return IsUnitInGroup(u, GROUP)
        endmethod
 
    endstruct
endlibrary


Code:
Infoormation:
¯¯¯¯¯¯¯¯¯¯

    A snippet to temporary disable a unit's attack.
    Also provides you a set and get function to have more managing powers.


Applied method
¯¯¯¯¯¯¯¯¯¯¯¯
    The system will temporary add 'Abun' (orc-cargo) ability to a unit to disabled it's attack.
    Therefore it won't work for units which already have the 'Abun' ability.


Import:
¯¯¯¯¯
    1. File -> Preferences -> Automaticlay create unknown variables
    2, Import the "Disarmament" folder into your map.


=========== Usage ==========


    1. Set "DA_Unit" variable, which is the unit you want to work with.
______________________________________________________________________

    2. After the unit is set you can run followingTriggers:

        Trigger - Run DA_GetData (ignoring conditions)
            after you tun this trigger "DA_Duration" will have the remaining duration for our unit.
            after you tun this trigger "DA_IsUnitDisarmed" tells us if the unit is currently disarmed.

        Trigger - Run DA_SetData (ignoring conditions)
            after you tun this trigger "DA_Duration" will be applied for our unit's remaining duration.
            after you tun this trigger "DA_IsUnitDisarmed" tells us if the unit is currently disarmed.

       Negative duration values implies an infinite duration for both triggers, GetData and SetData.
       "0" duration for "SetData" will instantly remove the disarmament.
______________________________________________________________________

    3. Event: Game - DA_Event becomes Equal to 1.00
 
            If this event runs it means that a duration expired and a unit will be able to attack again.
     
            use "DA_Unit" to refer here to the respective unit
_____________________________________________________________________

=========== Credits ==========

    Credits to ukn0wnD3str0y3r, from who's submission I have the idea.
    The original implementati

    Resources
        - Bribe
        - Vexorian
Contents

Disarmament v1.1 (Map)

Deleted member 219079

D

Deleted member 219079

All these gameplay tweaking snippets are nice additions to hive's collection!

In your onInit you create timer which you forgot to call ReleaseTimer() on afterwards: call TimerStart(NewTimer(), 0, false, function thistype.init).
 
Level 13
Joined
Nov 7, 2014
Messages
571
Have you thought about silencing the 'Aatk' ability in order to disable a unit's attack (you can see how this can be done from this amazing silence guide by leandrotp)? The 'Abun' (orc-cargo) ability seems to hide the attack button as well, which is fine I guess, but not as "cool" as actually seeing the attack ability getting silenced, also you can disable the attack for any unit which has the 'Aatk' ability.

PS: leandrotp's method also allows one to disable the 'Amov' ability (and almost any other ability?) ;P
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
Very useful system. It would be great if you can add the feature Aniki was talking about though! I also really like the GUI-friendly feature you added with it.

Needs Fixed

  • Nothing

Suggestions

  • JASS:
    if not (duration != 0) then
        // do stuff
    else
        if not UnitAddAbility(u, DISARM_ID) and not IsUnitInGroup(u, GROUP) then
            // debug message
            return false
        endif
    endif
    
    // >>
    
    if not (duration !=) then
        // do stuff
    elseif not UnitAddAbility(u_DISARM_ID) and not IsUnitInGroup(u, GROUP) then
        // debug message
        return false
    endif

Status

Approved
 
I finaly found time to read the silence tutorial, it's pure awesomeness.
Simply adding/removing in comparison though is, more straight forward.

I don't think it's worth for me to rewrite it now and use the silence method, specialisized for 'Aatk'.
It would be probably good though if, when leandrotp has continued his work, him or soemone else writes a full useable system with also mentionening exceptions and everything related.
 
Top