• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Snippet] [Needs work] Get Learned Abilities

Level 31
Joined
Jul 10, 2007
Messages
6,306
Not necessarily order learned. Just think of it like an ability array on the unit and index accesses that array. Count gets the count of that array.

edit
Sadly, this isn't useful for save/load ; P.


I actually made it for my custom xp script thingie as part of the fix to fix levels (UnitStripHeroLevel).
 
Last edited:
Well, how about this:

JASS:
private function Ability takes nothing returns boolean
        local integer i = GetUnitUserData(GetTriggerUnit())
        if (not Table(marked[i]).boolean.has(GetLearnedSkill())) then
            set Table(abils[i])[c[i]]=GetLearnedSkill()
            set Table(marked[i]).boolean[GetLearnedSkill()]=true
            set c[i]=c[i]+1
        endif
        return false
    endfunction

->

JASS:
    private function Ability takes nothing returns boolean
        local integer i = GetUnitUserData(GetTriggerUnit())
        local integer a = GetLearnedSkill()
        if (not Table(marked[i]).boolean.has(a)) then
            set Table(abils[i])[c[i]]=a
            set Table(marked[i]).boolean[a]=true
            set c[i]=c[i]+1
        endif
        return false
    endfunction

After all, it returns an integer, so creating a local here would be ok :)
 
Ok, so suppose you are using Libram with hero abilities, and so you could have multiple layers of different hero abilities (of course you'd learn them along the way and some paradigms will display 0 abilities until you learn them)... will this still work?

Also, you still don't need the typecasting for the Tables, since they are already typecasted as Tables when you load them.
 
Well it looks like you deallocate the learned ability if the ability was removed from the hero when you do the "count" method, and it would return 0 even for abilities that are potentially there just temporarily "removed" by Libram. I don't really see the point in checking if the ability was removed... I'm sure you have a reason though. Care to elaborate?
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
If a hero lost some levels or an ability was removed with UnitRemoveAbility >.>.

If Libram removes abilities, then yea, it'll return 0. The way to fix it is by hooking UnitAddAbility and UnitRemoveAbility, but that's a bit of overhead. This is only supposed to be for wc3 regular abilities, heh.


I could have a boolean option for hooking though ; )
 
I think Libram could use an update. I'll get around to it later on and try to make it compatible if it isn't already. Libram won't remove abilities aside from passives (unless you explicitly tell it to do so), it just disables them, so there shouldn't be a problem there as far as I know. (GetUnitAbilityLevel() will still != 0) But I will need to test it out for passives, ofc, since they are removed. :p

It actually should work fine with most learned abilities, but I haven't tested it yet. I'll test it sometime this weekend or something.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
You could still elimate all the "Table()" typecasting and this needs a better description how to use it and why to use it.

Eh, no real need to remove the table typecasting. It's just extra work for me with no benefit ; P.

why to use it

I'm not going to write something on that. You use it when you have a need for it, end of story -.-. I wrote it because I ended up having a need for it.

how to use it

I'll add that it's an indexed array of abilities ; )
 
Then your resource suffers obscurity. I can't really think of a reason for it other than the reason you already supported for your other resource, and with that in mind I feel it better to just inline it directly into that other resource. I know how much you hate to couple resources but I feel without any real purpose of this system aside from that one other library it kind of doesn't belong on its own. I think it was troll-brain who said "Cool!=Useful" and I agree with that here --

  1. Get learned abilities
  2. ???
  3. Profit!! (but what kind of profit?)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Then your resource suffers obscurity. I can't really think of a reason for it other than the reason you already supported for your other resource, and with that in mind I feel it better to just inline it directly into that other resource. I know how much you hate to couple resources but I feel without any real purpose of this system aside from that one other library it kind of doesn't belong on its own. I think it was troll-brain who said "Cool!=Useful" and I agree with that here --

You know that almost no matter what, I refuse to couple. I will never couple 2 resources together for modularity purposes ; ).


And obviously gy'ing this will require gy'ing Hero Reward, which is an extremely useful lib.
 
  1. Get learned abilities
  2. ???
  3. Profit!! (but what kind of profit?)

Works for me
TrollFace.png


I guess one way to save this resource is by making another one that requires it. (lol)
 
This version has the updates I have been looking for:

JASS:
library GetLearnedAbilities /* v1.1.0.0
*************************************************************************************
*
*   Allows one to retrieve all currently learned abilities of a unit
*
*************************************************************************************
*
*   */ requires /*
*
*       */ UnitIndexer /*             hiveworkshop.com/forums/showthread.php?t=172090
*       */ Table /*                   hiveworkshop.com/forums/showthread.php?t=188084
*       */ RegisterPlayerUnitEvent /* hiveworkshop.com/forums/showthread.php?t=203338
*
************************************************************************************
*
*   struct LearnedAbilities extends array
*
*       static method operator [] takes unit u returns LearnedAbilities
*       method operator [] takes integer index returns integer abilityId
*
*       method operator count takes nothing returns integer abilityCount
*
***********************************************************************************/
    globals
        private Table abils
        private Table marked
        private integer array c
    endglobals
    private function Index takes nothing returns boolean
        set abils[GetIndexedUnitId()] = Table.create()
        set marked[GetIndexedUnitId()] = Table.create()
        return false
    endfunction
    private function Deindex takes nothing returns boolean
        call abils[GetIndexedUnitId()].destroy()
        call marked[GetIndexedUnitId()].destroy()
        set c[GetIndexedUnitId()] = 0
        return false
    endfunction
    private function Ability takes nothing returns nothing
        local integer i = GetUnitUserData(GetTriggerUnit())
        if (not marked[i].boolean.has(GetLearnedSkill())) then
            set abils[i][c[i]] = GetLearnedSkill()
            set marked[i].boolean[GetLearnedSkill()] = true
            set c[i] = c[i] + 1
        endif
    endfunction
    private module M
        private static method onInit takes nothing returns nothing
            set abils = Table.create()
            set marked = Table.create()
            call RegisterUnitIndexEvent(Filter(function Index), UnitIndexer.INDEX)
            call RegisterUnitIndexEvent(Filter(function Deindex), UnitIndexer.DEINDEX)
            call RegisterPlayerUnitEvent(EVENT_PLAYER_HERO_SKILL, function Ability)
        endmethod
    endmodule
    struct LearnedAbilities extends array
        static method operator [] takes unit u returns LearnedAbilities
            return GetUnitUserData(u)
        endmethod
        method operator [] takes integer index returns integer
            return abils[this][index]
        endmethod
        method operator count takes nothing returns integer
            local integer i = c[this]
            local integer m
            loop
                exitwhen i == 0
                set i = i - 1
                set m = abils[this][i]
                if GetUnitAbilityLevel(GetUnitById(this), m) == 0 then
                    call marked[this].remove(m)
                    set c[this] = c[this] - 1
                    set abils[this][i] = abils[this][c[this]]
                    call abils[this].remove(c[this])
                endif
            endloop
            return c[this]
        endmethod
        implement M
    endstruct
endlibrary
 
Top