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

[JASS/AI] Hide "Hold, Patrol and Move" functional in any version of War 3 or Reforged.

Level 7
Joined
Mar 14, 2021
Messages
43
Mostly this is aimed at those who are still playing the non-reforged versions without memory hacks. Without using the X,Y glitch to hide icons with value -11.

Explanation:

This is thanks to the SilenceEx library that allows you to silence an ability, in this case 'Amov', whose requirement for it to be silenced is that its mana cost is different from 0 for it to work. (- Leantrop - SilenceEx - Everything you don't know about Silence.)

What you must do:

1) It's simple enough, it's adding the Root Ability to a unit, since by default this spell immediately silences the 'Amov' Ability to a unit as well as hiding its buttons, such as Move, Hold and Patrol; if in item editor you set Rooted Turning to true this makes the unit not move but can turn, same effect as the nerubian's Spell Web, but the 'Amov' ability will not be silenced.
1650338211006.png


2) Then with Silence Ex remove the silence put by Root on the unit and that's it, the unit can move with the attack button.

JASS:
private function SILENCE_TESTUNIT_AMOV takes nothing returns nothing
    call SetUnitAbilitySilenced(TestUnit,'Amov',false) //I return to the ability 'Amov' immune to silence
    call UnitAddAbility(TestUnit,'Aro1') //I add Root to hide 'Amov'
    call UnitRemoveAbility(TestUnit,'Aro1') //Let's remove Aro1 "Root" since we don't need it anymore.
endfunction

3) The Smart order won't work at all so another Canal type ability will be used, which its Base Order ID in the item editor will be (smart) "plus the Canal spell will have the Visible Option unchecked for it so this hidden", so with this and a code can be used in favor to handle the unit naturally. (This step and code is thanks to DioD who did the same but hiding all the command interface, but it had certain disadvantages, but thanks to him this detail was solved.)
(- DioD Demo Map - Full Command Cart)

JASS:
scope OrderSmartChannel initializer Init

globals
    private trigger MZ       = CreateTrigger()
    private trigger SZ       = CreateTrigger()
    constant integer SmartIDHide = 'A000'
 
    private constant string KeyStringCMD = "Key_StringCMD"
endglobals

private struct AuxiliarDataUnit
    unit u = null
    unit t = null
    item itm = null
    destructable des = null
    real x = 0
    real y = 0
endstruct

//Code By DioD
private function FCC_Order2 takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local AuxiliarDataUnit d = GetHandleInt(GetHandleId(t), KeyStringCMD)
 
    if d.des != null then
        call IssueTargetOrder(d.u,"smart",d.des)
    elseif d.itm != null then
        call IssueTargetOrder(d.u,"smart",d.itm)
    elseif d.t != null then
        if IsUnitAlly(d.t,GetOwningPlayer(d.u)) then
            call IssueTargetOrder(d.u,"smart",d.t)
        else
            call IssueTargetOrder(d.u,"attack",d.t)
        endif
    else
    endif
 
    call DecUnitAbilityLevel(d.u,SmartIDHide)
 
    call RemoveInt(GetHandleId(t), KeyStringCMD)
    call RemoveBoolean(GetHandleId(d.u), KeyStringCMD)
    call DestroyTimer(t)
    call d.destroy()
    set t = null
endfunction

//Code By DioD
private function FCC_MAIN2 takes nothing returns nothing
    local AuxiliarDataUnit d = 0
    local timer t = null
    if GetIssuedOrderId() != OrderId("smart") then
        return
    elseif GetUnitAbilityLevel(GetTriggerUnit(),SmartIDHide) <= 0 or GetHandleBoolean(GetHandleId(GetTriggerUnit()), KeyStringCMD) then
        return
    endif
 
    set d = AuxiliarDataUnit.create()
    set d.u = GetTriggerUnit()
    set d.t = GetOrderTargetUnit()
    set d.itm = GetOrderTargetItem()
    set d.des = GetOrderTargetDestructable()
    set d.x = GetOrderPointX()
    set d.y = GetOrderPointY()
 
    call SetHandleBoolean(GetHandleId(d.u), KeyStringCMD, true)
 
    if d.des != null then
    elseif d.itm != null then
    elseif d.t != null then
    else
        call IssuePointOrder(d.u,"smart",d.x,d.y)
    endif
 
    call IncUnitAbilityLevel(d.u,SmartIDHide)

    set t = CreateTimer()
    call SetHandleInt(GetHandleId(t), KeyStringCMD, d)
    call TimerStart(t, 0, false, function FCC_Order2)
    set t = null
endfunction

private function StopChannelPoint takes nothing returns nothing
    if GetSpellAbilityId() == SmartIDHide then
        call IssueImmediateOrder(GetTriggerUnit(),"stop")
    endif
endfunction

private function SILENCE_TESTUNIT_AMOV takes nothing returns nothing
    call SetUnitAbilitySilenced(gg_unit_Hpal_0006,'Amov',false)//I return to the ability 'Amov' immune to silence
    call UnitAddAbility(gg_unit_Hpal_0006,SmartIDHide)//Added the channel skill with the "smart" order
    call UnitMakeAbilityPermanent(gg_unit_Hpal_0006,true,SmartIDHide)//The permanent ability to not be removed by a morph
    call SetUnitAbilitySilenced(gg_unit_Hpal_0006,SmartIDHide,true) // Here the Channel spell cannot be silenced and it will also have the Universal Spell option
    call UnitAddAbility(gg_unit_Hpal_0006,'Aro1') //I add Root to hide 'Amov'
    call UnitRemoveAbility(gg_unit_Hpal_0006,'Aro1') //Let's remove Aro1 "Root" since we don't need it anymore.
endfunction

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
private function Init takes nothing returns nothing
    call TriggerRegisterAnyUnitEventBJ( MZ, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
    call TriggerRegisterAnyUnitEventBJ( MZ, EVENT_PLAYER_UNIT_ISSUED_ORDER )
    call TriggerRegisterAnyUnitEventBJ( MZ, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
    call TriggerAddAction( MZ, function FCC_MAIN2 )
 
    call TriggerRegisterAnyUnitEventBJ( SZ, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddAction( SZ, function StopChannelPoint )
 
    call SILENCE_TESTUNIT_AMOV.execute()
endfunction

endscope

Note: Using the Channel ability with the command (smart), works fine only that clicking spam on an enemy will stop it for a while, similar to when Spamming the Attack button (very similar to the dota style that is use to farm or deny creeps lol). (I haven't found a solution for this yet but it's something for all versions of warcraft 3).

Credits to Leantrop for Silence Ex and DioD for the use of the Smart Spell Channel control.
1650340533080.png

Attached It will be a map with what is exposed here.
 

Attachments

  • Three_free_button_slots.w3x
    75 KB · Views: 41
Last edited:
Top