System Attribute System v4

emjlr3

Change can be a good thing
Reaction score
395
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!
 

Attachments

  • AS_Pic.JPG
    AS_Pic.JPG
    138.6 KB · Views: 2,036
  • Attribute System v4 - emjlr3.w3x
    72.5 KB · Views: 814

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
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?
 

emjlr3

Change can be a good thing
Reaction score
395
skimming though the Read Me is always a good place to start
 

Cohadar

master of fugue
Reaction score
209
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?
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
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.
 

Cohadar

master of fugue
Reaction score
209
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.
 

emjlr3

Change can be a good thing
Reaction score
395
Why AS_Enable is not private?

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

don't feel like porting it

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

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

Tables...:rolleyes:

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


don't remember

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.

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
 

Cohadar

master of fugue
Reaction score
209
back before you knew of WC3, its all we had/don't feel like porting
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.
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
>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.
 

Cohadar

master of fugue
Reaction score
209
>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.

Read post #7
 

emjlr3

Change can be a good thing
Reaction score
395
bah, how is hiding items unsafe again?

some crazy guy had some bug back in the day or some shit
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
Read post #7

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.
 

Cohadar

master of fugue
Reaction score
209
AOE spells that target items can probably destroy them.
And like someone already said AI units tend to pick up hidden items.
 

emjlr3

Change can be a good thing
Reaction score
395
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
 

Hatebreeder

So many apples
Reaction score
380
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 >.<
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    I ordered like five blocks for 15 dollars. They're just little aluminum blocks with holes drilled into them
  • Varine Varine:
    They are pretty much disposable. I have shitty nozzles though, and I don't think these were designed for how hot I've run them
  • Varine Varine:
    I tried to extract it but the thing is pretty stuck. Idk what else I can use this for
  • Varine Varine:
    I'll throw it into my scrap stuff box, I'm sure can be used for something
  • Varine Varine:
    I have spare parts for like, everything BUT that block lol. Oh well, I'll print this shit next week I guess. Hopefully it fits
  • Varine Varine:
    I see that, despite your insistence to the contrary, we are becoming a recipe website
  • Varine Varine:
    Which is unique I guess.
  • The Helper The Helper:
    Actually I was just playing with having some kind of mention of the food forum and recipes on the main page to test and see if it would engage some of those people to post something. It is just weird to get so much traffic and no engagement
  • The Helper The Helper:
    So what it really is me trying to implement some kind of better site navigation not change the whole theme of the site
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top