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

Vercas Ability System Question.

Level 7
Joined
Nov 6, 2019
Messages
186
So, i decided to try add Vercas Ability System to my map, however the abilities are not perm when u use a transformation spell

the book disappeared and if u set the book up to re add when u transform, the abilities in it disappear, any help?


JASS:
//TESH.scrollpos=1
//TESH.alwaysfold=0
/***************************************************************************************************\
|                                        Abilities System                                           |
|                                          by Vercas                                                |
|                                                                                                   |
|                                   Requires: - Table                                               |
|                                               by Vexorian                                         |
|                                                                                                   |
|        I made this system for my map, for making managing abilities easier but I thought other    |
|   people could use it as well so I uploaded it!                                                   |
|                                                                                                   |
|        Since version 2.01.a1, it has been completly rewritten and now the only reason to lag is...|
|   ABILITIES PRELOADING!!!                                                                         |
|   You know, the crappy Warcraft 3 engine lags the first time it sees an ability on an unit...     |
|   So do not complain for the lag, I will fix it later!                                            |
|                                                                                                   |
|   I've kept the old documentation trigger if you have any questions...                            |
|                                                                                                   |
|                                                                                                   |
|   Application Programming Interface (API) :                                                       |
|                                                                                                   |
|       AddAbil( item ID, ability ID, boolean) -> nothing                                           |
|           This adds an item to the system;                                                        |
|               Assigns an ability to an item! If the boolean is true, the ability is given when    |
|           the item is picked up, else when it's used.                                             |
\***************************************************************************************************/
/**/library AbilitiesSystem initializer Init requires Table/***************************************/
   
    globals
       
        private constant integer SB_ABILITY = 'A0CZ' // The ID of your main Spellbook. Please check the Object Editor for the ability.
   
        private Table ItemAbility // Fastest way to get the ability assigned to an item
        private Table ItemUsed    // 0 is true ; anything else is false... Pretty useless...
        private Table AbilityItem // To be used later for backwards compatibility
       
    endglobals
   
    function AddAbil takes integer it, integer abil, boolean c returns nothing
       
        local integer i      = 0
   
        set it:ItemAbility   = abil
       
        if c then
       
            set it:ItemUsed  = 0
           
        else
       
            set it:ItemUsed  = 1
           
        endif
       
        set abil:AbilityItem = it
       
        loop
           
            call SetPlayerAbilityAvailable( Player( i ), abil, false )
           
            set i = i + 1
            exitwhen i >= 16
           
        endloop
       
    endfunction
   
    private function Action takes nothing returns nothing
       
        local integer i = GetItemTypeId( GetManipulatedItem( ) )
        call RemoveItem( GetManipulatedItem( ) )
        call UnitAddAbility( GetTriggerUnit( ) , i:ItemAbility )
        call UnitMakeAbilityPermanent(GetTriggerUnit(), true, i:ItemAbility)
   
    endfunction
   
    private function Cond1 takes nothing returns boolean
   
        local integer i = GetItemTypeId( GetManipulatedItem( ) )
        return i:ItemAbility != 0 and i:ItemUsed == 0
       
    endfunction
   
    private function Cond2 takes nothing returns boolean
   
        local integer i = GetItemTypeId( GetManipulatedItem( ) )
        return i:ItemAbility != 0 and i:ItemUsed != 0
       
    endfunction
   
    private function Cond takes nothing returns boolean
   
        return GetUnitAbilityLevel( GetFilterUnit(), SB_ABILITY ) > 0
       
    endfunction
   
    private function Init takes nothing returns nothing
   
        local trigger t  = CreateTrigger       ( )
        local trigger t2 = CreateTrigger       ( )
       
        local boolexpr BX= Condition           ( function Cond )
       
        local integer i  = 0
       
        set ItemAbility  = Table.create        ( )
        set ItemUsed     = Table.create        ( )
        set AbilityItem  = Table.create        ( )
       
        loop
       
            call TriggerRegisterPlayerUnitEvent( t , Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, BX )
            call TriggerRegisterPlayerUnitEvent( t2, Player(i), EVENT_PLAYER_UNIT_USE_ITEM   , BX )
           
            set i = i + 1
            exitwhen i >= 16
           
        endloop
       
        call TriggerAddCondition               ( t , Condition( function Cond1 ) )
        call TriggerAddCondition               ( t2, Condition( function Cond2 ) )
       
        call TriggerAddAction                  ( t , function Action )
        call TriggerAddAction                  ( t2, function Action )
       
    endfunction
   
endlibrary

  • SetAbilitys
    • Events
      • Time - Elapsed game time is 0.01 seconds
    • Conditions
    • Actions
      • -------- Weapon Skills --------
      • -------- Active Skills --------
      • -------- Hide --------
      • Custom script: call AddAbil( 'I07Y', 'A0D2', true )
      • -------- Passive Skills --------
  • StartSkills
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 7, do (Actions)
        • Loop - Actions
          • Set VariableSet SBS = (Player((Player number of (Player((Integer A))))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (SBS controller) Equal to User
              • (SBS slot status) Equal to Is playing
            • Then - Actions
              • Unit - Add |cffffff80Book|r of Skills to SetHeroGS[(Player number of (Player((Integer A))))]
              • Hero - Create Hide (SBA) and give it to SetHeroGS[(Player number of (Player((Integer A))))]
            • Else - Actions

  • Skill Aquire
    • Events
      • Unit - A unit Acquires an item
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Item-type of (Item being manipulated)) Equal to Hide (SBA)
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SBAHide[(Player number of (Owner of (Hero manipulating item)))] Equal to 0
            • Then - Actions
              • Set VariableSet SBAHide[(Player number of (Owner of (Hero manipulating item)))] = 1
            • Else - Actions
        • Else - Actions
JASS:
//TESH.scrollpos=74
//TESH.alwaysfold=0
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//*   set t=Table.create() - instanceates a new table object
//*   call t.destroy()     - destroys it
//*   t[1234567]           - Get value for key 1234567
//*                          (zero if not assigned previously)
//*   set t[12341]=32      - Assigning it.
//*   call t.flush(12341)  - Flushes the stored value, so it
//*                          doesn't use any more memory
//*   t.exists(32)         - Was key 32 assigned? Notice
//*                          that flush() unassigns values.
//*   call t.reset()       - Flushes the whole contents of the
//*                          Table.
//*
//*   call t.destroy()     - Does reset() and also recycles the id.
//*
//*   If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//*  You can use Table on structs' onInit  if the struct is
//* placed in a library that requires Table or outside a library.
//*
//*  You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//*  set Table["thisstring"][ 7 ] = 2
//*  set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************

//=============================================================
    globals
        private constant integer MAX_INSTANCES=8100 //400000
        //Feel free to change max instances if necessary, it will only affect allocation
        //speed which shouldn't matter that much.

    //=========================================================
        private hashtable ht
    endglobals

    private struct GTable[MAX_INSTANCES]

        method reset takes nothing returns nothing
            call FlushChildHashtable(ht, integer(this) )
        endmethod

        private method onDestroy takes nothing returns nothing
            call this.reset()
        endmethod

        //=============================================================
        // initialize it all.
        //
        private static method onInit takes nothing returns nothing
            set ht = InitHashtable()
        endmethod

    endstruct

    //Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
    //! textmacro Table__make takes name, type, key
    struct $name$ extends GTable

        method operator [] takes $type$ key returns integer
            return LoadInteger(ht, integer(this), $key$)
        endmethod

        method operator []= takes $type$ key, integer value returns nothing
            call SaveInteger(ht,  integer(this)  ,$key$, value)
        endmethod

        method flush takes $type$ key returns nothing
            call RemoveSavedInteger(ht, integer(this), $key$)
        endmethod

        method exists takes $type$ key returns boolean
            return HaveSavedInteger( ht,  integer(this)  ,$key$)
        endmethod

        static method flush2D takes string firstkey returns nothing
            call $name$(- StringHash(firstkey)).reset()
        endmethod

        static method operator [] takes string firstkey returns $name$
            return $name$(- StringHash(firstkey) )
        endmethod

    endstruct
    //! endtextmacro

    //! runtextmacro Table__make("Table","integer","key" )
    //! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
    //! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )

endlibrary

image_2024-03-27_025409011.png
1711508064355.png
1711508080987.png


and then after transform

1711508108692.png
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,543
Make them all permanent after adding them.
 
Level 7
Joined
Nov 6, 2019
Messages
186
Make them all permanent after adding them.
doing that made the book perm, but the spell books inside the book and the hide ability disappeared, setting it to make the 3 books inside the book as perm, the books all show but the hide ability doesn't.
 
Last edited:
Level 7
Joined
Nov 6, 2019
Messages
186
  • StartSkills
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 7, do (Actions)
        • Loop - Actions
          • Set VariableSet SBS = (Player((Player number of (Player((Integer A))))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (SBS controller) Equal to User
              • (SBS slot status) Equal to Is playing
            • Then - Actions
              • Set VariableSet SBUnit = SetHeroGS[(Integer A)]
              • Unit - Add |cffffff80Book|r of Skills to SetHeroGS[(Player number of (Player((Integer A))))]
              • Custom script: call UnitMakeAbilityPermanent(udg_SBUnit, true, 'A0CZ')
              • Custom script: call UnitMakeAbilityPermanent(udg_SBUnit, true, 'A0CY')
              • Custom script: call UnitMakeAbilityPermanent(udg_SBUnit, true, 'A0CX')
              • Custom script: call UnitMakeAbilityPermanent(udg_SBUnit, true, 'A0CW')
              • Hero - Create Hide (SBA) and give it to SetHeroGS[(Player number of (Player((Integer A))))]
              • Custom script: call UnitMakeAbilityPermanent(udg_SBUnit, true, 'A0D2')
            • Else - Actions
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,543
Not sure then, if you can't get that to work then you need to either avoid using Morph spells entirely (you can trigger something similar with Skins) or use an alternative ability system that doesn't rely on Spellbooks.

For example one idea for a system that comes to mind:

1) Hide the Patrol/Move abilities off of the command card since these aren't really necessary.

2) Give the unit some permanent abilities that are hidden from the command card with easy to use hotkeys. These will act like your Spellbooks. You could use OSKeys as an alternative to allow custom hotkeys and not need these abilities.

3) Add all of the abilities that are currently in your Spellbooks to the unit by default but disable and hide them.

4) Manage the enabling/showing of these abilities based on whichever "Spellbook" you've opened (again, we've gotten rid of Spellbooks but we're mimicking their behavior with new hidden abilities or OSKeys).

So for example, when you press the Z hotkey, any "learned" abilities from range 1 to 8 are enabled/shown. When you press the X hotkey, those 8 are hidden and the abilities from range 9 to 17 are shown. Etc...

It wouldn't be too difficult to set this up with some Arrays and a Hashtable.
 
Level 7
Joined
Nov 6, 2019
Messages
186
ok seems i got the ability to perm and didnt know u could hide the move and patrol buttons, now how do i hide the Move/Patrol from command card?
 
Last edited:

Remixer

Map Reviewer
Level 31
Joined
Feb 19, 2011
Messages
1,957
ok seems i got the ability to perm and didnt know u could hide the move and patrol buttons, now how do i hide the Move/Patrol from command card?
If my memory serves me right you are able to hide/show abilities also from within spellbooks. If not directly, then through another spellbook with the said ability in question.

To hide Move or Patrol you need to use the native BlzUnitHideAbility() function on them - their raw reference code is 'Amov'.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,543
To hide Move or Patrol and any of the other "default command buttons" you need to import a custom CommandFunc.txt file. I attached one you can use that has Move/Patrol already hidden.

To further edit it, just open the text file in Notepad or any text editing program. Then all you have to do is change a button's X,Y positions to 0,-11 to make it hidden. You can reposition the buttons anywhere you'd like, it uses the same pattern that the buttons use in the Object Editor. For example you could change Move's Y position to 2 and it'll be placed on the bottom row instead of the top row.

IMPORTANT:
The final step is to change the import name of the file: Units\CommandFunc.txt
 

Attachments

  • CommandFunc.txt
    1.1 KB · Views: 2
Last edited:
Level 7
Joined
Nov 6, 2019
Messages
186
To hide Move or Patrol and any of the other "default command buttons" you import a custom CommandFunc.txt file. I attached one you can use that has Move/Patrol already hidden.

To further edit it, just open the text file in Notepad or any text editing program. Then all you have to do is change a button's X,Y positions to 0,-11 to make it hidden. You can also reposition to anywhere you'd like for further customization. It uses the same pattern that the buttons use in the Object Editor. For example you could change Move's Y position to 2 and it'll be placed on the bottom row instead of the top row.

IMPORTANT:
The final step is to change the import name of the file: Units\CommandFunc.txt

Nice Ty got that working, i do have another question, i have passives u get depending what area you are in, so you enter west get a buff, if u leave the west you loose the buff

so i set it up to add to spellbook when entering and remove when exiting, and it removes exiting but then you no longer get the buff back going back into the west

any idea of that issue?, it not super important but be better than covering command card

now without adding to book and just to command card never had a issue, so can go back to that if there's no fix

EDIT: Think i fixed it, seems to work.
 
Last edited:
Top