System Attribute System v4

Discussion in 'Systems and Snippets' started by emjlr3, Nov 25, 2007.

  1. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    Attribute System v4

    Version History:
    • v4 - No longer uses gamecache or requires CSCache, fixed a bug where stat points would not update if the learn inventory was open, minor readme updates, minor optimizations, now only works for 1 unit/player, reports an error if the user tries to enable it for more then 1
    • v3 - Fixed some minor grammatical errors in my documentation, as well as added better vJASS syntax to the library
    • v2 - Fixed problem with morphing heroes, and a bug where the system would start for units you did not enable it on
    • v1 - First release


    A re-release of a simple attribute system I made a while back which allows you to manually choose what attributes to increase when your hero levels up.

    Why use this as opposed to other attribute systems?
    Well as far as I know there is only one, Weaaddars. I used the same concept he did, however, I wrote all these triggers from scratch.
    In comparison, this is far more optimized, has no leaks(that I am aware of), is much easier to import, and has a quite better read me.

    In any case, download, try it out, you may find it useful, and please comment.

    Credits to Vexorian for CSSafety.

    JASS:
    library AttributeSystem initializer Init_AttributeSystem needs CSSafety
    
    //***************************************************************************
    //*                                                                         *
    //* Attribute System v4                                                     *
    //* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯               **URL in the works                    *
    //* Requires:                                                               *
    //* ¯¯¯¯¯¯¯¯¯                                                               *
    //*                                                                         *
    //* - A vJASS Preprocessor                                                  *
    //* - CSSafety library                                                      *
    //*                                                                         *
    //* - The custom items and abilities found in this map                      *
    //* - Updated rawcodes for the aforementioned objects                       * 
    //*                                                                         *
    //***************************************************************************
    
    
    globals  
    //Config. Options\\     
        // Attribute(Attribute System) ability rawcode
        private constant integer AS_Abil = 'A001'
        // Blank item rawcode 
        private constant integer AS_Blank = 'I000'
        // Cancel item rawcode
        private constant integer AS_Cancel = 'I001'
        // Number of stat points remaining item rawcode
        private constant integer AS_Att = 'I005'
        // Increment Strength item rawcode
        private constant integer AS_Str = 'I004'
        // Increment Agility item rawcode
        private constant integer AS_Agi = 'I002'
        // Increment Intelligence item rawcode
        private constant integer AS_Int = 'I003'   
    
    //Do not touch past here unless you pain for death!!\\
        private item array AS_I0
        private item array AS_I1
        private item array AS_I2
        private item array AS_I3
        private item array AS_I4
        private item array AS_I5
        private item array AS_IAtt0
        private item array AS_IAtt1
        private item array AS_IAtt2
        private item array AS_IAtt3
        private item array AS_IAtt4
        private item array AS_IAtt5
        
        private integer array AS_PointsPerLevel
        private integer array AS_LastLevel
        private integer array AS_Points
        private boolean array AS_Enabled    
        private boolean array AS_On
        
        private unit AS_Hero
    endglobals
    
    
    //**Library of functions**\\
    
    //Enable system for hero
    function AS_Enable takes unit u, integer i returns nothing
        local integer id = GetPlayerId(GetOwningPlayer(u))
        
        if AS_Enabled[id] then
            call BJDebugMsg("Error: "+GetPlayerName(GetOwningPlayer(u))+" already has the system running.")
            return
        endif
        
        set AS_I0[id] = CreateItem(AS_Str,0,0)
        call SetItemVisible(AS_I0[id],false)
        
        set AS_I1[id] = CreateItem(AS_Att,0,0)
        call SetItemVisible(AS_I1[id],false)
        
        set AS_I2[id] = CreateItem(AS_Agi,0,0)
        call SetItemVisible(AS_I2[id],false)
        
        set AS_I3[id] = CreateItem(AS_Blank,0,0)
        call SetItemVisible(AS_I3[id],false)
        
        set AS_I4[id] = CreateItem(AS_Int,0,0)
        call SetItemVisible(AS_I4[id],false)
        
        set AS_I5[id] = CreateItem(AS_Cancel,0,0)
        call SetItemVisible(AS_I5[id],false)
        call SetItemDroppable(AS_I5[id],false)
        
        set AS_LastLevel[id] = GetHeroLevel(u)
        set AS_Enabled[id] = true
        set AS_PointsPerLevel[id] = i
    endfunction
    
    //When the hero levels up
    private function AS_Level takes unit u returns nothing
        local integer points
        local integer id = GetPlayerId(GetOwningPlayer(u))
        
        if AS_Enabled[id]==true then
            set points = ((GetHeroLevel(u)-AS_LastLevel[id])*AS_PointsPerLevel[id])+AS_Points[id]
            set AS_LastLevel[id] = GetHeroLevel(u)
            if GetUnitAbilityLevel(u,AS_Abil)<1 and AS_On[id]==false then
                call UnitAddAbility(u,AS_Abil) 
                call UnitMakeAbilityPermanent(u,true,AS_Abil)
            endif
            if AS_On[id]==true then
                call SetItemCharges(AS_I1[id],points)
            endif
            set AS_Points[id] = points
            call IssueImmediateOrder(u,"replenishon") 
        endif  
    endfunction
    
    //Swap the inventory
    private function AS_SwapInv takes unit u, integer whichway returns nothing
        local integer id = GetPlayerId(GetOwningPlayer(u))
        local item it
        
        if whichway==1 then
            set AS_IAtt0[id] = UnitRemoveItemFromSlot(u,0)
            call SetItemVisible(AS_IAtt0[id],false)
            call SetItemVisible(AS_I0[id],true)
            call UnitAddItem(u,AS_I0[id])
            
            set AS_IAtt1[id] = UnitRemoveItemFromSlot(u,1)
            call SetItemVisible(AS_IAtt1[id],false)
            call SetItemCharges(AS_I1[id],AS_Points[id])
            call SetItemVisible(AS_I1[id],true)
            call UnitAddItem(u,AS_I1[id])
            
            set AS_IAtt2[id] = UnitRemoveItemFromSlot(u,2)
            call SetItemVisible(AS_IAtt2[id],false)
            call SetItemVisible(AS_I2[id],true)
            call UnitAddItem(u,AS_I2[id])
            
            set AS_IAtt3[id] = UnitRemoveItemFromSlot(u,3)
            call SetItemVisible(AS_IAtt3[id],false)
            call SetItemVisible(AS_I3[id],true)
            call UnitAddItem(u,AS_I3[id])
            
            set AS_IAtt4[id] = UnitRemoveItemFromSlot(u,4)
            call SetItemVisible(AS_IAtt4[id],false)
            call SetItemVisible(AS_I4[id],true)
            call UnitAddItem(u,AS_I4[id])
            
            set AS_IAtt5[id] = UnitRemoveItemFromSlot(u,5)
            call SetItemVisible(AS_IAtt5[id],false)
            call SetItemVisible(AS_I5[id],true)
            call UnitAddItem(u,AS_I5[id])
            
            set AS_On[id] = true
        else
            set it = UnitRemoveItemFromSlot(u,0)
            call SetItemVisible(it,false)
            call SetItemVisible(AS_IAtt0[id],true)
            call UnitAddItem(u,AS_IAtt0[id])
            
            set it = UnitRemoveItemFromSlot(u,1)
            call SetItemVisible(it,false)
            call SetItemVisible(AS_IAtt1[id],true)
            call UnitAddItem(u,AS_IAtt1[id])
            
            set it = UnitRemoveItemFromSlot(u,2)
            call SetItemVisible(it,false)
            call SetItemVisible(AS_IAtt2[id],true)
            call UnitAddItem(u,AS_IAtt2[id])
            
            set it = UnitRemoveItemFromSlot(u,3)
            call SetItemVisible(it,false)
            call SetItemVisible(AS_IAtt3[id],true)
            call UnitAddItem(u,AS_IAtt3[id])
            
            set it = UnitRemoveItemFromSlot(u,4)
            call SetItemVisible(it,false)
            call SetItemVisible(AS_IAtt4[id],true)
            call UnitAddItem(u,AS_IAtt4[id])
            
            set it = UnitRemoveItemFromSlot(u,5)
            call SetItemVisible(it,false)
            call SetItemVisible(AS_IAtt5[id],true)
            call UnitAddItem(u,AS_IAtt5[id])
            
            set AS_On[id] = false
        endif    
        
        set it = null
    endfunction
    
    //Returns what slot the item is in
    private function AS_GetItemSlot takes unit hero, item it returns integer
        local integer i = 0
    	
        loop
            exitwhen i==6
            if UnitItemInSlot(hero,i)==it then
                return i
            endif
            set i = i + 1
        endloop
    	
        return -1
    endfunction
    
    //**Working Functions**\\
    
    //Add attribute option when the hero levels
    private function AS_level_Actions takes nothing returns nothing
        call AS_Level(GetTriggerUnit())
    endfunction
    
    //Swap inventory for the hero when needed
    private function AS_TRO_Child takes nothing returns nothing
        call IssueImmediateOrder(AS_Hero,"replenishon")
        call IssueImmediateOrder(AS_Hero,"replenishlifeoff")
        
        call ReleaseTimer(GetExpiredTimer() )
    endfunction
    private function AS_TRO takes unit hero returns nothing
        set AS_Hero = hero
        call TimerStart(NewTimer(),0.,false,function AS_TRO_Child)
    endfunction 
    private function AS_inven_Actions takes nothing returns nothing
        local unit hero = GetTriggerUnit()
        local integer order = GetIssuedOrderId()
        local integer temp = 0
        
        if not IsUnitType(hero,UNIT_TYPE_HERO) then
            set hero = null
            return
        endif
        if order==OrderId("replenish") then
            call UnitRemoveAbility(hero,AS_Abil)
            call AS_SwapInv(hero,1)
        elseif order==OrderId("replenishoff") then
            call AS_TRO(hero)
        endif 
    	
        set hero = null
    endfunction
    
    //Add attributes when selected
    private function AS_att_Actions takes nothing returns nothing
        local unit hero = GetManipulatingUnit()
        local item used = GetManipulatedItem()
        local integer id = GetPlayerId(GetOwningPlayer(hero))
        local integer array temp
    	
        if not AS_On[id] then
            set hero = null
            set used = null
            return
        endif
        set temp[0] = AS_GetItemSlot(hero,used)
        set temp[1] = AS_Points[id]-1
        if temp[0]!=5 or temp[1]<0 then
            call ModifyHeroStat( temp[0]/2,hero,bj_MODIFYMETHOD_ADD,1)
            set AS_Points[id] = temp[1]
            call SetItemCharges(AS_I1[id],temp[1])
            if temp[1]==0 then
                call AS_SwapInv(hero,0)
            endif
        elseif temp[1]>=0 then
            call AS_SwapInv(hero,0)
            call UnitAddAbility(hero,AS_Abil)
            call UnitMakeAbilityPermanent(hero,true,AS_Abil)
            call IssueImmediateOrder(hero,"replenishon")
        else
            call AS_SwapInv(hero,0)
        endif
    	
        set hero = null
        set used = null
    endfunction
    
    //===========================================================================
    private function Init_AttributeSystem takes nothing returns nothing
        local trigger level = CreateTrigger() 
        local trigger inven = CreateTrigger() 
        local trigger att = CreateTrigger()     
        
        call TriggerRegisterAnyUnitEventBJ(level, EVENT_PLAYER_HERO_LEVEL )
        call TriggerAddAction( level, function AS_level_Actions )
        
        call TriggerRegisterAnyUnitEventBJ( inven, EVENT_PLAYER_UNIT_ISSUED_ORDER )
        call TriggerRegisterAnyUnitEventBJ( inven, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
        call TriggerRegisterAnyUnitEventBJ( inven, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
        call TriggerAddAction( inven, function AS_inven_Actions )
        
        call TriggerRegisterAnyUnitEventBJ( att, EVENT_PLAYER_UNIT_USE_ITEM )
        call TriggerAddAction( att, function AS_att_Actions )
    endfunction   
    
    endlibrary


    -emjlr3, enjoy!
     

    Attached Files:

    • Like Like x 6
  2. Doom-Angel

    Doom-Angel Jass User (Just started using NewGen)

    Ratings:
    +167 / 0 / -0
    wow realy nice system i liked it +Rep from me
     
  3. cr4xzZz

    cr4xzZz Also known as azwraith_ftL.

    Ratings:
    +51 / 0 / -0
    Perfect! I was looking for an attribute system like that for ages. +rep if I can, but which field should I edit to make Heroes gain, for example, 10 attribute points?
     
  4. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    skimming though the Read Me is always a good place to start
     
  5. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    Why AS_Enable is not private?

    "AS_Item_Att"+I2S(0..5) <----- AAAAAAAAAAAAAAAAAAAAAAAAAAA
    Use structs for inventory ffs.

    You know you don't have to put prefixes to your functions if they are public or private?

    Tables...:rolleyes:

    Why exactly are you using all these?
     
  6. phyrex1an

    phyrex1an Staff Member and irregular helper Staff Member

    Ratings:
    +446 / 0 / -0
    A few things:

    1. --- Above post ---

    2. If you still want to use tables then why write "AS_Item_Att"+I2S(1) instead of "AS_Item_Att1"?

    3. SetItemVisible(it,false). I believe that Vexorian declared that unsafe and added a better way to hide items to his caster system. I think it was something that made AI units pick up items even when they where hidden.
     
  7. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    It moves items in inventory when switching ... shame on you.

    The only safe way to "hide" items is actually to destroy them and then restore them from data stored in structs.
    Data includes items Id, HP, Number of Charges, Custom Value and position in slot.
    This assumes that you are not using item attaching.

    And then you can use cool stuff like UnitAddItemToSlotById :D

    Well there is a lot of critique on this sys, but at least it works properly.
     
  8. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    don't feel like porting it

    don't feel like updating that part, it does not make a difference with performance

    back before you knew of WC3, its all we had/don't feel like porting

    don't remember

    2. so I can loop through the items and add/remove them as needed
    3. never had an issues, if anyone can make it bug, I'll update that, until then, it works as intended

    *This is a systems I released before vJASS or structs, I don't feel like porting, it, this was basically just a release for this site, if you feel like doing it yourself, be my guest
     
  9. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    LoooL, I was making .PUD files .....
    "Back in the days" is such a silly sentance :D

    Anyways like I said, (coding aside) this thing works as it is supposed to work.
    The only remark is swapping item places in inventory.
     
  10. phyrex1an

    phyrex1an Staff Member and irregular helper Staff Member

    Ratings:
    +446 / 0 / -0
    >2. so I can loop through the items and add/remove them as needed

    Well, I'm mostly nitpicking but there is no reason to write "AS_Item_Att"+I2S(1) instead of "AS_Item_Att1", the result is the same and we save one string concat and an I2S.

    >The only remark is swapping item places in inventory.
    Suggestion: Instead of adding a "null" item to the hero add a dummy item that you remove as soon as all items are added. Easiest way to get the items to the right place.
     
  11. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0

    UnitAddItemToSlotById
     
  12. phyrex1an

    phyrex1an Staff Member and irregular helper Staff Member

    Ratings:
    +446 / 0 / -0
    >UnitAddItemToSlotById
    Hmm, second easiest? :p

    Edit: Or not. UnitAddItemToSlotById creates a new item and that's not what we want here. We want to have the same items as we had before entering the Attribute selector inventory.
     
  13. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    Read post #7
     
  14. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    bah, how is hiding items unsafe again?

    some crazy guy had some bug back in the day or some shit
     
  15. phyrex1an

    phyrex1an Staff Member and irregular helper Staff Member

    Ratings:
    +446 / 0 / -0
    So you rather to through the trouble of updating all variable references to items? Or use a struct wrapper around all items? That sounds troublesome to me.

    >bah, how is hiding items unsafe again?
    The only thing I know is there is/was a module in the caster system that uses a hidden unit with an inventory to store items.
     
  16. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    AOE spells that target items can probably destroy them.
    And like someone already said AI units tend to pick up hidden items.
     
  17. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    not if u add a check for IsItemVisible, like a good AI coder

    and well, dont let AoE spells target items, simple as that, why would one do that anyway, does not seem very useful

    in anycase, don't be a sped, and problems will not ensue
     
  18. Cohadar

    Cohadar master of fugue

    Ratings:
    +209 / 0 / -0
    Just curious, what is a sped?
     
  19. Hatebreeder

    Hatebreeder So many apples

    Ratings:
    +383 / 0 / -0
    WoW. this System is... Simple :rolleyes:
    Seriously. After I read the ReadMe, I could understand all this (Although I'm not an expirienced JASSer).
    Great System, and great Noob-friendly Coding!
    +Rep from me =)

    *Edit* Damn, I got to spread +Rep before I can give it to you again >.<
     
    • Like Like x 1
  20. Sim

    Sim Forum Administrator Staff Member

    Ratings:
    +531 / 0 / -0
    Approved.
     

Share This Page