• 🏆 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] Custom Stat System (CSS) v1.5g

I urge all users who are using an earlier version of this system to update as soon as possible to avoid possible issues found in older versions.

For those who already have a previous version (before 1.5j), please copy the code below, paste it into an empty trigger and run it just like how you execute the Implementation Macro. It will patch up the bugged Life Regeneration abilities. I am deeply sorry for the inconvenience. You can also find a copy of this in the test map of v1.5j.

JASS:
// CSS - Life Regeneration
//============================================================================================
//! textmacro LifeRegenAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a Arel $RAWCODE$ Ihpr 1 $VALUE$ anam "CSS - Life Regen ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTexturesCommandButtonsBTNRingSkull.blp
//! endtextmacro

//! runtextmacro LifeRegenAbility("ZxJ0", "+00001", "1")
//! runtextmacro LifeRegenAbility("ZxJ1", "+00002", "2")
//! runtextmacro LifeRegenAbility("ZxJ2", "+00004", "4")
//! runtextmacro LifeRegenAbility("ZxJ3", "+00008", "8")
//! runtextmacro LifeRegenAbility("ZxJ4", "+00016", "16")
//! runtextmacro LifeRegenAbility("ZxJ5", "+00032", "32")
//! runtextmacro LifeRegenAbility("ZxJ6", "+00064", "64")
//! runtextmacro LifeRegenAbility("ZxJ7", "+00128", "128")
//! runtextmacro LifeRegenAbility("ZxJ8", "+00256", "256")
//! runtextmacro LifeRegenAbility("ZxJ9", "+00512", "512")
//! runtextmacro LifeRegenAbility("ZxJa", "+01024", "1024")
//! runtextmacro LifeRegenAbility("ZxJb", "+02048", "2048")
//! runtextmacro LifeRegenAbility("ZxJc", "+04096", "4096")
//! runtextmacro LifeRegenAbility("ZxJd", "+08192", "8192")
//! runtextmacro LifeRegenAbility("ZxJe", "+16384", "16384")
//! runtextmacro LifeRegenAbility("ZxJf", "+32768", "32768")
//! runtextmacro LifeRegenAbility("ZxJg", "+65536", "65536")
//! runtextmacro LifeRegenAbility("ZxJh", "-131072", "-131072")

CUSTOM STAT SYSTEM v1.5g

Features
  • You can now have a fully-functional item with up to 11 types of stats with a single GUI custom script. Abilities for items' passive stats are no longer required.
  • GUI-friendly interface and usage. Configurability relies mainly on global boolean variables.
  • Right Click Item Socketing that transfers the overwhelming benefits from the mechanics of Diablo 2's socketing system to Warcraft 3. Furthermore, this is only an add-on and can be toggled on/off at will.
  • Socketing means empowering an item with another item (usually called a gem). An item that is socketable usually has sockets which are, in a nutshell, holes to which a gem can be inserted. When all the sockets are filled the item can no longer be socketed. Socketing is a way of upgrading your item as you wish to and it is a prominent feature in most RPG games.
  • Quite simple actually. Right-click on the socket item and left click on the target item. A notification will pop-up upon successful socketing.
  • Item info panel that can be accessed with a single chat command (as seen in the screenshot above). Just remember to include it in your map's log.
  • Socket event can be caught with the Event: Game - EVENT_SOCKET_FINISH becomes equal to 1.00. Do not use waits in the response trigger or it is screwed up.
  • BonusMod-like features for extensive usage. Now a standalone part of the system.
  • Easy implementation.
  • Vanilla WE JASS. JNGP is required only for running the Object Merger macro.
  • => A system for epic RPGs (and its other sub-genres such as ORPGs, SPRPGs, etc) as well as any maps that incorporate a large amount of items. Say goodbye to your old-fasioned method of sitting for hours creating stats for your items. CSS is here to stay.

It is easy. Just copy the Map Header Custom Code, CSS Standalone Bonus trigger and the abilities. Then use the system however you want.




JASS:
//************************************************************************************************************
//*                                                                                                          *
//*                              CUSTOM STAT SYSTEM (CSS)                                                    *
//*                                                                                                          *
//*   Author:   Doomlord                                                                                     *
//*   Version:  1.5g                                                                                         *
//*                                                                                                          *
//*   Credits:                                                                                               *
//*   + Earth-Fury:    BonusMod binary algoritm; implementation macro.                                       *
//*   + Crigges:       A great amount of help and support.                                                   *
//*   + Geries:        Help me with the item hashtable values cleanup.                                       *
//*   + rulerofiron99: Item Socketing method referenced from [GUI]Right Click Item Recipe v1.05.             *
//*   + Vexorian:      CSS_SimError [url]http://www.wc3c.net/showthread.php?t=101260[/url]                   *
//*   + Magtheridon96: [Snippet]BoundInt [url]http://www.hiveworkshop.com/forums/2294066-post804.html[/url]  *
//*   + WaterKnight:   Help with the stack for custom Event Response.                                        *
//*   + PurgeandFire:  Pinpoint a possible desync bug with the system.                                       *
//*   + Nestharus:     Mentioning the possible negative life bug in his Bonus lib.                           *
//*                                                                                                          *
//************************************************************************************************************


//**************************************************************************************
//* INTRODUCTION:                                                                      *
//*                                                                                    *
//* An alternative to BonusMod for those who prefer a vanilla JASS approach.           *
//*                                                                                    *
//* Just follow the API and you are pretty much done.                                  *
//**************************************************************************************


//********************************************************************************************************
//* REQUIREMENTS:                                                                                        *
//*                                                                                                      *
//* JNGP [url]http://www.hiveworkshop.com/forums/tools-560/jassnewgenpack-5d-227445[/url] (Recommended)  *
//* OR:                                                                                                  *
//* Your superhuman capability to transfer 198 abilities to your map. (Not Recommended)                  *
//********************************************************************************************************


//************************************************************************************************************************************************
//* INSTALLATION INSTRUCTION:                                                                                                                    *
//*                                                                                                                                              *
//* Step 1: Copy the custom code for bonus handling to your map header.                                                                          *
//* Step 2: Use JNGP to implement the system's abilities through macro. Instruction is included in the Implementation Macro trigger.             *
//* Step 3: Copy the whole CSS folder to your map. Don't forget to turn on "Automatically create unknown variables while pasting trigger data".  *
//* Step 4: Except for this trigger, delete every other useless elements.                                                                        *
//* Step 5: Use this BonusMod alternative however you want.                                                                                      *
//*                                                                                                                                              *
//************************************************************************************************************************************************


//**************************************************************************************
//* Bonus Types Identifier:                                                            *
//*                                                                                    *
//* Armor Bonus:        0                                                              *
//* Attack Speed Bonus: 1                                                              *
//* Damage Bonus:       2                                                              *
//* Agility Bonus:      3                                                              *
//* Intelligence Bonus: 4                                                              *
//* Strength Bonus:     5                                                              *
//* Life Regen Bonus:   6                                                              *
//* Mana Regen Bonus:   7                                                              *
//* Life Bonus:         8                                                              *
//* Mana Bonus:         9                                                              *
//* Sight Range Bonus:  10                                                             *
//**************************************************************************************


//********************************************************************************
//* Generic Bonus APIs                                                           *
//*                                                                              *
//* CSS_GetBonus takes unit u, integer bonusType returns integer                 *
//* CSS_AddBonus takes unit u, integer amount, integer bonusType returns nothing *
//* CSS_ClearBonus takes unit u, integer bonusType                               *
//********************************************************************************

// Clear bonus

function CSS_ClearBonus takes unit u, integer bonusType returns nothing

    if bonusType > 10 or bonusType < 0 or GetUnitTypeId (u) == 0 or IsUnitType (u, UNIT_TYPE_DEAD) then
        return
    endif

    call CSS_AddBonus (u, -LoadInteger (udg_CSS_Hashtable, GetHandleId (u), bonusType), bonusType)
endfunction

// Get current bonus

function CSS_GetBonus takes unit u, integer bonusType returns integer

    if bonusType > 10 or bonusType < 0 or GetUnitTypeId (u) == 0 or IsUnitType (u, UNIT_TYPE_DEAD) then
        return 0
    endif

    return LoadInteger (udg_CSS_Hashtable, GetHandleId (u), bonusType)
endfunction

// For preloading abilities

function CSS_Preload takes nothing returns nothing
    local integer i = 0
    local unit u = CreateUnit(Player(15), 'hfoo', 0, 0, 0.00)

    loop
        exitwhen i > 197
        call UnitAddAbility(u, udg_CSS_Abilities[i])
        set i = i + 1
    endloop

    call RemoveUnit(u)
    set u = null
endfunction

//===========================================================================
function InitTrig_CSS_Standalone_Bonus takes nothing returns nothing
    local integer i = 0
    local integer a = 1

    set udg_CSS_Abilities[0] = 'ZxA0'
    set udg_CSS_Abilities[1] = 'ZxA1'
    set udg_CSS_Abilities[2] = 'ZxA2'
    set udg_CSS_Abilities[3] = 'ZxA3'
    set udg_CSS_Abilities[4] = 'ZxA4'
    set udg_CSS_Abilities[5] = 'ZxA5'
    set udg_CSS_Abilities[6] = 'ZxA6'
    set udg_CSS_Abilities[7] = 'ZxA7'
    set udg_CSS_Abilities[8] = 'ZxA8'
    set udg_CSS_Abilities[9] = 'ZxA9'
    set udg_CSS_Abilities[10] = 'ZxAa'
    set udg_CSS_Abilities[11] = 'ZxAb'
    set udg_CSS_Abilities[12] = 'ZxAc'
    set udg_CSS_Abilities[13] = 'ZxAd'
    set udg_CSS_Abilities[14] = 'ZxAe'
    set udg_CSS_Abilities[15] = 'ZxAf'
    set udg_CSS_Abilities[16] = 'ZxAg'
    set udg_CSS_Abilities[17] = 'ZxAh'
    set udg_CSS_Abilities[18] = 'ZxI0'
    set udg_CSS_Abilities[19] = 'ZxI1'
    set udg_CSS_Abilities[20] = 'ZxI2'
    set udg_CSS_Abilities[21] = 'ZxI3'
    set udg_CSS_Abilities[22] = 'ZxI4'
    set udg_CSS_Abilities[23] = 'ZxI5'
    set udg_CSS_Abilities[24] = 'ZxI6'
    set udg_CSS_Abilities[25] = 'ZxI7'
    set udg_CSS_Abilities[26] = 'ZxI8'
    set udg_CSS_Abilities[27] = 'ZxI9'
    set udg_CSS_Abilities[28] = 'ZxIa'
    set udg_CSS_Abilities[29] = 'ZxIb'
    set udg_CSS_Abilities[30] = 'ZxIc'
    set udg_CSS_Abilities[31] = 'ZxId'
    set udg_CSS_Abilities[32] = 'ZxIe'
    set udg_CSS_Abilities[33] = 'ZxIf'
    set udg_CSS_Abilities[34] = 'ZxIg'
    set udg_CSS_Abilities[35] = 'ZxIh'
    set udg_CSS_Abilities[36] = 'ZxB0'
    set udg_CSS_Abilities[37] = 'ZxB1'
    set udg_CSS_Abilities[38] = 'ZxB2'
    set udg_CSS_Abilities[39] = 'ZxB3'
    set udg_CSS_Abilities[40] = 'ZxB4'
    set udg_CSS_Abilities[41] = 'ZxB5'
    set udg_CSS_Abilities[42] = 'ZxB6'
    set udg_CSS_Abilities[43] = 'ZxB7'
    set udg_CSS_Abilities[44] = 'ZxB8'
    set udg_CSS_Abilities[45] = 'ZxB9'
    set udg_CSS_Abilities[46] = 'ZxBa'
    set udg_CSS_Abilities[47] = 'ZxBb'
    set udg_CSS_Abilities[48] = 'ZxBc'
    set udg_CSS_Abilities[49] = 'ZxBd'
    set udg_CSS_Abilities[50] = 'ZxBe'
    set udg_CSS_Abilities[51] = 'ZxBf'
    set udg_CSS_Abilities[52] = 'ZxBg'
    set udg_CSS_Abilities[53] = 'ZxBh'
    set udg_CSS_Abilities[54] = 'ZxG0'
    set udg_CSS_Abilities[55] = 'ZxG1'
    set udg_CSS_Abilities[56] = 'ZxG2'
    set udg_CSS_Abilities[57] = 'ZxG3'
    set udg_CSS_Abilities[58] = 'ZxG4'
    set udg_CSS_Abilities[59] = 'ZxG5'
    set udg_CSS_Abilities[60] = 'ZxG6'
    set udg_CSS_Abilities[61] = 'ZxG7'
    set udg_CSS_Abilities[62] = 'ZxG8'
    set udg_CSS_Abilities[63] = 'ZxG9'
    set udg_CSS_Abilities[64] = 'ZxGa'
    set udg_CSS_Abilities[65] = 'ZxGb'
    set udg_CSS_Abilities[66] = 'ZxGc'
    set udg_CSS_Abilities[67] = 'ZxGd'
    set udg_CSS_Abilities[68] = 'ZxGe'
    set udg_CSS_Abilities[69] = 'ZxGf'
    set udg_CSS_Abilities[70] = 'ZxGg'
    set udg_CSS_Abilities[71] = 'ZxGh'
    set udg_CSS_Abilities[72] = 'ZxH0'
    set udg_CSS_Abilities[73] = 'ZxH1'
    set udg_CSS_Abilities[74] = 'ZxH2'
    set udg_CSS_Abilities[75] = 'ZxH3'
    set udg_CSS_Abilities[76] = 'ZxH4'
    set udg_CSS_Abilities[77] = 'ZxH5'
    set udg_CSS_Abilities[78] = 'ZxH6'
    set udg_CSS_Abilities[79] = 'ZxH7'
    set udg_CSS_Abilities[80] = 'ZxH8'
    set udg_CSS_Abilities[81] = 'ZxH9'
    set udg_CSS_Abilities[82] = 'ZxHa'
    set udg_CSS_Abilities[83] = 'ZxHb'
    set udg_CSS_Abilities[84] = 'ZxHc'
    set udg_CSS_Abilities[85] = 'ZxHd'
    set udg_CSS_Abilities[86] = 'ZxHe'
    set udg_CSS_Abilities[87] = 'ZxHf'
    set udg_CSS_Abilities[88] = 'ZxHg'
    set udg_CSS_Abilities[89] = 'ZxHh'
    set udg_CSS_Abilities[90] = 'ZxF0'
    set udg_CSS_Abilities[91] = 'ZxF1'
    set udg_CSS_Abilities[92] = 'ZxF2'
    set udg_CSS_Abilities[93] = 'ZxF3'
    set udg_CSS_Abilities[94] = 'ZxF4'
    set udg_CSS_Abilities[95] = 'ZxF5'
    set udg_CSS_Abilities[96] = 'ZxF6'
    set udg_CSS_Abilities[97] = 'ZxF7'
    set udg_CSS_Abilities[98] = 'ZxF8'
    set udg_CSS_Abilities[99] = 'ZxF9'
    set udg_CSS_Abilities[100] = 'ZxFa'
    set udg_CSS_Abilities[101] = 'ZxFb'
    set udg_CSS_Abilities[102] = 'ZxFc'
    set udg_CSS_Abilities[103] = 'ZxFd'
    set udg_CSS_Abilities[104] = 'ZxFe'
    set udg_CSS_Abilities[105] = 'ZxFf'
    set udg_CSS_Abilities[106] = 'ZxFg'
    set udg_CSS_Abilities[107] = 'ZxFh'
    set udg_CSS_Abilities[108] = 'ZxJ0'
    set udg_CSS_Abilities[109] = 'ZxJ1'
    set udg_CSS_Abilities[110] = 'ZxJ2'
    set udg_CSS_Abilities[111] = 'ZxJ3'
    set udg_CSS_Abilities[112] = 'ZxJ4'
    set udg_CSS_Abilities[113] = 'ZxJ5'
    set udg_CSS_Abilities[114] = 'ZxJ6'
    set udg_CSS_Abilities[115] = 'ZxJ7'
    set udg_CSS_Abilities[116] = 'ZxJ8'
    set udg_CSS_Abilities[117] = 'ZxJ9'
    set udg_CSS_Abilities[118] = 'ZxJa'
    set udg_CSS_Abilities[119] = 'ZxJb'
    set udg_CSS_Abilities[120] = 'ZxJc'
    set udg_CSS_Abilities[121] = 'ZxJd'
    set udg_CSS_Abilities[122] = 'ZxJe'
    set udg_CSS_Abilities[123] = 'ZxJf'
    set udg_CSS_Abilities[124] = 'ZxJg'
    set udg_CSS_Abilities[125] = 'ZxJh'
    set udg_CSS_Abilities[126] = 'ZxK0'
    set udg_CSS_Abilities[127] = 'ZxK1'
    set udg_CSS_Abilities[128] = 'ZxK2'
    set udg_CSS_Abilities[129] = 'ZxK3'
    set udg_CSS_Abilities[130] = 'ZxK4'
    set udg_CSS_Abilities[131] = 'ZxK5'
    set udg_CSS_Abilities[132] = 'ZxK6'
    set udg_CSS_Abilities[133] = 'ZxK7'
    set udg_CSS_Abilities[134] = 'ZxK8'
    set udg_CSS_Abilities[135] = 'ZxK9'
    set udg_CSS_Abilities[136] = 'ZxKa'
    set udg_CSS_Abilities[137] = 'ZxKb'
    set udg_CSS_Abilities[138] = 'ZxKc'
    set udg_CSS_Abilities[139] = 'ZxKd'
    set udg_CSS_Abilities[140] = 'ZxKe'
    set udg_CSS_Abilities[141] = 'ZxKf'
    set udg_CSS_Abilities[142] = 'ZxKg'
    set udg_CSS_Abilities[143] = 'ZxKh'
    set udg_CSS_Abilities[144] = 'ZxE0'
    set udg_CSS_Abilities[145] = 'ZxE1'
    set udg_CSS_Abilities[146] = 'ZxE2'
    set udg_CSS_Abilities[147] = 'ZxE3'
    set udg_CSS_Abilities[148] = 'ZxE4'
    set udg_CSS_Abilities[149] = 'ZxE5'
    set udg_CSS_Abilities[150] = 'ZxE6'
    set udg_CSS_Abilities[151] = 'ZxE7'
    set udg_CSS_Abilities[152] = 'ZxE8'
    set udg_CSS_Abilities[153] = 'ZxE9'
    set udg_CSS_Abilities[154] = 'ZxEa'
    set udg_CSS_Abilities[155] = 'ZxEb'
    set udg_CSS_Abilities[156] = 'ZxEc'
    set udg_CSS_Abilities[157] = 'ZxEd'
    set udg_CSS_Abilities[158] = 'ZxEe'
    set udg_CSS_Abilities[159] = 'ZxEf'
    set udg_CSS_Abilities[160] = 'ZxEg'
    set udg_CSS_Abilities[161] = 'ZxEh'
    set udg_CSS_Abilities[162] = 'ZxD0'
    set udg_CSS_Abilities[163] = 'ZxD1'
    set udg_CSS_Abilities[164] = 'ZxD2'
    set udg_CSS_Abilities[165] = 'ZxD3'
    set udg_CSS_Abilities[166] = 'ZxD4'
    set udg_CSS_Abilities[167] = 'ZxD5'
    set udg_CSS_Abilities[168] = 'ZxD6'
    set udg_CSS_Abilities[169] = 'ZxD7'
    set udg_CSS_Abilities[170] = 'ZxD8'
    set udg_CSS_Abilities[171] = 'ZxD9'
    set udg_CSS_Abilities[172] = 'ZxDa'
    set udg_CSS_Abilities[173] = 'ZxDb'
    set udg_CSS_Abilities[174] = 'ZxDc'
    set udg_CSS_Abilities[175] = 'ZxDd'
    set udg_CSS_Abilities[176] = 'ZxDe'
    set udg_CSS_Abilities[177] = 'ZxDf'
    set udg_CSS_Abilities[178] = 'ZxDg'
    set udg_CSS_Abilities[179] = 'ZxDh'
    set udg_CSS_Abilities[180] = 'ZxC0'
    set udg_CSS_Abilities[181] = 'ZxC1'
    set udg_CSS_Abilities[182] = 'ZxC2'
    set udg_CSS_Abilities[183] = 'ZxC3'
    set udg_CSS_Abilities[184] = 'ZxC4'
    set udg_CSS_Abilities[185] = 'ZxC5'
    set udg_CSS_Abilities[186] = 'ZxC6'
    set udg_CSS_Abilities[187] = 'ZxC7'
    set udg_CSS_Abilities[188] = 'ZxC8'
    set udg_CSS_Abilities[189] = 'ZxC9'
    set udg_CSS_Abilities[190] = 'ZxCa'
    set udg_CSS_Abilities[191] = 'ZxCb'
    set udg_CSS_Abilities[192] = 'ZxCc'
    set udg_CSS_Abilities[193] = 'ZxCd'
    set udg_CSS_Abilities[194] = 'ZxCe'
    set udg_CSS_Abilities[195] = 'ZxCf'
    set udg_CSS_Abilities[196] = 'ZxCg'
    set udg_CSS_Abilities[197] = 'ZxCh'

    loop
        exitwhen i > 30
        set udg_CSS_Power[i] = a
        set a = a*2
        set i = i + 1
    endloop

    set udg_CSS_Hashtable = InitHashtable()

    if udg_CSS_PreloadBoolean then
        call CSS_Preload()
    endif
endfunction
JASS:
//************************************************************************************************************
//*                                                                                                          *
//*                              CUSTOM STAT SYSTEM (CSS)                                                    *
//*                                                                                                          *
//*   Author:   Doomlord                                                                                     *
//*   Version:  1.5g                                                                                         *
//*                                                                                                          *
//*   Credits:                                                                                               *
//*   + Earth-Fury:    BonusMod binary algoritm; implementation macro.                                       *
//*   + Crigges:       A great amount of help and support.                                                   *
//*   + Geries:        Help me with the item hashtable values cleanup.                                       *
//*   + rulerofiron99: Item Socketing method referenced from [GUI]Right Click Item Recipe v1.05.             *
//*   + Vexorian:      CSS_SimError [url]http://www.wc3c.net/showthread.php?t=101260[/url]                   *
//*   + Magtheridon96: [Snippet]BoundInt [url]http://www.hiveworkshop.com/forums/2294066-post804.html[/url]  *
//*   + WaterKnight:   Help with the stack for custom Event Response.                                        *
//*   + PurgeandFire:  Pinpoint a possible desync bug with the system.                                       *
//*   + Nestharus:     Mentioning the possible negative life bug in his Bonus lib.                           *
//*                                                                                                          *
//************************************************************************************************************


//**************************************************************************************
//* INTRODUCTION:                                                                      *
//*                                                                                    *
//* 1 item - 11 passive stats with one custom script. This is Custom Stat System (CSS) *
//*                                                                                    *
//* A system that aims to get rid of mapmakers' annoyance of having to do a boring and *
//* repetitive job of creating a multitude of item passive stat abilities. At the      *
//* same time it also possesses generic bonus mod features to let you modify a unit's  *
//* stats freely and easily. It is also quite GUI friendly since everything can be     *
//* achieved solely through custom scripts.                                            *
//*                                                                                    *
//* Version 1.2 and onwards supports item socketing.                                   *
//**************************************************************************************


//**********************************************************************************************************************************
//* FEATURES:                                                                                                                      *
//*                                                                                                                                *
//* Pros:                                                                                                                          *
//* + Simple and GUI-friendly item passive stats registration.                                                                     *
//* + Has little effect on performance.                                                                                            *
//* + Quick implementation of system and system abilities through macro.                                                           *
//* + You no longer have to sit for hours creating item passive abilities for your map.                                            *
//* + Use only 1 hashtable (udg_CSS_Hashtable).                                                                                    *
//* + Pure JASS, only require JNGP for ability implementation.                                                                     *
//* + BonusMod-like features with better range for some stats.                                                                     *
//* + Bonus Range: -131072 to 131071.                                                                                              *
//* + Right Click Item Socketing.                                                                                                  *
//* + Socket event can be caught with the Event: EVENT_SOCKET_FINISH becomes equal to 1.00.                                        *
//* + In JASS: call TriggerRegisterVariableEvent(trigger, "EVENT_SOCKET_FINISH", EQUAL, 1.00).                                     *                                                                                                   *
//*                                                                                                                                *
//* Cons:                                                                                                                          *
//* + Does not include movement speed.                                                                                             *
//* + May bug if a unit somehow surpasses the bonus limit in some occasion.                                                        *
//* -> Fix: Don't allow a unit to achieve near-limit for a stat i.e keep it at a reasonable level.                                 *
//* + Limited configurability.                                                                                                     *
//* + Insufficient item tooltip, which is unavoidable because it is hard-coded.                                                    *
//**********************************************************************************************************************************


//********************************************************************************************************
//* REQUIREMENTS:                                                                                        *
//*                                                                                                      *
//* JNGP [url]http://www.hiveworkshop.com/forums/tools-560/jassnewgenpack-5d-227445[/url] (Recommended)  *
//* OR:                                                                                                  *
//* Your superhuman capability to transfer 198 abilities to your map. (Not Recommended)                  *
//********************************************************************************************************


//************************************************************************************************************************************************
//* INSTALLATION INSTRUCTION:                                                                                                                    *
//*                                                                                                                                              *
//* Step 1: Copy the custom code for bonus handling to your map header.                                                                          *
//* Step 2: Use JNGP to implement the system's abilities through macro. Instruction is included in the Implementation Macro trigger.             *
//* Step 3: Copy the whole CSS folder to your map. Don't forget to turn on "Automatically create unknown variables while pasting trigger data".  *
//* Step 4: Put the CSS trigger on top of your Item Declaration trigger.                                                                         *
//* Step 5: Register your items as examplified in the Item Declaration trigger. Remember to use Map Initialization event.                        *
//* Step 6: Set the global variables to modify your settings.                                                                                    *
//*         + udg_CSS_GemLevel: set a level identifier for your gem items. Gem Items must have a level higher than this value to function,       *
//*         + udg_CSS_Preload: set to true if you want to preload system abilities. Increase loading time but prevents first lags.               *
//*         + udg_CSS_SocketingEnabled: set to true if you want to enable the Right Click Item Socketing feature.                                *
//*         + udg_CSS_GemBonusBoolean: set to true if you want to allow wielded gems to display its bonuses.                                     *
//*         + udg_CSS_CustomSwitch: set to true if you want the item to give bonus only when it is fully socketed.                               *
//************************************************************************************************************************************************


//**************************************************************************************
//* Item Registration API                                                              *
//*                                                                                    *
//* call CSS_ItemInitialize (integer itemRawCode, integer armorBonus,                  *
//* integer attackSpeedBonus, integer damageBonus, integer agilityBonus,               *
//* integer intelligenceBonus, integer strengthBonus, integer lifeRegenBonus,          *
//* integer manaRegenBonus, integer lifeBonus, integer manaBonus,                      *
//* integer sightRangeBonus, integer socket)                                           *
//**************************************************************************************


//**************************************************************************************
//* Gem Registration API                                                               *
//*                                                                                    *
//* call CSS_GemInitialize (integer itemRawCode, integer armorBonus,                   *
//* integer attackSpeedBonus, integer damageBonus, integer agilityBonus,               *
//* integer intelligenceBonus, integer strengthBonus, integer lifeRegenBonus,          *
//* integer manaRegenBonus, integer lifeBonus, integer manaBonus,                      *
//* integer sightRangeBonus)                                                           *
//**************************************************************************************

//===========================================================================
// Only needed if you decided to use Right Click Item Socketing

// Item socket effect

constant function CSS_ItemSocketEffect takes nothing returns string
    return "Abilities\\Spells\\Items\\AIlm\\AIlmTarget.mdl"
endfunction

// Item socket effect attachment point

constant function CSS_ISEAttachPoint takes nothing returns string
    return "origin"
endfunction

// Item preload

function CSS_ItemPreload takes nothing returns nothing
    local unit u = CreateUnit(Player(15), 'Hpal', 0, 0, 0.00)
    local integer i = 0
    local integer j = LoadInteger (udg_CSS_Hashtable, -5, -5)
    local item array it

    loop
        exitwhen i > j
        set it[i] = CreateItem (LoadInteger (udg_CSS_Hashtable, -5, i), 0, 0)
        call UnitAddItem (u, it[i])
        set i = i + 1
    endloop

    set i = 0

    loop
        exitwhen i > j
        call RemoveItem (it[i])
        set it[i] = null
        set i = i + 1
    endloop

    call RemoveUnit (u)
    call FlushChildHashtable (udg_CSS_Hashtable, -5)
    set u = null
endfunction
//===========================================================================

// Fail-safe mechanism, only use in specific cases to avoid possible collision with other systems
// Refresh and update the unit's stats given by items in its inventory
// In a nutshell, do not use this unless you know what you are doing

function CSS_StatUpdate takes unit u returns nothing
    local integer i = 0
    local integer j = 0
    local integer k = GetHandleId (u)

    loop
        exitwhen j > 10
        call CSS_AddBonus (u, -LoadInteger (udg_CSS_Hashtable, k, j - 11), j)
        call SaveInteger (udg_CSS_Hashtable, k, j - 11, 0)
        set j = j + 1
    endloop

    loop
        exitwhen i > 5
        set j = 0

        loop
            exitwhen j > 10
            call CSS_AddBonus (u, LoadInteger (udg_CSS_Hashtable, GetHandleId (UnitItemInSlot (u, i)), j), j)
            call SaveInteger (udg_CSS_Hashtable, k, j - 11, LoadInteger (udg_CSS_Hashtable, k, j - 11) + LoadInteger (udg_CSS_Hashtable, GetHandleId (UnitItemInSlot (u, i)), j))
            set j = j + 1
        endloop

        set i = i + 1
    endloop
endfunction

// Item Socket Info Panel

function CSS_ItemInfoSocketPanel takes nothing returns boolean
    local group g = CreateGroup ()
    local item it
    local unit u
    local integer i
    local integer j = 0
    local player p = GetTriggerPlayer ()
    local integer k
    local string s

    if not udg_CSS_SocketingEnabled then
        call CSS_SimError ("Socketing feature is not enabled")
        call DestroyGroup (g)

        set p = null
        set g = null
        return false
    endif

    call GroupEnumUnitsSelected(g, p, null)

    if CountUnitsInGroup (g) > 1 then
        call CSS_SimError ("Invalid Selection")
        call DestroyGroup (g)

        set p = null
        set g = null
        return false
    else
        set u = FirstOfGroup (g)

        if not IsUnitOwnedByPlayer (u, p) then
            call CSS_SimError ("You must select an owned unit")
        else
            set it = UnitItemInSlot (u, S2I(SubString(GetEventPlayerChatString(), 16, StringLength(GetEventPlayerChatString()))) - 1)

            if it == null or not LoadBoolean (udg_CSS_Hashtable, GetItemTypeId (it), -4) then
                call CSS_SimError ("No item in chosen slot or chosen item is not registered with CSS")
            else

                call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + "Item Name: " + "|r" + udg_CSS_String[12] + GetItemName (it) + "|r")
                call DisplayTimedTextToPlayer (p, 0, 0, 15, "\n")

                set i = GetHandleId (it)
                set k = GetItemTypeId (it)

                loop
                    exitwhen j == LoadInteger (udg_CSS_Hashtable, k, -2)

                    set s = LoadStr (udg_CSS_Hashtable, i, -31 - j)

                    if s == null then
                        set s = "Not Socketed"
                    endif

                    call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + "Socket " + "#" + I2S (j + 1) + ": " + "|r" + udg_CSS_String[11] + s + "|r")
                    set s = ""
                    set j = j + 1
                endloop

            endif

            set it = null
        endif

        set u = null
    endif

    call DestroyGroup (g)
    set g = null
    set p = null

    return false
endfunction

// Item Info Panel

function CSS_ItemInfoPanel takes nothing returns boolean
    local group g = CreateGroup ()
    local item it
    local unit u
    local integer i
    local integer j = 0
    local player p = GetTriggerPlayer ()
    local integer k
    local integer l
    local string s1
    local string s2

    call GroupEnumUnitsSelected(g, p, null)

    if CountUnitsInGroup (g) > 1 then
        call CSS_SimError ("Invalid Selection")
        call DestroyGroup (g)

        set p = null
        set g = null
        return false
    else
        set u = FirstOfGroup (g)

        if not IsUnitOwnedByPlayer (u, p) then
            call CSS_SimError ("You must select an owned unit")
        else
            set it = UnitItemInSlot (u, S2I(SubString(GetEventPlayerChatString(), 10, StringLength(GetEventPlayerChatString()))) - 1)

            if it == null or not LoadBoolean (udg_CSS_Hashtable, GetItemTypeId (it), -4) then
                call CSS_SimError ("No item in chosen slot or chosen item is not registered with CSS")
            else

                set i = GetHandleId (it)
                set k = GetItemTypeId (it)

                if udg_CSS_SocketingEnabled then
                    call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + "Item Name: " + "|r" + udg_CSS_String[12] + GetItemName (it) + "|r")
                    call DisplayTimedTextToPlayer (p, 0, 0, 15, "\n")
                else
                    call DisplayTimedTextToPlayer (p, 0, 0, 15, "\n\n\n" + udg_CSS_String[25] + "Item Name: " + "|r" + udg_CSS_String[12] + GetItemName (it) + "|r")
                    call DisplayTimedTextToPlayer (p, 0, 0, 15, "\n")
                endif

                loop
                    exitwhen j > 10

                    if udg_CSS_SocketingEnabled then
                        set l = LoadInteger (udg_CSS_Hashtable, i, j)

                        if l > 0 then
                            set s2 = "+"
                        else
                            set s2 = ""
                        endif

                        if l - LoadInteger (udg_CSS_Hashtable, k, j) > 0 then
                            set s1 = udg_CSS_String[24] + " +" + I2S (l - LoadInteger (udg_CSS_Hashtable, k, j)) + "|r"
                        elseif l - LoadInteger (udg_CSS_Hashtable, k, j) < 0 then
                            set s1 = udg_CSS_String[24] + " -" + I2S (LoadInteger (udg_CSS_Hashtable, k, j) - l) + "|r"
                        else
                            set s1 = ""
                        endif

                        if j == 1 or j == 7 and s1 != "" then
                            set s1 = s1 + udg_CSS_String[24] + "%|r"
                        endif

                        if j == 1 or j == 7 then
                            call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + udg_CSS_String[j] + "|r" + udg_CSS_String[13+j] + s2 + I2S (LoadInteger (udg_CSS_Hashtable, k, j)) + "%|r" + s1)
                        else
                            call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + udg_CSS_String[j] + "|r" + udg_CSS_String[13+j] + s2 + I2S (LoadInteger (udg_CSS_Hashtable, k, j)) + "|r" + s1)
                        endif

                        set s1 = ""
                        set s2 = ""
                    else
                        set l = LoadInteger (udg_CSS_Hashtable, k, j)

                        if l > 0 then
                            set s2 = "+"
                        else
                            set s2 = ""
                        endif

                        if j == 1 or j == 7 then
                            call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + udg_CSS_String[j] + "|r" + udg_CSS_String[13+j] + s2 + I2S (LoadInteger (udg_CSS_Hashtable, k, j)) + "%|r")
                        else
                            call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + udg_CSS_String[j] + "|r" + udg_CSS_String[13+j] + s2 + I2S (LoadInteger (udg_CSS_Hashtable, k, j)) + "|r")
                        endif

                        set s2 = ""
                    endif

                    set j = j + 1
                endloop

                if udg_CSS_SocketingEnabled then
                    call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + "\nNumber of sockets: " + "|r" + udg_CSS_String[26] + I2S (LoadInteger (udg_CSS_Hashtable, k, -2)) + "|r")

                    if not HaveSavedInteger (udg_CSS_Hashtable, i, -2) then
                        call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + "Number of empty sockets: " + "|r" + udg_CSS_String[26] + I2S (LoadInteger (udg_CSS_Hashtable, k, -2)) + "|r")
                    else
                        call DisplayTimedTextToPlayer (p, 0, 0, 15, udg_CSS_String[25] + "Number of empty sockets: " + "|r" + udg_CSS_String[26] + I2S (LoadInteger (udg_CSS_Hashtable, i, -2)) + "|r")
                    endif
                endif

            endif

            set it = null
        endif

        set u = null
    endif

    call DestroyGroup (g)
    set g = null
    set p = null

    return false
endfunction

// Item sell event check

function CSS_ItemPawnCheck takes nothing returns boolean
    local unit u = GetTriggerUnit ()
    local integer i = GetHandleId (GetSoldItem ())
    local integer k = GetItemTypeId (GetSoldItem ())
    local trigger trig
    local integer t
    local integer j = 0
    local integer m = GetHandleId (u)

    loop
        exitwhen j > 10

        if udg_CSS_SocketingEnabled then
            call CSS_AddBonus(u, -LoadInteger (udg_CSS_Hashtable, i, j), j)
            call SaveInteger (udg_CSS_Hashtable, m, j - 11, LoadInteger (udg_CSS_Hashtable, m, j - 11) - LoadInteger (udg_CSS_Hashtable, i, j))
        else
            call CSS_AddBonus(u, -LoadInteger (udg_CSS_Hashtable, k, j), j)
            call SaveInteger (udg_CSS_Hashtable, m, j - 11, LoadInteger (udg_CSS_Hashtable, m, j - 11) - LoadInteger (udg_CSS_Hashtable, k, j))
        endif

        set j = j + 1
    endloop

    if LoadBoolean (udg_CSS_Hashtable, i, -6) then
        set trig = LoadTriggerHandle (udg_CSS_Hashtable, i, -10)
        set t = GetHandleId (trig)
        call SaveInteger (udg_CSS_Hashtable, t, 1, LoadInteger (udg_CSS_Hashtable, t, 1) + 1)

        if LoadInteger (udg_CSS_Hashtable, t, 1) == LoadInteger (udg_CSS_Hashtable, t, 0) then

            call DestroyTrigger (trig)
            call FlushChildHashtable (udg_CSS_Hashtable, t)

            if LoadTriggerHandle (udg_CSS_Hashtable, -10, -1) == trig then
                call RemoveSavedHandle (udg_CSS_Hashtable, -10, -1)
            endif

        endif

        set trig = null
        call FlushChildHashtable (udg_CSS_Hashtable, i)
    endif

    set u = null
    return false
endfunction

// Only needed if you decided to use Right Click Item Socketing

// Item socket event check

function CSS_ItemSocketCheck takes nothing returns boolean
    local item itemMain
    local item itemSocket
    local integer itemSlot
    local unit u
    local integer j = 0
    local integer i
    local integer k
    local integer l
    local integer m
    local integer n

    if GetOrderTargetItem() != null then
        set u = GetTriggerUnit()
        set itemSlot = GetIssuedOrderId() - 852002
        set itemMain = UnitItemInSlot (u, itemSlot)
        set itemSocket = GetOrderTargetItem()
        set i = GetItemTypeId (itemSocket)
        set k = GetItemTypeId (itemMain)
        set l = GetHandleId (itemMain)
        set m = GetHandleId (itemSocket)

        if not HaveSavedInteger (udg_CSS_Hashtable, l, -2) then
            call SaveInteger (udg_CSS_Hashtable, l, -2, LoadInteger (udg_CSS_Hashtable, k, -2))
        endif

        set n = LoadInteger (udg_CSS_Hashtable, l, -2)

        if itemMain != null and itemSocket != null and itemMain != itemSocket then

            if (LoadBoolean (udg_CSS_Hashtable, i, -3) and LoadBoolean (udg_CSS_Hashtable, k, -3)) or (not LoadBoolean (udg_CSS_Hashtable, i, -4) and LoadBoolean (udg_CSS_Hashtable, k, -3)) or (not LoadBoolean (udg_CSS_Hashtable, k, -4) and LoadBoolean (udg_CSS_Hashtable, i, -3)) or (not LoadBoolean (udg_CSS_Hashtable, i, -4) and not LoadBoolean (udg_CSS_Hashtable, k, -3)) or (not LoadBoolean (udg_CSS_Hashtable, k, -4) and not LoadBoolean (udg_CSS_Hashtable, i, -3)) or (LoadBoolean (udg_CSS_Hashtable, k, -7) and LoadBoolean (udg_CSS_Hashtable, i, -7)) then
                set itemSocket = null
                set itemMain = null
                set u = null
                return false
            endif

            if GetItemLevel (itemSocket) > udg_CSS_GemLevel and GetItemLevel (itemMain) < udg_CSS_GemLevel and n > 0 then

                loop
                    exitwhen j > 10
                    call SaveInteger (udg_CSS_Hashtable, l, j, LoadInteger (udg_CSS_Hashtable, l, j) + LoadInteger (udg_CSS_Hashtable, i, j))

                    if not udg_CSS_GemBonusBoolean and not udg_CSS_CustomSwitch then
                        call CSS_AddBonus(u, LoadInteger (udg_CSS_Hashtable, i, j), j)
                    endif

                    call SaveInteger (udg_CSS_Hashtable, GetHandleId (u), j - 11, LoadInteger (udg_CSS_Hashtable, GetHandleId (u), j - 11) + LoadInteger (udg_CSS_Hashtable, i, j))
                    set j = j + 1
                endloop

                call SaveStr (udg_CSS_Hashtable, l, -30 - LoadInteger (udg_CSS_Hashtable, k, -2) + n - 1, GetItemName(itemSocket))
                call CSS_SimNotification (GetItemName(itemMain) + " has been socketed with " + GetItemName(itemSocket) + " - " + I2S(n - 1) + " sockets left")
                call SaveBoolean (udg_CSS_Hashtable, m, -1, true)

                call SaveBoolean (udg_CSS_Hashtable, m, -1, false)
                call DestroyEffect (AddSpecialEffectTarget (CSS_ItemSocketEffect(), u, CSS_ISEAttachPoint ()))
                call SaveInteger (udg_CSS_Hashtable, l, -2, n - 1)

                set j = 0

                if udg_CSS_CustomSwitch and LoadInteger (udg_CSS_Hashtable, l, -2) == 0 then

                    loop
                        exitwhen j > 10
                        call CSS_AddBonus(u, LoadInteger (udg_CSS_Hashtable, l, j), j)
                        set j = j + 1
                    endloop

                endif

                set udg_CSS_Counter = udg_CSS_Counter + 1
                set udg_CSS_EventMainItemStacked[udg_CSS_Counter] = itemMain
                set udg_CSS_EventSocketItemStacked[udg_CSS_Counter] = itemSocket
                set udg_CSS_EventUnitStacked[udg_CSS_Counter] = u
                set udg_CSS_EventMainItem = itemMain
                set udg_CSS_EventSocketItem = itemSocket
                set udg_CSS_EventUnit = u
                set udg_EVENT_SOCKET_FINISH = 1
                set udg_EVENT_SOCKET_FINISH = 0
                set udg_CSS_EventMainItem = null
                set udg_CSS_EventSocketItem = null
                set udg_CSS_EventUnit = null
                set udg_CSS_EventMainItemStacked[udg_CSS_Counter] = null
                set udg_CSS_EventSocketItemStacked[udg_CSS_Counter] = null
                set udg_CSS_EventUnitStacked[udg_CSS_Counter] = null
                set udg_CSS_Counter = udg_CSS_Counter - 1

                call RemoveItem (itemSocket)

            elseif LoadInteger (udg_CSS_Hashtable, l, -2) == 0 and LoadBoolean (udg_CSS_Hashtable, k, -3) then
                call CSS_SimError ("Main item is fully socketed")
            endif
        endif

        set u = null
        set itemMain = null
        set itemSocket = null
    endif

    return false
endfunction

// Item drop event check

function CSS_ItemDropCheck takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local integer i = GetHandleId (GetManipulatedItem())
    local integer k = GetItemTypeId (GetManipulatedItem())
    local integer j = 0
    local integer m = GetHandleId (u)

    if not LoadBoolean (udg_CSS_Hashtable, i, -1) then

        if not LoadBoolean (udg_CSS_Hashtable, k, -3) and LoadBoolean (udg_CSS_Hashtable, k, -5) then
            set u = null
            return false
        endif

        if udg_CSS_CustomSwitch and (not HaveSavedInteger (udg_CSS_Hashtable, i, -2) or LoadInteger (udg_CSS_Hashtable, i, -2) != 0) then
            set u = null
            return false
        endif

        loop
            exitwhen j > 10

            if udg_CSS_SocketingEnabled then
                call CSS_AddBonus(u, -LoadInteger (udg_CSS_Hashtable, i, j), j)
                call SaveInteger (udg_CSS_Hashtable, m, j - 11, LoadInteger (udg_CSS_Hashtable, m, j - 11) - LoadInteger (udg_CSS_Hashtable, i, j))
            else
                call CSS_AddBonus(u, -LoadInteger (udg_CSS_Hashtable, k, j), j)
                call SaveInteger (udg_CSS_Hashtable, m, j - 11, LoadInteger (udg_CSS_Hashtable, m, j - 11) - LoadInteger (udg_CSS_Hashtable, k, j))
            endif

            set j = j + 1
        endloop

    endif

    set u = null
    return false
endfunction

// Only needed if you decided to use Right Click Item Socketing

// Function for clearing dead/removed items' hashtable

function CSS_Event_Fire takes nothing returns boolean
    local trigger trig = GetTriggeringTrigger ()
    local integer t = GetHandleId (trig)

    call SaveInteger (udg_CSS_Hashtable, t, 1, LoadInteger (udg_CSS_Hashtable, t, 1) + 1)

    if LoadInteger (udg_CSS_Hashtable, t, 1) == LoadInteger (udg_CSS_Hashtable, t, 0) then

        call DestroyTrigger (trig)
        call FlushChildHashtable (udg_CSS_Hashtable, t)

        if LoadTriggerHandle (udg_CSS_Hashtable, -10, -1) == trig then
            call RemoveSavedHandle (udg_CSS_Hashtable, -10, -1)
        endif

    endif

    call FlushChildHashtable (udg_CSS_Hashtable, GetHandleId (GetTriggerWidget()))
    set trig = null

    return false
endfunction

// Item acquisition event check

function CSS_ItemAcquireCheck takes nothing returns boolean
    local trigger t = LoadTriggerHandle(udg_CSS_Hashtable, -10, -1)
    local integer l = GetHandleId (t)
    local unit u = GetTriggerUnit()
    local integer i = GetItemTypeId(GetManipulatedItem())
    local integer k = GetHandleId(GetManipulatedItem())
    local integer j = 0

    if not LoadBoolean (udg_CSS_Hashtable, k, -6) and LoadBoolean (udg_CSS_Hashtable, i, -4) and udg_CSS_SocketingEnabled then

        if t == null or LoadInteger (udg_CSS_Hashtable, l, 0) == 100 then
            set t = CreateTrigger ()
            set l = GetHandleId (t)
            call SaveInteger (udg_CSS_Hashtable, l, 0, 1)
            call SaveInteger (udg_CSS_Hashtable, l, 1, 0)
            call SaveTriggerHandle (udg_CSS_Hashtable, -10, -1, t)
            call TriggerAddCondition (t, Condition(function CSS_Event_Fire))
        else
            call SaveInteger (udg_CSS_Hashtable, l, 0, LoadInteger (udg_CSS_Hashtable, l, 0) + 1)
        endif

        call SaveTriggerHandle (udg_CSS_Hashtable, k, -10, t)
        call TriggerRegisterDeathEvent (t, GetManipulatedItem())
        call SaveBoolean (udg_CSS_Hashtable, k, -6, true)
    endif

    if not LoadBoolean (udg_CSS_Hashtable, i, -5) then

        loop
            exitwhen j > 10

            if not HaveSavedInteger (udg_CSS_Hashtable, k, j) then
                call SaveInteger (udg_CSS_Hashtable, k, j, LoadInteger (udg_CSS_Hashtable, i, j))
            endif

            set j = j + 1
        endloop

        if udg_CSS_CustomSwitch and (not HaveSavedInteger (udg_CSS_Hashtable, k, -2) or LoadInteger (udg_CSS_Hashtable, k, -2) != 0) then
            set t = null
            set u = null
            return false
        endif

        set j = 0

        loop
            exitwhen j > 10

            if udg_CSS_SocketingEnabled then
                call CSS_AddBonus(u, LoadInteger (udg_CSS_Hashtable, k, j), j)
                call SaveInteger (udg_CSS_Hashtable, GetHandleId (u), j - 11, LoadInteger (udg_CSS_Hashtable, GetHandleId (u), j - 11) + LoadInteger (udg_CSS_Hashtable, k, j))
            else
                call CSS_AddBonus(u, LoadInteger (udg_CSS_Hashtable, i, j), j)
                call SaveInteger (udg_CSS_Hashtable, GetHandleId (u), j - 11, LoadInteger (udg_CSS_Hashtable, GetHandleId (u), j - 11) + LoadInteger (udg_CSS_Hashtable, i, j))
            endif

            set j = j + 1
        endloop

    endif

    set t = null
    set u = null
    return false
endfunction

// Item Database Initialize

function CSS_ItemInitialize takes integer itemRawCode, integer armorBonus, integer attackSpeedBonus, integer damageBonus, integer agilityBonus, integer intelligenceBonus, integer strengthBonus, integer lifeRegenBonus, integer manaRegenBonus, integer lifeBonus, integer manaBonus, integer sightRangeBonus, integer socket returns nothing
    local integer j = LoadInteger (udg_CSS_Hashtable, -5, -5)

    call SaveInteger (udg_CSS_Hashtable, -5, j, itemRawCode)
    call SaveInteger (udg_CSS_Hashtable, -5, -5, j + 1)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 0, armorBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 1, attackSpeedBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 2, damageBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 3, agilityBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 4, intelligenceBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 5, strengthBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 6, lifeRegenBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 7, manaRegenBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 8, lifeBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 9, manaBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 10, sightRangeBonus)
    call SaveBoolean (udg_CSS_Hashtable, itemRawCode, -4, true)

    if udg_CSS_SocketingEnabled then
        call SaveInteger (udg_CSS_Hashtable, itemRawCode, -2, socket)
        call SaveBoolean (udg_CSS_Hashtable, itemRawCode, -3, true)
    endif

endfunction

// Gem Database Initialize

function CSS_GemInitialize takes integer itemRawCode, integer armorBonus, integer attackSpeedBonus, integer damageBonus, integer agilityBonus, integer intelligenceBonus, integer strengthBonus, integer lifeRegenBonus, integer manaRegenBonus, integer lifeBonus, integer manaBonus, integer sightRangeBonus returns nothing
    local integer j = LoadInteger (udg_CSS_Hashtable, -5, -5)

    call SaveInteger (udg_CSS_Hashtable, -5, j, itemRawCode)
    call SaveInteger (udg_CSS_Hashtable, -5, -5, j + 1)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 0, armorBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 1, attackSpeedBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 2, damageBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 3, agilityBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 4, intelligenceBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 5, strengthBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 6, lifeRegenBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 7, manaRegenBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 8, lifeBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 9, manaBonus)
    call SaveInteger (udg_CSS_Hashtable, itemRawCode, 10, sightRangeBonus)
    call SaveBoolean (udg_CSS_Hashtable, itemRawCode, -4, true)

    if udg_CSS_SocketingEnabled then
        call SaveBoolean (udg_CSS_Hashtable, itemRawCode, -7, true)

        if not udg_CSS_GemBonusBoolean then
            call SaveBoolean (udg_CSS_Hashtable, itemRawCode, -5, true)
        endif
    endif
endfunction

//===========================================================================
function InitTrig_CSS_Item_Functions takes nothing returns nothing
    local trigger acquireItem = CreateTrigger()
    local trigger dropItem = CreateTrigger()
    local trigger itemInfo = CreateTrigger()
    local trigger itemSocketInfo = CreateTrigger()
    local trigger socketItem
    local trigger pawnItem
    local integer j = 0

    call SaveInteger (udg_CSS_Hashtable, -5, -5, 0)

    call TriggerRegisterAnyUnitEventBJ(acquireItem, EVENT_PLAYER_UNIT_PICKUP_ITEM)
    call TriggerAddCondition(acquireItem, Condition(function CSS_ItemAcquireCheck))
    call TriggerRegisterAnyUnitEventBJ(dropItem, EVENT_PLAYER_UNIT_DROP_ITEM)
    call TriggerAddCondition(dropItem, Condition(function CSS_ItemDropCheck))

    set udg_CSS_String[0] = "Armor Bonus: "
    set udg_CSS_String[1] = "Attack Speed Bonus: "
    set udg_CSS_String[2] = "Damage Bonus: "
    set udg_CSS_String[3] = "Agility Bonus: "
    set udg_CSS_String[4] = "Intelligence Bonus: "
    set udg_CSS_String[5] = "Strength Bonus: "
    set udg_CSS_String[6] = "Life Regen Bonus: "
    set udg_CSS_String[7] = "Mana Regen Bonus: "
    set udg_CSS_String[8] = "Life Bonus: "
    set udg_CSS_String[9] = "Mana Bonus: "
    set udg_CSS_String[10] = "Sight Range Bonus: "
 
    loop
        call TriggerRegisterPlayerChatEvent(itemInfo, Player(j), "-iteminfo", false)
        call TriggerRegisterPlayerChatEvent(itemSocketInfo, Player(j), "-itemsocketinfo", false)
        set j = j + 1
        exitwhen j > 15
    endloop

    call TriggerAddCondition(itemInfo, Condition(function CSS_ItemInfoPanel))
    call TriggerAddCondition(itemSocketInfo, Condition(function CSS_ItemInfoSocketPanel))

    if udg_CSS_SocketingEnabled then
        set socketItem = CreateTrigger ()
        set pawnItem = CreateTrigger ()

        call TriggerRegisterAnyUnitEventBJ(socketItem, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
        call TriggerAddCondition(socketItem, Condition(function CSS_ItemSocketCheck))
        call TriggerRegisterAnyUnitEventBJ(pawnItem, EVENT_PLAYER_UNIT_PAWN_ITEM)
        call TriggerAddCondition(pawnItem, Condition(function CSS_ItemPawnCheck))


        set socketItem = null
        set pawnItem = null
    endif

    set itemInfo = null
    set itemSocketInfo = null
    set acquireItem = null
    set dropItem = null

endfunction

JASS:
// Map header custom code

// SimError by Vexorian at wc3c.net

// Sim Error (modified)

function CSS_SimError takes string s returns nothing
    local string msg = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00" + s + "|r"
    local player ForPlayer = GetTriggerPlayer()
    local sound error = CreateSoundFromLabel("InterfaceError", false, false, false, 10, 10)

    if GetLocalPlayer() == ForPlayer then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(ForPlayer, 0.52, 0.96, 2.00, msg)
        call StartSound(error)
    endif

    set ForPlayer = null
endfunction

function CSS_SimNotification takes string s returns nothing
    local string msg = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cff32cd32" + s + "|r"
    local player ForPlayer = GetTriggerPlayer()
    local sound notify = CreateSoundFromLabel("ItemReward", false, false, false, 10, 10)

    if GetLocalPlayer() == ForPlayer then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(ForPlayer, 0.52, 0.96, 2.00, msg)
        call StartSound (notify)
    endif

    set ForPlayer = null
endfunction

// Bound Int by Magtheridon96 at hiveworkshop.com

// BoundInt

function BoundInt takes integer i, integer min, integer max returns integer
    return IMaxBJ(IMinBJ(i, max), min)
endfunction

// Bonus Handling Code

function CSS_AddBonus takes unit u, integer amount, integer bonusType returns nothing
    local integer max = udg_CSS_Power[17]
    local integer min = -udg_CSS_Power[17]
    local integer i = 16
    local integer j = LoadInteger (udg_CSS_Hashtable, GetHandleId(u), bonusType)

    if amount > max - 1 or amount < min then
        call CSS_SimError ("Value too high or too low")
        return
    endif

    if amount + j >= max or amount + j <= min then
        call CSS_SimError ("Current value at maximum or minimum")
        return
    endif

    set amount = amount + j
    call BoundInt (amount, min, max - 1)

    if bonusType < 0 or bonusType > 10 then
        call CSS_SimError ("CSS Error: Invalid bonus type (" + I2S(bonusType) + ")")
        return
    elseif bonusType == 8 or bonusType == 9 then

        if bonusType == 8 and amount*1. + GetUnitState(u, UNIT_STATE_MAX_LIFE) <= 0 then
            call CSS_SimError ("Unit's current max life is lower than the negative bonus amount. Unable to subtract.")
            return
        elseif bonusType == 9 and amount*1. + GetUnitState(u, UNIT_STATE_MAX_MANA) <= 0 then
            call CSS_SimError ("Unit's current max mana is lower than the negative bonus amount. Unable to subtract.")
            return
        endif

        call SaveInteger(udg_CSS_Hashtable, GetHandleId(u), bonusType, amount)

        if amount < 0 then
            set amount = max + amount
        else
            call UnitRemoveAbility(u, udg_CSS_Abilities[(bonusType + 1)*18 - 1])
        endif

        loop
            if amount >= udg_CSS_Power[i] then
                call UnitAddAbility(u, udg_CSS_Abilities[bonusType*18 + i])
                call UnitMakeAbilityPermanent(u, true, udg_CSS_Abilities[bonusType*18 + i])
                set amount = amount - udg_CSS_Power[i]
            else
                call UnitRemoveAbility(u, udg_CSS_Abilities[bonusType*18 + i])
            endif
        
            set i = i - 1
            exitwhen i < 0
        endloop

        if LoadInteger(udg_CSS_Hashtable, GetHandleId(u), bonusType) < 0 then
            call UnitAddAbility(u, udg_CSS_Abilities[(bonusType + 1)*18 - 1])
            call UnitMakeAbilityPermanent(u, true, udg_CSS_Abilities[(bonusType + 1)*18 - 1])
        endif

    else

        call SaveInteger(udg_CSS_Hashtable, GetHandleId(u), bonusType, amount)

        if amount < 0 then
            set amount = max + amount
            call UnitAddAbility(u, udg_CSS_Abilities[(bonusType + 1)*18 - 1])
            call UnitMakeAbilityPermanent(u, true, udg_CSS_Abilities[(bonusType + 1)*18 - 1])
        else
            call UnitRemoveAbility(u, udg_CSS_Abilities[(bonusType+1)*18 - 1])
        endif

        loop
            if amount >= udg_CSS_Power[i] then
                call UnitAddAbility(u, udg_CSS_Abilities[bonusType*18 + i])
                call UnitMakeAbilityPermanent(u, true, udg_CSS_Abilities[bonusType*18 + i])
                set amount = amount - udg_CSS_Power[i]
            else
                call UnitRemoveAbility(u, udg_CSS_Abilities[bonusType*18 + i])
            endif
        
            set i = i - 1
            exitwhen i < 0
        endloop

    endif
endfunction

JASS:
// CSS Implementation Macro based on BonusMod's Implementation Macro
// Full credit goes to Earth-Fury
// The text below is extracted from BonusMod's

// About these macros:
//
// The first parameter is the rawcode for the ability. The convention used here by default is:
// Zx followed by an uppercase letter, unique to the bonus, followed by a 0-9-a-z representing
// the base of two the ability applys.
//
// The second parameter is the display value of the ability. This is so that they all line up
// neatly in the object editor.
//
// The third parameter is the actual value the bonus ability applys.
//
// Note that you should copy this in to its own trigger, save once, close the map and re-open
// it in the World Editor, then disable the trigger you copied this in to. If you do not
// disable the trigger, saving will take an insane ammount of time every time you save. If you
// make any changes below, you can simply enable the trigger again, save again, then disable
// the trigger again.

// CSS - Armor
//============================================================================================
//! textmacro ArmorAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AId1 $RAWCODE$ Idef 1 $VALUE$ anam "CSS - Armor ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNHumanArmorUpOne.blp
//! endtextmacro

//! runtextmacro ArmorAbility("ZxA0", "+00001", "1")
//! runtextmacro ArmorAbility("ZxA1", "+00002", "2")
//! runtextmacro ArmorAbility("ZxA2", "+00004", "4")
//! runtextmacro ArmorAbility("ZxA3", "+00008", "8")
//! runtextmacro ArmorAbility("ZxA4", "+00016", "16")
//! runtextmacro ArmorAbility("ZxA5", "+00032", "32")
//! runtextmacro ArmorAbility("ZxA6", "+00064", "64")
//! runtextmacro ArmorAbility("ZxA7", "+00128", "128")
//! runtextmacro ArmorAbility("ZxA8", "+00256", "256")
//! runtextmacro ArmorAbility("ZxA9", "+00512", "512")
//! runtextmacro ArmorAbility("ZxAa", "+01024", "1024")
//! runtextmacro ArmorAbility("ZxAb", "+02048", "2048")
//! runtextmacro ArmorAbility("ZxAc", "+04096", "4096")
//! runtextmacro ArmorAbility("ZxAd", "+08192", "8192")
//! runtextmacro ArmorAbility("ZxAe", "+16384", "16384")
//! runtextmacro ArmorAbility("ZxAf", "+32768", "32768")
//! runtextmacro ArmorAbility("ZxAg", "+65536", "65536")
//! runtextmacro ArmorAbility("ZxAh", "-131072", "-131072")

// CSS - Damage
//============================================================================================
//! textmacro DamageAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AItg $RAWCODE$ Iatt 1 $VALUE$ anam "CSS - Damage ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNClawsOfAttack.blp
//! endtextmacro

//! runtextmacro DamageAbility("ZxB0", "+00001", "1")
//! runtextmacro DamageAbility("ZxB1", "+00002", "2")
//! runtextmacro DamageAbility("ZxB2", "+00004", "4")
//! runtextmacro DamageAbility("ZxB3", "+00008", "8")
//! runtextmacro DamageAbility("ZxB4", "+00016", "16")
//! runtextmacro DamageAbility("ZxB5", "+00032", "32")
//! runtextmacro DamageAbility("ZxB6", "+00064", "64")
//! runtextmacro DamageAbility("ZxB7", "+00128", "128")
//! runtextmacro DamageAbility("ZxB8", "+00256", "256")
//! runtextmacro DamageAbility("ZxB9", "+00512", "512")
//! runtextmacro DamageAbility("ZxBa", "+01024", "1024")
//! runtextmacro DamageAbility("ZxBb", "+02048", "2048")
//! runtextmacro DamageAbility("ZxBc", "+04096", "4096")
//! runtextmacro DamageAbility("ZxBd", "+08192", "8192")
//! runtextmacro DamageAbility("ZxBe", "+16384", "16384")
//! runtextmacro DamageAbility("ZxBf", "+32768", "32768")
//! runtextmacro DamageAbility("ZxBg", "+65536", "65536")
//! runtextmacro DamageAbility("ZxBh", "-131072", "-131072")

// CSS - Sight Range
//============================================================================================
//! textmacro SightRangeAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIsi $RAWCODE$ Isib 1 $VALUE$ anam "CSS - Sight Range ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNTelescope.blp
//! endtextmacro

//! runtextmacro SightRangeAbility("ZxC0", "+00001", "1")
//! runtextmacro SightRangeAbility("ZxC1", "+00002", "2")
//! runtextmacro SightRangeAbility("ZxC2", "+00004", "4")
//! runtextmacro SightRangeAbility("ZxC3", "+00008", "8")
//! runtextmacro SightRangeAbility("ZxC4", "+00016", "16")
//! runtextmacro SightRangeAbility("ZxC5", "+00032", "32")
//! runtextmacro SightRangeAbility("ZxC6", "+00064", "64")
//! runtextmacro SightRangeAbility("ZxC7", "+00128", "128")
//! runtextmacro SightRangeAbility("ZxC8", "+00256", "256")
//! runtextmacro SightRangeAbility("ZxC9", "+00512", "512")
//! runtextmacro SightRangeAbility("ZxCa", "+01024", "1024")
//! runtextmacro SightRangeAbility("ZxCb", "+02048", "2048")
//! runtextmacro SightRangeAbility("ZxCc", "+04096", "4096")
//! runtextmacro SightRangeAbility("ZxCd", "+08192", "8192")
//! runtextmacro SightRangeAbility("ZxCe", "+16384", "16384")
//! runtextmacro SightRangeAbility("ZxCf", "+32768", "32768")
//! runtextmacro SightRangeAbility("ZxCg", "+65536", "65536")
//! runtextmacro SightRangeAbility("ZxCh", "-131072", "-131072")

// CSS - Max Mana
//============================================================================================
//! textmacro MaxManaAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AImz $RAWCODE$ Iman 1 $VALUE$ anam "CSS - Max Mana ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNPendantOfMana.blp
//! endtextmacro

//! runtextmacro MaxManaAbility("ZxD0", "+00001", "1")
//! runtextmacro MaxManaAbility("ZxD1", "+00002", "2")
//! runtextmacro MaxManaAbility("ZxD2", "+00004", "4")
//! runtextmacro MaxManaAbility("ZxD3", "+00008", "8")
//! runtextmacro MaxManaAbility("ZxD4", "+00016", "16")
//! runtextmacro MaxManaAbility("ZxD5", "+00032", "32")
//! runtextmacro MaxManaAbility("ZxD6", "+00064", "64")
//! runtextmacro MaxManaAbility("ZxD7", "+00128", "128")
//! runtextmacro MaxManaAbility("ZxD8", "+00256", "256")
//! runtextmacro MaxManaAbility("ZxD9", "+00512", "512")
//! runtextmacro MaxManaAbility("ZxDa", "+01024", "1024")
//! runtextmacro MaxManaAbility("ZxDb", "+02048", "2048")
//! runtextmacro MaxManaAbility("ZxDc", "+04096", "4096")
//! runtextmacro MaxManaAbility("ZxDd", "+08192", "8192")
//! runtextmacro MaxManaAbility("ZxDe", "+16384", "16384")
//! runtextmacro MaxManaAbility("ZxDf", "+32768", "32768")
//! runtextmacro MaxManaAbility("ZxDg", "+65536", "65536")
//! runtextmacro MaxManaAbility("ZxDh", "-131072", "-131072")

// CSS - Max Life
//============================================================================================
//! textmacro MaxLifeAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIlf $RAWCODE$ Ilif 1 $VALUE$ anam "CSS - Max Life ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNPeriapt1.blp
//! endtextmacro

//! runtextmacro MaxLifeAbility("ZxE0", "+00001", "1")
//! runtextmacro MaxLifeAbility("ZxE1", "+00002", "2")
//! runtextmacro MaxLifeAbility("ZxE2", "+00004", "4")
//! runtextmacro MaxLifeAbility("ZxE3", "+00008", "8")
//! runtextmacro MaxLifeAbility("ZxE4", "+00016", "16")
//! runtextmacro MaxLifeAbility("ZxE5", "+00032", "32")
//! runtextmacro MaxLifeAbility("ZxE6", "+00064", "64")
//! runtextmacro MaxLifeAbility("ZxE7", "+00128", "128")
//! runtextmacro MaxLifeAbility("ZxE8", "+00256", "256")
//! runtextmacro MaxLifeAbility("ZxE9", "+00512", "512")
//! runtextmacro MaxLifeAbility("ZxEa", "+01024", "1024")
//! runtextmacro MaxLifeAbility("ZxEb", "+02048", "2048")
//! runtextmacro MaxLifeAbility("ZxEc", "+04096", "4096")
//! runtextmacro MaxLifeAbility("ZxEd", "+08192", "8192")
//! runtextmacro MaxLifeAbility("ZxEe", "+16384", "16384")
//! runtextmacro MaxLifeAbility("ZxEf", "+32768", "32768")
//! runtextmacro MaxLifeAbility("ZxEg", "+65536", "65536")
//! runtextmacro MaxLifeAbility("ZxEh", "-131072", "-131072")

// CSS - Strength
//============================================================================================
//! textmacro HeroStrAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIa1 $RAWCODE$ Iagi 1 0 Iint 1 0 Istr 1 $VALUE$ anam "CSS - Hero STR ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNGauntletsOfOgrePower.blp
//! endtextmacro

//! runtextmacro HeroStrAbility("ZxF0", "+00001", "1")
//! runtextmacro HeroStrAbility("ZxF1", "+00002", "2")
//! runtextmacro HeroStrAbility("ZxF2", "+00004", "4")
//! runtextmacro HeroStrAbility("ZxF3", "+00008", "8")
//! runtextmacro HeroStrAbility("ZxF4", "+00016", "16")
//! runtextmacro HeroStrAbility("ZxF5", "+00032", "32")
//! runtextmacro HeroStrAbility("ZxF6", "+00064", "64")
//! runtextmacro HeroStrAbility("ZxF7", "+00128", "128")
//! runtextmacro HeroStrAbility("ZxF8", "+00256", "256")
//! runtextmacro HeroStrAbility("ZxF9", "+00512", "512")
//! runtextmacro HeroStrAbility("ZxFa", "+01024", "1024")
//! runtextmacro HeroStrAbility("ZxFb", "+02048", "2048")
//! runtextmacro HeroStrAbility("ZxFc", "+04096", "4096")
//! runtextmacro HeroStrAbility("ZxFd", "+08192", "8192")
//! runtextmacro HeroStrAbility("ZxFe", "+16384", "16384")
//! runtextmacro HeroStrAbility("ZxFf", "+32768", "32768")
//! runtextmacro HeroStrAbility("ZxFg", "+65536", "65536")
//! runtextmacro HeroStrAbility("ZxFh", "-131072", "-131072")

// CSS - Agility
//============================================================================================
//! textmacro HeroAgiAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIa1 $RAWCODE$ Iagi 1 $VALUE$ Iint 1 0 Istr 1 0 anam "CSS - Hero AGI ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNSlippersOfAgility.blp
//! endtextmacro

//! runtextmacro HeroAgiAbility("ZxG0", "+00001", "1")
//! runtextmacro HeroAgiAbility("ZxG1", "+00002", "2")
//! runtextmacro HeroAgiAbility("ZxG2", "+00004", "4")
//! runtextmacro HeroAgiAbility("ZxG3", "+00008", "8")
//! runtextmacro HeroAgiAbility("ZxG4", "+00016", "16")
//! runtextmacro HeroAgiAbility("ZxG5", "+00032", "32")
//! runtextmacro HeroAgiAbility("ZxG6", "+00064", "64")
//! runtextmacro HeroAgiAbility("ZxG7", "+00128", "128")
//! runtextmacro HeroAgiAbility("ZxG8", "+00256", "256")
//! runtextmacro HeroAgiAbility("ZxG9", "+00512", "512")
//! runtextmacro HeroAgiAbility("ZxGa", "+01024", "1024")
//! runtextmacro HeroAgiAbility("ZxGb", "+02048", "2048")
//! runtextmacro HeroAgiAbility("ZxGc", "+04096", "4096")
//! runtextmacro HeroAgiAbility("ZxGd", "+08192", "8192")
//! runtextmacro HeroAgiAbility("ZxGe", "+16384", "16384")
//! runtextmacro HeroAgiAbility("ZxGf", "+32768", "32768")
//! runtextmacro HeroAgiAbility("ZxGg", "+65536", "65536")
//! runtextmacro HeroAgiAbility("ZxGh", "-131072", "-131072")

// CSS - Intelligence
//============================================================================================
//! textmacro HeroIntAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIa1 $RAWCODE$ Iagi 1 0 Iint 1 $VALUE$ Istr 1 0 anam "CSS - Hero INT ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNMantle.blp
//! endtextmacro

//! runtextmacro HeroIntAbility("ZxH0", "+00001", "1")
//! runtextmacro HeroIntAbility("ZxH1", "+00002", "2")
//! runtextmacro HeroIntAbility("ZxH2", "+00004", "4")
//! runtextmacro HeroIntAbility("ZxH3", "+00008", "8")
//! runtextmacro HeroIntAbility("ZxH4", "+00016", "16")
//! runtextmacro HeroIntAbility("ZxH5", "+00032", "32")
//! runtextmacro HeroIntAbility("ZxH6", "+00064", "64")
//! runtextmacro HeroIntAbility("ZxH7", "+00128", "128")
//! runtextmacro HeroIntAbility("ZxH8", "+00256", "256")
//! runtextmacro HeroIntAbility("ZxH9", "+00512", "512")
//! runtextmacro HeroIntAbility("ZxHa", "+01024", "1024")
//! runtextmacro HeroIntAbility("ZxHb", "+02048", "2048")
//! runtextmacro HeroIntAbility("ZxHc", "+04096", "4096")
//! runtextmacro HeroIntAbility("ZxHd", "+08192", "8192")
//! runtextmacro HeroIntAbility("ZxHe", "+16384", "16384")
//! runtextmacro HeroIntAbility("ZxHf", "+32768", "32768")
//! runtextmacro HeroIntAbility("ZxHg", "+65536", "65536")
//! runtextmacro HeroIntAbility("ZxHh", "-131072", "-131072")

// CSS - Attack Speed
//============================================================================================
//! textmacro AttackSpeedAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIsx $RAWCODE$ Isx1 1 $VALUE$ anam "CSS - Attack Speed ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNGlove.blp
//! endtextmacro

//! runtextmacro AttackSpeedAbility("ZxI0", "+00001", "0.01")
//! runtextmacro AttackSpeedAbility("ZxI1", "+00002", "0.02")
//! runtextmacro AttackSpeedAbility("ZxI2", "+00004", "0.04")
//! runtextmacro AttackSpeedAbility("ZxI3", "+00008", "0.08")
//! runtextmacro AttackSpeedAbility("ZxI4", "+00016", "0.16")
//! runtextmacro AttackSpeedAbility("ZxI5", "+00032", "0.32")
//! runtextmacro AttackSpeedAbility("ZxI6", "+00064", "0.64")
//! runtextmacro AttackSpeedAbility("ZxI7", "+00128", "1.28")
//! runtextmacro AttackSpeedAbility("ZxI8", "+00256", "2.56")
//! runtextmacro AttackSpeedAbility("ZxI9", "+00512", "5.12")
//! runtextmacro AttackSpeedAbility("ZxIa", "+01024", "10.24")
//! runtextmacro AttackSpeedAbility("ZxIb", "+02048", "20.48")
//! runtextmacro AttackSpeedAbility("ZxIc", "+04096", "40.96")
//! runtextmacro AttackSpeedAbility("ZxId", "+08192", "81.92")
//! runtextmacro AttackSpeedAbility("ZxIe", "+16384", "163.84")
//! runtextmacro AttackSpeedAbility("ZxIf", "+32768", "327.68")
//! runtextmacro AttackSpeedAbility("ZxIg", "+65536", "655.36")
//! runtextmacro AttackSpeedAbility("ZxIh", "-131072", "-1310.72")

// CSS - Life Regeneration
//============================================================================================
//! textmacro LifeRegenAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a Arel $RAWCODE$ Ihpr 1 $VALUE$ anam "CSS - Life Regen ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNRingSkull.blp
//! endtextmacro

//! runtextmacro LifeRegenAbility("ZxJ0", "+00001", "1")
//! runtextmacro LifeRegenAbility("ZxJ1", "+00002", "2")
//! runtextmacro LifeRegenAbility("ZxJ2", "+00004", "4")
//! runtextmacro LifeRegenAbility("ZxJ3", "+00008", "8")
//! runtextmacro LifeRegenAbility("ZxJ4", "+00016", "16")
//! runtextmacro LifeRegenAbility("ZxJ5", "+00032", "32")
//! runtextmacro LifeRegenAbility("ZxJ6", "+00064", "64")
//! runtextmacro LifeRegenAbility("ZxJ7", "+00128", "128")
//! runtextmacro LifeRegenAbility("ZxJ8", "+00256", "256")
//! runtextmacro LifeRegenAbility("ZxJ9", "+00512", "512")
//! runtextmacro LifeRegenAbility("ZxJa", "+01024", "1024")
//! runtextmacro LifeRegenAbility("ZxJb", "+02048", "2048")
//! runtextmacro LifeRegenAbility("ZxJc", "+04096", "4096")
//! runtextmacro LifeRegenAbility("ZxJd", "+08192", "8192")
//! runtextmacro LifeRegenAbility("ZxJe", "+16384", "16384")
//! runtextmacro LifeRegenAbility("ZxJf", "+32768", "32768")
//! runtextmacro LifeRegenAbility("ZxJg", "+65536", "65536")
//! runtextmacro LifeRegenAbility("ZxJh", "-131072", "-131072")

// CSS - Mana Regeneration
//============================================================================================
//! textmacro ManaRegenAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIrm $RAWCODE$ Imrp 1 $VALUE$ anam "CSS - Mana Regen ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNSobiMask.blp
//! endtextmacro

//! runtextmacro ManaRegenAbility("ZxK0", "+00001", "0.01")
//! runtextmacro ManaRegenAbility("ZxK1", "+00002", "0.02")
//! runtextmacro ManaRegenAbility("ZxK2", "+00004", "0.04")
//! runtextmacro ManaRegenAbility("ZxK3", "+00008", "0.08")
//! runtextmacro ManaRegenAbility("ZxK4", "+00016", "0.16")
//! runtextmacro ManaRegenAbility("ZxK5", "+00032", "0.32")
//! runtextmacro ManaRegenAbility("ZxK6", "+00064", "0.64")
//! runtextmacro ManaRegenAbility("ZxK7", "+00128", "1.28")
//! runtextmacro ManaRegenAbility("ZxK8", "+00256", "2.56")
//! runtextmacro ManaRegenAbility("ZxK9", "+00512", "5.12")
//! runtextmacro ManaRegenAbility("ZxKa", "+01024", "10.24")
//! runtextmacro ManaRegenAbility("ZxKb", "+02048", "20.48")
//! runtextmacro ManaRegenAbility("ZxKc", "+04096", "40.96")
//! runtextmacro ManaRegenAbility("ZxKd", "+08192", "81.92")
//! runtextmacro ManaRegenAbility("ZxKe", "+16384", "163.84")
//! runtextmacro ManaRegenAbility("ZxKf", "+32768", "327.68")
//! runtextmacro ManaRegenAbility("ZxKg", "+65536", "655.36")
//! runtextmacro ManaRegenAbility("ZxKh", "-131072", "-1310.72")

// Don't let a //! external command be the last line in a trigger!

  • Color Code Setting
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Color codes for the item info panel can be set here --------
      • -------- If you want a text to be colored white as default, set the color code to |cffffffff --------
      • -------- Don't touch the indexes, modify the value only --------
      • -------- Socket Item Name --------
      • Set CSS_String[11] = |cffff0000
      • -------- Item Name --------
      • Set CSS_String[12] = |cff32cd32
      • -------- Bonus Stat --------
      • Set CSS_String[24] = |cFF0000FF
      • -------- Other Text --------
      • Set CSS_String[25] = |cffffffff
      • -------- Numbers other than stat --------
      • Set CSS_String[26] = |cFFFFA500
      • -------- Color Codes for Stats --------
      • -------- Armor --------
      • Set CSS_String[13] = |cFFFFA500
      • -------- Attack Speed --------
      • Set CSS_String[14] = |cFF800080
      • -------- Damage --------
      • Set CSS_String[15] = |CFF7EBFF1
      • -------- Agility --------
      • Set CSS_String[16] = |cFFFFD700
      • -------- Intelligence --------
      • Set CSS_String[17] = |cFF000000
      • -------- Strength --------
      • Set CSS_String[18] = |cff00ff00
      • -------- Life Regen --------
      • Set CSS_String[19] = |cff32cd32
      • -------- Mana Regen --------
      • Set CSS_String[20] = |CFFFFFF01
      • -------- Life --------
      • Set CSS_String[21] = |CFF1CB619
      • -------- Mana --------
      • Set CSS_String[22] = |CFF106246
      • -------- Sight Range --------
      • Set CSS_String[23] = |CFF4E2A04
  • Variable Creation
    • Events
    • Conditions
    • Actions
      • Set CSS_Abilities[0] = Acid Bomb
      • Set CSS_GemBonusBoolean = False
      • Set CSS_GemLevel = 0
      • Set CSS_Hashtable = (Last created hashtable)
      • Set CSS_Power[0] = 0
      • Set CSS_PreloadBoolean = False
      • Set CSS_SocketingEnabled = False
      • Set EVENT_SOCKET_FINISH = 0.00
      • Set CSS_EventMainItem = (Last created item)
      • Set CSS_EventSocketItem = (Last created item)
      • Set CSS_EventUnit = (Last created unit)
      • Set CSS_EventMainItemStacked[0] = (Last created item)
      • Set CSS_EventSocketItemStacked[0] = (Last created item)
      • Set CSS_EventUnitStacked[0] = (Last created unit)
      • Set CSS_Counter = 0
Known Issue: May bug if a unit somehow surpasses the bonus limit in some occasion.
-> Fix: Don't allow a unit to achieve near-limit for a stat i.e keep it at a reasonable level.


Currently the macro script will not work on Windows 64 computers because of a Microsoft patch and/or Warcraft III patch that broke LUA.



How easy can you register an item? For example I wish to register my "Alleria's Flute of Accuracy" (raw code 'afac') with these following stats:
  • 150 bonus Armor.
  • 400% bonus Attack Speed.
  • 800 bonus Damage.
  • 15 bonus Agility.
  • 45 bonus Intelligence.
  • 55 bonus Strength.
  • 85 bonus Life Regen.
  • 100% bonus Mana Regen.
  • 100 bonus Life.
  • 1000 bonus Mana.
  • 10 bonus Sight Range.
  • 3 sockets
Instead of creating 11 item abilities, I would only need a few trigger lines:
  • Item Declaration
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Item Declaration --------
      • Custom script: call CSS_ItemInitialize('afac', 150, 400, 800, 15, 45, 55, 85, 100, 100, 1000, 10, 3)
      • -------- Item Declaration End --------
      • -------- After item declaration, add the custom script below to prevent first pickup lag. --------
      • -------- Item Preload --------
      • Custom script: call CSS_ItemPreload()
      • -------- Item Preload End --------

+ v1.0: Initial release.
+ v1.0a: Temporarily remove the Object Merger Macro
+ v1.0b: Fixed a bug with sight range bonus plus making some changes to the test map for better testing.
+ v1.1: Revamped the code almost completely according to Mag's extremely helpful review. Thanks very much. Object Merger Macro is also readded.
+ v1.1a: Added credit for SimError by Vexorian. Now uses the BoundInt snippet by Magtheridon96.
+ v1.2: Added item socketing. Fixed some bugs.
+ v1.3: Fixed all bugs related to item socketing.
+ v1.4: Added a boolean to toggle Right Click Item Socketing on/off. Now supports quick and easy item info panel through chat command.
+ Quick Update: Added a color code setting trigger for item info panel.
+ Fix: Fixed an item pawn bug found by Almia.
+ v1.5: Added a function for refreshing item bonuses.
+ v1.5b: Fixed a minor bug with item info panel.
+ v1.5c: Fixed a bug with item socket info panel.
+ v1.5d: Added item info panel support for core system functionality i.e item stat registration.
+ v1.5e: Added variable creation method and a new sound when a unit successfully socket an item.
+ v1.5f: Added a prefix for SimError to avoid collision. Fixed a minor bug with Item Socket Info.
+ v1.5g: Added custom event response for successful item socketing.
+ v1.5h: Fixed a possible desync issue with item info panel.
+ v1.5i: Fixed a critical bug with selling items. BonusMod alternative is now a standalone part of the system.
+ ==Quick Fix==: Fixed a minor issue with a test trigger.
+ v1.5j: Fixed a critical bug with Life Regen abilities found by leonguyen112.
+ v1.5g: Added a new boolean that prevent items from giving bonuses until fully socketed.


Another thing I would like to point out is that I left the Implementation Macro in the test map. If you need to use this system, just ask a friend who uses a Windows version that doesn't conflict with the LUA object generator to run the macro and create the abilities for you.

One may wonder, why is this system called "Custom Stat" when it mainly deals with items rather than stats?
- Well tbh it was originally only a plain custom stat system but now that it has a lot of extensions, I am too lazy to do a complete function prefix change for the system itself :p

Thanks to Almia, -Kobas- and leonguyen112 for spotting bugs with the system.


FINAL WORDS
+All feedback, testing, criticism, suggestions, etc. are welcome as this is my first system submission. Thanks in advance.
+If you need help with this system, contact me or post in this thread.
+Credit is not required but recommended.
+Humans are bound to make mistakes. Don't hesitate to tell me if you find any bug.

Keywords:
item, bonus, stat, system, socketing, right, click, ORPG, RPG, custom, armor, hp, mp, damage, sight, life, mana, whatever, blah blah blah
Contents

Custom Stat System v1.5g (Map)

Reviews
17:28, 17th Feb 2013 Purgeandfire: Approved and highly recommended. This system is now completely flexible, allowing you to implement the bonus mod separately. It is very well documented and a lot of work has been done to get it bug-free. The...

Moderator

M

Moderator

17:28, 17th Feb 2013
Purgeandfire: Approved and highly recommended. This system is now completely flexible, allowing you to implement the bonus mod separately. It is very well documented and a lot of work has been done to get it bug-free. The examples are great and should be sufficient to help any GUI'er use this. :)
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Macros do not work on x64 computers due to a windows update. This spell will be rejected. (Check the Nov. 2012 news batch)

Notice: All scripts that use ObjectMerger and Lua for Object Generation are currently unacceptable because of a Microsoft patch and/or Warcraft III patch that broke Lua. This is only a temporary measure.

you cant create 1 ability with multiple levels because you can only give unit 1 ability with unique rawcode so you wont be able to stack those effects as you can with different abilities with same effect

Thats not the problem with multi-level abilities. The problem is that they lag like hell :) (having a unit with 8 1-level abilities is faster than having him with 2 10-level abiiteis)

If multi-level abilities didnt lag, than someone with a non-broken computer would just make 1 2-million level bonus for every ability, but the map itself would be closer to a gig.
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
Thank for the useful feedbacks and comments. I am going to apply approriate actions as the situation demands.

@gorillabull: I think I mentioned how the macro is based on BonusMod's and full credit goes to Earth-Fury, no?

@Arhowk: thanks for sharing practical and necessary info.

@Chaosy: this extends off BonusMod's features to achieve simple, GUI-friendly registration of item passive stats. It also has the measure to counter the neg max life/mana bug that BonusMod lacks. And what are those 'systems that are already made' you are talking about?
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
If multi-level abilities didnt lag, than someone with a non-broken computer would just make 1 2-million level bonus for every ability, but the map itself would be closer to a gig.

do u tested?
i used 10 ability all with lv10, dont was any noticeable lagg at all, multilevel ability isnt just lv100 abilities.............

@Chaosy: this extends off BonusMod's features to achieve simple, GUI-friendly registration of item passive stats. It also has the measure to counter the neg max life/mana bug that BonusMod lacks. And what are those 'systems that are already made' you are talking about?

have few but not same, nice if have similiar systems with different solutions, because user can choose what he understand better or fit better to his map.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
do u tested?
i used 10 ability all with lv10, dont was any noticeable lagg at all, multilevel ability isnt just lv100 abilities.............



have few but not same, nice if have similiar systems with different solutions, because user can choose what he understand better or fit better to his map.

10 on one unit?

now with every bonus, 100 10 level abilites, on more than one unit
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
its depend how do u do..........

stat, mov speed = with trigger
max hp/mp aint that much either, overall what remain at unit that is only damage and attackspeed

have more solution depend how do u need the bonus is and what is the max cap on map

We are talking about green/red bonus so manipulation through trigger is out of the question here ;P

And as far as I am aware, your bringing down 9 stats to only 2 is a magic-like move tbh.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
We are talking about green/red bonus so manipulation through trigger is out of the question here ;P

And as far as I am aware, your bringing down 9 stats to only 2 is a magic-like move tbh.

thats just response about level, not about ur system because it is nice, but who dont need mui things, just mpi and dont need something complicated for them viable the ability level option because for mpi hp/mp regen (just example) enough a periodic trigger until if system is mui then ability could better.

sry for off
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Anyone with some MPQ knowledge could just copy and paste the abilities since you gave them a unique header :eek:
 
Level 7
Joined
Nov 15, 2009
Messages
225
I like this system. It works like it should and is mostly easy to use, even as a beginner.


You should add more info how to import stuff into another map. This is the hardest part for beginners and they will not spend hours to copy and paste single spells.


Another little thing, I recomment to delete the hero attribute spells.
You can modify it without using spells.

Hope I could help :)
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
I like this system. It works like it should and is mostly easy to use, even as a beginner.


You should add more info how to import stuff into another map. This is the hardest part for beginners and they will not spend hours to copy and paste single spells.


Another little thing, I recomment to delete the hero attribute spells.
You can modify it without using spells.

Hope I could help :)

Thanks for testing and providing such useful feedbacks.

About the Hero Attribute there is a bit of a misunderstanding as the bonus provided is displayed in green/red value, unlike the white number when triggered.
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
Like I already said, it's reminding me of my "Advanced Inventory Handling" system I did a while back (in 2009). I know you didn't copy, just makes me realize the history repeats itself and some people are already in my footsteps. Keep up your good work!

Thank you very much for your kind words. And yes, there shall always be ppl who will invent the wheel if they don't have it.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
could u make text appear for longer time?
i mean to this with long duration
JASS:
    call DisplayTimedTextToPlayer(Player(0), 0, 0, 30, "Type -dmg <amount> to add damage")

coz not appear at chatlog and after if someone is slow then must restart the map for try the another values because text disapear too fast and item bonus stat dont was write into their tooltip :) or just write into quest

also i guess better if dont disable black mask and fog of war because then peoples can test sight too :p


i like this system mainly coz jass and not vjass than other systems :D
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
could u make text appear for longer time?
i mean to this with long duration
JASS:
    call DisplayTimedTextToPlayer(Player(0), 0, 0, 30, "Type -dmg <amount> to add damage")

coz not appear at chatlog and after if someone is slow then must restart the map for try the another values because text disapear too fast and item bonus stat dont was write into their tooltip :) or just write into quest

also i guess better if dont disable black mask and fog of war because then peoples can test sight too :p


i like this system mainly coz jass and not vjass than other systems :D

Requests granted. Except for the item bonuses I recommend that you read up my examplary item declaration to find out what the bonuses are. You can try declaring one or two items and you will be familiar with this system in no time :)

And thanks for the compliment. I appreciate it.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
i just wrote that more handy if u add to item tooltop tip, anyway u swaped the mana and life regen bonuses

if i type life regen than that change mana regen and invers if i type mana regen coz u assigned the mana regen abilities in life regen function, same with mana regen function there u add life regen abilitites

  • Hero - Instantly revive Paladin 0022 <gen> at (Position of Paladin 0022 <gen>), Show revival graphics
leak

also could be usefull if u rename the test triggers :)
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
i just wrote that more handy if u add to item tooltop tip, anyway u swaped the mana and life regen bonuses

if i type life regen than that change mana regen and invers if i type mana regen coz u assigned the mana regen abilities in life regen function, same with mana regen function there u add life regen abilitites

  • Hero - Instantly revive Paladin 0022 <gen> at (Position of Paladin 0022 <gen>), Show revival graphics
leak

also could be usefull if u rename the test triggers :)

Thanks for pointing that out. Fixing now.

And btw it is called a test trigger, it is not a part of the system, only for better testing. I reckon that you would also find it annoying that ppl are judging the test triggers of your system, no?

EDIT: bug fixed.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
a question, why dont use a integer for check unit have already that ability or no?

JASS:
function AddHpRegen takes unit u, integer new returns nothing
    local integer array lifeRegenBonus
    local integer i = 11
    local integer a 
    local integer max = Pow2(12)
    local integer lifeRegen = LoadInteger(udg_h, GetHandleId(u), 9) + new
    call SaveInteger(udg_h, GetHandleId(u), 9, lifeRegen)
    set lifeRegenBonus[0] = 'A000' 
    set lifeRegenBonus[1] = 'A001' 
    set lifeRegenBonus[2] = 'A002' 
    set lifeRegenBonus[3] = 'A003' 
    set lifeRegenBonus[4] = 'A004' 
    set lifeRegenBonus[5] = 'A005' 
    set lifeRegenBonus[6] = 'A006' 
    set lifeRegenBonus[7] = 'A007' 
    set lifeRegenBonus[8] = 'A008' 
    set lifeRegenBonus[9] = 'A009' 
    set lifeRegenBonus[10] = 'A00A' 
    set lifeRegenBonus[11] = 'A00B' 
    set lifeRegenBonus[13] = 'A00C' 

    if lifeRegen < 0 then
        set lifeRegen = max + lifeRegen
        call UnitAddAbility(u, lifeRegenBonus[13])
        call UnitMakeAbilityPermanent(u, true, lifeRegenBonus[13])
    else
        call UnitRemoveAbility(u, lifeRegenBonus[13])
    endif

    loop
        set a = GetUnitAbilityLevel (u, lifeRegenBonus[i])
        if lifeRegen >= Pow2(i) and lifeRegen > 0 then
           if a == 0 then // add if unit dont have ability
            call UnitAddAbility(u, lifeRegenBonus[i])
            call UnitMakeAbilityPermanent(u, true, lifeRegenBonus[i])
           endif
        set lifeRegen = lifeRegen - Pow2(i)
        else
           if a > 0 then //remove only if unit got this ability
            call UnitRemoveAbility(u, lifeRegenBonus[i])
           endif
        endif
        
        set i = i - 1
        exitwhen i < 0
    endloop
endfunction
 
Last edited:
Level 17
Joined
Nov 13, 2006
Messages
1,814
its not problem or anything just question u dont thought about use only 1 function for modify the similiar things?
because only difference is the ability raw codes

so something like

JASS:
function BonusMod takes unit u, integer value, integer properties returns nothing
    local integer array lifeRegenBonus
    local integer i = 11
    local integer a 
    local integer max = Pow2(12)
    local integer NewAmount = LoadInteger(udg_h, GetHandleId(u), properties) + value
    if properties == 9 then
     set lifeRegenBonus[0] = 'A000' 
     set lifeRegenBonus[1] = 'A001' 
     set lifeRegenBonus[2] = 'A002' 
     set lifeRegenBonus[3] = 'A003' 
     set lifeRegenBonus[4] = 'A004' 
     set lifeRegenBonus[5] = 'A005' 
     set lifeRegenBonus[6] = 'A006' 
     set lifeRegenBonus[7] = 'A007' 
     set lifeRegenBonus[8] = 'A008' 
     set lifeRegenBonus[9] = 'A009' 
     set lifeRegenBonus[10] = 'A00A' 
     set lifeRegenBonus[11] = 'A00B' 
     set lifeRegenBonus[13] = 'A00C'
   elseif properties == 10 then
      ............
   endif
//rest action

endfunction
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
Oh sorry I misunderstood your idea, thought you are referring to the "integer that checks if the unit has the ability or not" thing. Yes indeed this is the original path that BonusMod uses with an integer as the identifier for the bonus functions but I want to take a different path, another way. It is not efficient and stuffs but I feel like I could understand it, use it, control it properly as I wanted to. If a mod tell me I must change this then I certainly will but for now I want to leave it that way, it is my first system ever after all.

I understood your point perfectly. It is completely my choice to take this path though and I don't want to stray from it. Thanks for your advice :)
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
u use ability index -1 but u can use same max than (ability index + 1)^2-1, its mean if u got 17 ability then 18^2-1 and i could be 17 (how much ability u got :) )

anyway u sometimes skiped a index and used it for special case
JASS:
    local integer i = 16
    local integer max = CSS_Powers(17)
    local integer damage = LoadInteger(udg_CSS_Hashtable, GetHandleId(u), 0)

    set damageBonus[0] = 'ZxB0'
    set damageBonus[1] = 'ZxB1'
    set damageBonus[2] = 'ZxB2'
    set damageBonus[3] = 'ZxB3'
    set damageBonus[4] = 'ZxB4'
    set damageBonus[5] = 'ZxB5'
    set damageBonus[6] = 'ZxB6'
    set damageBonus[7] = 'ZxB7'
    set damageBonus[8] = 'ZxB8'
    set damageBonus[9] = 'ZxB9'
    set damageBonus[10] = 'ZxBa'
    set damageBonus[11] = 'ZxBb'
    set damageBonus[12] = 'ZxBc'
    set damageBonus[13] = 'ZxBd'
    set damageBonus[14] = 'ZxBe'
    set damageBonus[15] = 'ZxBf'
    set damageBonus[16] = 'ZxBg'
    //where is the 17? :D
    set damageBonus[18] = 'ZxBh'

its just raise ur limit with custom stat from 4096->8191 for life regen example
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
its fine with fix :) good description, well organized,5/5.

(little off but why need preload the items if item abilities preloaded too?)

Thanks very much. However this version is bugged a little bit. I am gonna fix the bug plus uploading a new feature: item socketing (like the one in Diablo 2 :D)

Well preloading items is a must I am afraid, it must be done so that the pickup and drop check are initialized or there will be first use lag otherwise.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Thanks very much. However this version is bugged a little bit. I am gonna fix the bug plus uploading a new feature: item socketing (like the one in Diablo 2 :D)

Well preloading items is a must I am afraid, it must be done so that the pickup and drop check are initialized or there will be first use lag otherwise.

preloading not only for custom items needed?

(hehe slowly u start making a similiar map than me, i also started with custom stat, now i made full screen equipments with refine socket and charms craps :D)

go ahead (i hope that also only jass)
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
preloading not only for custom items needed?

(hehe slowly u start making a similiar map than me, i also started with custom stat, now i made full screen equipments with refine socket and charms craps :D)

go ahead (i hope that also only jass)

Yep. In my case you have to preload items.

Yes the socketing method is in JASS as usual. And this one utilizes the item-swap method rather than through an external mean (kinda like Diablo 2). Currently you can't unsocket or use runes though :p I think I will add rune on another day.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Yep. In my case you have to preload items.

Yes the socketing method is in JASS as usual. And this one utilizes the item-swap method rather than through an external mean (kinda like Diablo 2). Currently you can't unsocket or use runes though :p I think I will add rune on another day.

item swap, do you mean u make from every item more version only coz of sockets and when u add into item 1 socket then swap item?
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
item swap, do you mean u make from every item more version only coz of sockets and when u add into item 1 socket then swap item?

Uhm no. That would be going against this system's motto.

When I said "item swap" I was referring to the act of right-clicking on an item then left-click on another to swap their positions :p

In this case, you will right-click on the Gem then left-click on the item to socket. It is quick and easy enough :D
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Uhm no. That would be going against this system's motto.

When I said "item swap" I was referring to the act of right-clicking on an item then left-click on another to swap their positions :p

ah, i understand now what u mean under swap :D
whatever the main problem is with makeing maybe equipment system later, is the 6 slot limit in inventory because lets say atm u have 2 socket item and 1 equipment and already only 3 space left in inventory :/

another ideea is good, but for me that 6 slot limit annoyed, thats why i started with multiboard equipment system then everything remade to full screen inventory.
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
ah, i understand now what u mean under swap :D
whatever the main problem is with makeing maybe equipment system later, is the 6 slot limit in inventory because lets say atm u have 2 socket item and 1 equipment and already only 3 space left in inventory :/

another ideea is good, but for me that 6 slot limit annoyed, thats why i started with multiboard equipment system then everything remade to full screen inventory.

Eh? I don't understand what you mean by equipment system :p
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
i meant u 1st made a system what add custom stat, assigned to items, now u make sockets, soon (i guess because u going to that way :D) u will make equipment system[items categorized to weapons/armors etc and cant hold 2 from same type] :D

Probably not since I am just utilizing the power of my stat system to create extensions. Mainly to prove that it is not a copy of other BonusMod systems. That being said, it is obvious the equipment system isn't based on the stat system and thus I possibly won't do it.

But your system is awesome enough :D I can't hope to compete
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
Probably not since I am just utilizing the power of my stat system to create extensions. Mainly to prove that it is not a copy of other BonusMod systems. That being said, it is obvious the equipment system isn't based on the stat system and thus I possibly won't do it.

But your system is awesome enough :D I can't hope to compete

yes thats how i started my system too, 1st was only midifing the max hp/mp, then the dmg and attack speed and at end?
even when i added full screen inventory and made socket/refine another crap with sht load codes still got comment about it is a "copy" of kobas system, when i dont watched his system also was wrote myself the whole crap :p

ust a not, dont add effect to gem until not inserted to equipment/=item because that weird :D
example in diablo 2 too, when gem dont was inserted, just was in inventory in natural form, dont gived any stat bonus, only after player inserted into item :p

this was the previous version

http://www.hiveworkshop.com/forums/map-development-202/orpg-template-223745/#post2226807

ain't was perfect, but also not the 1st edition so u started with enough strong core
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
yes thats how i started my system too, 1st was only midifing the max hp/mp, then the dmg and attack speed and at end?
even when i added full screen inventory and made socket/refine another crap with sht load codes still got comment about it is a "copy" of kobas system, when i dont watched his system also was wrote myself the whole crap :p

ust a not, dont add effect to gem until not inserted to equipment/=item because that weird :D
example in diablo 2 too, when gem dont was inserted, just was in inventory in natural form, dont gived any stat bonus, only after player inserted into item :p

Well. Okay seems like a good suggestion. I will add a function to configure it i.e allow gems to give bonuses or not when not socketed.

Don't worry I also got one such comment from C***sy but I really don't care. The users will judge it for us.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
you could explain this?

JASS:
// SimError by Vexorian at wc3c.net

// Sim Error (modified)

function SimError takes string s returns nothing
    local string msg = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00" + s + "|r"
    local player ForPlayer = GetTriggerPlayer()
    local sound error = CreateSoundFromLabel("InterfaceError", false, false, false, 10, 10)

    if GetLocalPlayer() == ForPlayer then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(ForPlayer, 0.52, 0.96, 2.00, msg)
        call StartSound(error)
    endif

    set ForPlayer = null
endfunction

function SimNotification takes string s returns nothing
    local string msg = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cff32cd32" + s + "|r"
    local player ForPlayer = GetTriggerPlayer()

    if GetLocalPlayer() == ForPlayer then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(ForPlayer, 0.52, 0.96, 2.00, msg)
    endif

    set ForPlayer = null
endfunction


why use that instead the simple DisplayTimedTextToPlayer? i mean the getlocalplayer part, also i dont see event for them so idk if triggerplayer is work?

a problem, u attach data to item type id, result is if user use 2 item what got same item type id then system is screwed totally because u cant put nothing to 2nd

JASS:
LoadInteger (udg_CSS_Hashtable, k, -2)

use this

JASS:
LoadInteger (udg_CSS_Hashtable, GetHandleId(your item), -2)

if item is sold, destroyed then flush the item handle id

for me here started the totally new rewrited system, coz i attached every data to item handle id (dmg, level requiment, class requiment, stat requiment, attack speed, hp, model path if attachment villager map, price, self item, sockets)

(dont need negative value for hash index, u can use ofc just i think easier to handle the normal positive index, like item infor between 1-100, socket info 101-200 (example: 101=socket item type id, 102=the amount, 103 the 2nd socket item if it was inserted to item, item typeid, 104 the 2nd item amount))
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
you could explain this?

JASS:
// SimError by Vexorian at wc3c.net

// Sim Error (modified)

function SimError takes string s returns nothing
    local string msg = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00" + s + "|r"
    local player ForPlayer = GetTriggerPlayer()
    local sound error = CreateSoundFromLabel("InterfaceError", false, false, false, 10, 10)

    if GetLocalPlayer() == ForPlayer then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(ForPlayer, 0.52, 0.96, 2.00, msg)
        call StartSound(error)
    endif

    set ForPlayer = null
endfunction

function SimNotification takes string s returns nothing
    local string msg = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cff32cd32" + s + "|r"
    local player ForPlayer = GetTriggerPlayer()

    if GetLocalPlayer() == ForPlayer then
        call ClearTextMessages()
        call DisplayTimedTextToPlayer(ForPlayer, 0.52, 0.96, 2.00, msg)
    endif

    set ForPlayer = null
endfunction


why use that instead the simple DisplayTimedTextToPlayer? i mean the getlocalplayer part, also i dont see event for them so idk if triggerplayer is work?

a problem, u attach data to item type id, result is if user use 2 item what got same item type id then system is screwed totally because u cant put nothing to 2nd

JASS:
LoadInteger (udg_CSS_Hashtable, k, -2)

use this

JASS:
LoadInteger (udg_CSS_Hashtable, GetHandleId(your item), -2)

if item is sold, destroyed then flush the item handle id

for me here started the totally new rewrited system, coz i attached every data to item handle id (dmg, level requiment, class requiment, stat requiment, attack speed, hp, model path if attachment villager map, price, self item, sockets)

(dont need negative value for hash index, u can use ofc just i think easier to handle the normal positive index, like item infor between 1-100, socket info 101-200 (example: 101=socket item type id, 102=the amount, 103 the 2nd socket item if it was inserted to item, item typeid, 104 the 2nd item amount))

DisplayTimedTextToPlayer would require a loop through 15 players :p Plus this is much more convenient.

About the item type and item handle thing, here is a picture

http://www.hiveworkshop.com/forums/pastebin.php?id=zknxku

Test and see for yourself if you don't believe me.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
DisplayTimedTextToPlayer would require a loop through 15 players :p Plus this is much more convenient.

About the item type and item handle thing, here is a picture

http://www.hiveworkshop.com/forums/pastebin.php?id=zknxku

Test and see for yourself if you don't believe me.

i tested and dont work, you can test again, pick 2 same item type, insert socket to 1st one then insert another socket to 2nd one and see what happen

i dont heard yet about that loop, this is the jasscraft result , i thought if it is a native then dont loop inside
native DisplayTextToPlayer takes player toPlayer, real x, real y, string message returns nothing
native DisplayTimedTextToPlayer takes player toPlayer, real x, real y, real duration, string message returns nothing
 
Last edited:
Top