//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//* set t=Table.create() - instanceates a new table object
//* call t.destroy() - destroys it
//* t[1234567] - Get value for key 1234567
//* (zero if not assigned previously)
//* set t[12341]=32 - Assigning it.
//* call t.flush(12341) - Flushes the stored value, so it
//* doesn't use any more memory
//* t.exists(32) - Was key 32 assigned? Notice
//* that flush() unassigns values.
//* call t.reset() - Flushes the whole contents of the
//* Table.
//*
//* call t.destroy() - Does reset() and also recycles the id.
//*
//* If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//* You can use Table on structs' onInit if the struct is
//* placed in a library that requires Table or outside a library.
//*
//* You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//* set Table["thisstring"][ 7 ] = 2
//* set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//Feel free to change max instances if necessary, it will only affect allocation
//speed which shouldn't matter that much.
//=========================================================
private hashtable ht
endglobals
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushChildHashtable(ht, integer(this) )
endmethod
private method onDestroy takes nothing returns nothing
call this.reset()
endmethod
//=============================================================
// initialize it all.
//
private static method onInit takes nothing returns nothing
set ht = InitHashtable()
endmethod
endstruct
//Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
//! textmacro Table__make takes name, type, key
struct $name$ extends GTable
method operator [] takes $type$ key returns integer
return LoadInteger(ht, integer(this), $key$)
endmethod
method operator []= takes $type$ key, integer value returns nothing
call SaveInteger(ht, integer(this) ,$key$, value)
endmethod
method flush takes $type$ key returns nothing
call RemoveSavedInteger(ht, integer(this), $key$)
endmethod
method exists takes $type$ key returns boolean
return HaveSavedInteger( ht, integer(this) ,$key$)
endmethod
static method flush2D takes string firstkey returns nothing
call $name$(- StringHash(firstkey)).reset()
endmethod
static method operator [] takes string firstkey returns $name$
return $name$(- StringHash(firstkey) )
endmethod
endstruct
//! endtextmacro
//! runtextmacro Table__make("Table","integer","key" )
//! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
//! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//////////////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@ Bonus Mod
//@=======================================================================================
//@ Credits:
//@---------------------------------------------------------------------------------------
//@ Written by:
//@ dhk_undead_lord aka Anachron
//@ Based on the work of:
//@ Earth-Fury
//@ weaaddar
//@
//@ If you use this system, please credit all of the people mentioned above in your map.
//@=======================================================================================
//@ Bonus Mod Readme
//@---------------------------------------------------------------------------------------
//@
//@ BonusMod is a system for adding bonuses to a single unit. For example, you may wish
//@ to add a +40 damage bonus, or a -3 armor 'bonus'. Bonus mod works by adding abilitys
//@ to a unit which effect the particular stat by a power of two. By combining diffrent
//@ powers of two, you can reach any number between 0 and 2^(n+1) - 1, where n is the
//@ largest power of 2 used. Bonus mod can also apply negative bonuses, by adding an
//@ ability which has a 'bonus' of -2^(n+1), where again, n is the maximum power of 2.
//@ With the negative bonus, you can add anywhere between 1 and 2^(n+1)-1 of a bonus. This
//@ gives bonus mod a range of bonuses between -2^(n+1) and 2^(n+1)-1. By default, n is
//@ set at 11, giving us a range of bonuses between -4096 and +4095.
//@
//@---------------------------------------------------------------------------------------
//@ Adding Bonus Mod to your map:
//@
//@ Copy this library in to a trigger named "BonusMod" in your map.
//@
//@ After the script is copied, the hard part begins. You will have to transfer all of the
//@ bonus abilitys found in this map to yours. However, this is really easy to do if you
//@ are using the JASS NewGen editor. (Which you will have to be anyway, considering this
//@ system is written in vJASS.) Included with this library are macros for the Object
//@ Merger included in NewGen. Simply copy the Object Merger script included with this
//@ system in to your map in its own trigger. Save your map. (Saving will take a while.
//@ Up to 5 min if you have a slow computer.) Close your map, and reopen it. Disable the
//@ trigger you copied the ObjectMerger script in to.
//@ Your map now has all the abilitys it needs!
//@
//@---------------------------------------------------------------------------------------
//@ Functions:
//@
//@ boolean UnitSetBonus(unit <target unit>, integer <bonus type>, integer <bonus ammount>)
//@
//@ This function clears any previously applied bonus on <target unit>, setting the
//@ unit's bonus for <bonus type> to <bonus ammount>. <bonus type> should be one of the
//@ integer type constants below. This function will return false if the desired bonus is
//@ not a valid bonus type, or out of the range of bonuses that can be applied.
//@
//@ integer UnitGetBonus(unit <target unit>, integer <bonus type>)
//@
//@ Returns the bonus ammount of <bonus type> currently applied to <target unit>.
//@
//@ boolean UnitAddBonus(unit <target unit>, integer <bonus type>, integer <bonus ammount>)
//@
//@ This function will add <bonus ammount> to the bonus of type <bonus type> on the
//@ unit <target unit>. <bonus ammount> can be a negative value. This function will return
//@ false if the new bonus will be out of the range which bonus mod can apply.
//@
//@ nothing UnitClearBonus(unit <target unit>, integer <bonus type>)
//@
//@ This function will effectively set the bonus of type <bonus type> for the unit
//@ <target unit> to 0. It is advised you use this function over UnitSetBonus(..., ..., 0)
//@
//@---------------------------------------------------------------------------------------
//@ Variables:
//@
//@ BonusMod_MaxBonus
//@ The maximum bonus that Bonus Mod can apply
//@ BonusMod_MinBonus
//@ The minimum bonus that Bonus Mod can apply
//@---------------------------------------------------------------------------------------
//@ Increasing the Range of Bonuses:
//@
//@ By default, bonus mod uses 13 abilitys per bonus type. This gives each bonus type a
//@ range of -4096 to +4095. To increase this range, you will have to create one new
//@ ability for each ability, for each power of two you increase bonus mod by. You will
//@ also have to edit the negative bonus ability to apply a bonus of -2^(n+1), where n is
//@ the largest power of two you will be using for positive bonuses. You will need to edit
//@ the ABILITY_COUNT constant found below to reflect the new total number of abilitys
//@ each individual bonus will use. You will also have to add the abilitys to the function
//@ InitializeAbilitys. Note that the number in the array index indicates which power of
//@ 2 is held there. So, for instance, set BonusAbilitys[i + 15] would hold an ability
//@ which changes the relivent stat by 32768. (2^15 = 32768) The last ability in the array
//@ must apply a negative bonus.
//@
//@ Here is an example of the bonus BONUS_ARMOR using 15 abilitys instead of 12:
//@
//@ set i = BONUS_ARMOR * ABILITY_COUNT
//@ set BonusAbilitys[i + 0] = 'ZxA0' // +1
//@ set BonusAbilitys[i + 1] = 'ZxA1' // +2
//@ set BonusAbilitys[i + 2] = 'ZxA2' // +4
//@ set BonusAbilitys[i + 3] = 'ZxA3' // +8
//@ set BonusAbilitys[i + 4] = 'ZxA4' // +16
//@ set BonusAbilitys[i + 5] = 'ZxA5' // +32
//@ set BonusAbilitys[i + 6] = 'ZxA6' // +64
//@ set BonusAbilitys[i + 7] = 'ZxA7' // +128
//@ set BonusAbilitys[i + 8] = 'ZxA8' // +256
//@ set BonusAbilitys[i + 9] = 'ZxA9' // +512
//@ set BonusAbilitys[i + 10] = 'ZxAa' // +1024
//@ set BonusAbilitys[i + 11] = 'ZxAb' // +2048
//@ set BonusAbilitys[i + 12] = 'ZxAc' // +4096
//@ set BonusAbilitys[i + 13] = 'ZxAd' // +8192
//@ set BonusAbilitys[i + 14] = 'ZxAe' // +16384
//@ set BonusAbilitys[i + 15] = 'ZxAf' // -32768
//@
//@---------------------------------------------------------------------------------------
//@ Adding and Removing Bonus Types:
//@
//@ Removing a bonus type is simple. First, delete it from the list of constants found
//@ below. Make sure the constants are numberd 0, 1, 2, 3, etc. without any gaps. Change
//@ the BONUS_TYPES constant to reflect the new number of bonuses. You must then remove
//@ the lines of array initialization for the bonus you removed from the
//@ InitializeAbilitys function. You can then delete the abilitys for that bonus type, and
//@ you are then done removing a bonus type.
//@
//@ Adding a bonus type is done in much the same way. Add a constant for it to the list of
//@ constants below, ensuring they are numberd 0, 1, 2, 3 etc. withour any gaps. Change
//@ the BONUS_TYPES constant to reflect the new number of bonuses. You must then create
//@ all the needed abilitys for the new bonus type. Ensure the bonus they each apply is a
//@ power of 2, as with the already included bonuses. See the section Increasing the Range
//@ of Bonuses for more information. After all the abilitys are added, you must add the
//@ needed lines to the InitializeAbilitys function. The existing lines should be a clear
//@ enogh example.
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//////////////////////////////////////////////////////////////////////////////////////////
library BonusMod initializer Initialize
globals
//========================================================================================
// Bonus Type Constants
//========================================================================================
constant integer BONUS_ARMOR = 0 // Armor Bonus
constant integer BONUS_DAMAGE = 1 // Damage Bonus
constant integer BONUS_SIGHT_RANGE = 2 // Sight Range Bonus
constant integer BONUS_MANA_REGEN = 3 // Mana Regeneration Bonus (A % value)
constant integer BONUS_LIFE_REGEN = 4 // Life Regeneration Bonus (An absolute value)
constant integer BONUS_HERO_STR = 5 // Strength Bonus
constant integer BONUS_HERO_AGI = 6 // Agility Bonus
constant integer BONUS_HERO_INT = 7 // Intelligence Bonus
constant integer BONUS_SPEED_MOVE = 8 // Movespeed Bonus (A % value)
constant integer BONUS_SPEED_ATTACK = 9 // Attackspeed Bonus (A % value)
// The number of bonus type constants above:
constant integer BONUS_TYPES = 10
//========================================================================================
// Other Configuration
//========================================================================================
// The number of abilitys used per bonus type:
private constant integer ABILITY_COUNT = 13
// Note: Setting the following to false will decrease loading time, but will cause a
// small ammount of lag when a bonus is first applied. (Especially a negative bonus)
// If set to true, all BonusMod abilitys will be preloaded:
private constant boolean PRELOAD_ABILITYS = true
// Only applies if PRELOAD_ABILITYS is set to true.
// The unit type used to preload abilitys on:
private constant integer PRELOAD_DUMMY_UNIT = 'hpea'
endglobals
//========================================================================================
// Ability Initialization
//----------------------------------------------------------------------------------------
// The following function is used to define the rawcodes for all the abilitys bonus mod
// uses. If you use the text macros included with BonusMod, and if you do not wish to add,
// remove, or change the range of bonuses, you will not have to edit the following.
//
// Note that if your map already has abilitys with rawcodes that begin with Zx followed by
// an upper-case letter, the ObjectMerger macros included with this library will not work
// and you will have to edit the lines below. However, you could use the find and replace
// feature in JASS NewGen's Trigger Editor Syntax Highlighter to replace all occurances of
// Zx both here and in the ObjectMerger macros to ease configuration.
//========================================================================================
private keyword BonusAbilitys
private function InitializeAbilitys takes nothing returns nothing
local integer i
// Bonus Mod - Armor abilitys
set i = BONUS_ARMOR * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxA0' // +1
set BonusAbilitys[i + 1] = 'ZxA1' // +2
set BonusAbilitys[i + 2] = 'ZxA2' // +4
set BonusAbilitys[i + 3] = 'ZxA3' // +8
set BonusAbilitys[i + 4] = 'ZxA4' // +16
set BonusAbilitys[i + 5] = 'ZxA5' // +32
set BonusAbilitys[i + 6] = 'ZxA6' // +64
set BonusAbilitys[i + 7] = 'ZxA7' // +128
set BonusAbilitys[i + 8] = 'ZxA8' // +256
set BonusAbilitys[i + 9] = 'ZxA9' // +512
set BonusAbilitys[i + 10] = 'ZxAa' // +1024
set BonusAbilitys[i + 11] = 'ZxAb' // +2048
set BonusAbilitys[i + 12] = 'ZxAc' // -4096
// Bonus Mod - Damage abilitys
set i = BONUS_DAMAGE * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxB0' // +1
set BonusAbilitys[i + 1] = 'ZxB1' // +2
set BonusAbilitys[i + 2] = 'ZxB2' // +4
set BonusAbilitys[i + 3] = 'ZxB3' // +8
set BonusAbilitys[i + 4] = 'ZxB4' // +16
set BonusAbilitys[i + 5] = 'ZxB5' // +32
set BonusAbilitys[i + 6] = 'ZxB6' // +64
set BonusAbilitys[i + 7] = 'ZxB7' // +128
set BonusAbilitys[i + 8] = 'ZxB8' // +256
set BonusAbilitys[i + 9] = 'ZxB9' // +512
set BonusAbilitys[i + 10] = 'ZxBa' // +1024
set BonusAbilitys[i + 11] = 'ZxBb' // +2048
set BonusAbilitys[i + 12] = 'ZxBc' // -4096
// Bonus Mod - Sight Range abilitys
set i = BONUS_SIGHT_RANGE * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxC0' // +1
set BonusAbilitys[i + 1] = 'ZxC1' // +2
set BonusAbilitys[i + 2] = 'ZxC2' // +4
set BonusAbilitys[i + 3] = 'ZxC3' // +8
set BonusAbilitys[i + 4] = 'ZxC4' // +16
set BonusAbilitys[i + 5] = 'ZxC5' // +32
set BonusAbilitys[i + 6] = 'ZxC6' // +64
set BonusAbilitys[i + 7] = 'ZxC7' // +128
set BonusAbilitys[i + 8] = 'ZxC8' // +256
set BonusAbilitys[i + 9] = 'ZxC9' // +512
set BonusAbilitys[i + 10] = 'ZxCa' // +1024
set BonusAbilitys[i + 11] = 'ZxCb' // +2048
set BonusAbilitys[i + 12] = 'ZxCc' // -4096
// Bonus Mod - Mana Regen abilitys
set i = BONUS_MANA_REGEN * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxD0' // +1
set BonusAbilitys[i + 1] = 'ZxD1' // +2
set BonusAbilitys[i + 2] = 'ZxD2' // +4
set BonusAbilitys[i + 3] = 'ZxD3' // +8
set BonusAbilitys[i + 4] = 'ZxD4' // +16
set BonusAbilitys[i + 5] = 'ZxD5' // +32
set BonusAbilitys[i + 6] = 'ZxD6' // +64
set BonusAbilitys[i + 7] = 'ZxD7' // +128
set BonusAbilitys[i + 8] = 'ZxD8' // +256
set BonusAbilitys[i + 9] = 'ZxD9' // +512
set BonusAbilitys[i + 10] = 'ZxDa' // +1024
set BonusAbilitys[i + 11] = 'ZxDb' // +2048
set BonusAbilitys[i + 12] = 'ZxDc' // -4096
// Bonus Mod - Life Regen abilitys
set i = BONUS_LIFE_REGEN * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxE0' // +1
set BonusAbilitys[i + 1] = 'ZxE1' // +2
set BonusAbilitys[i + 2] = 'ZxE2' // +4
set BonusAbilitys[i + 3] = 'ZxE3' // +8
set BonusAbilitys[i + 4] = 'ZxE4' // +16
set BonusAbilitys[i + 5] = 'ZxE5' // +32
set BonusAbilitys[i + 6] = 'ZxE6' // +64
set BonusAbilitys[i + 7] = 'ZxE7' // +128
set BonusAbilitys[i + 8] = 'ZxE8' // +256
set BonusAbilitys[i + 9] = 'ZxE9' // +512
set BonusAbilitys[i + 10] = 'ZxEa' // +1024
set BonusAbilitys[i + 11] = 'ZxEb' // +2048
set BonusAbilitys[i + 12] = 'ZxEc' // -4096
// Bonus Mod - Hero STR abilitys
set i = BONUS_HERO_STR * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxF0' // +1
set BonusAbilitys[i + 1] = 'ZxF1' // +2
set BonusAbilitys[i + 2] = 'ZxF2' // +4
set BonusAbilitys[i + 3] = 'ZxF3' // +8
set BonusAbilitys[i + 4] = 'ZxF4' // +16
set BonusAbilitys[i + 5] = 'ZxF5' // +32
set BonusAbilitys[i + 6] = 'ZxF6' // +64
set BonusAbilitys[i + 7] = 'ZxF7' // +128
set BonusAbilitys[i + 8] = 'ZxF8' // +256
set BonusAbilitys[i + 9] = 'ZxF9' // +512
set BonusAbilitys[i + 10] = 'ZxFa' // +1024
set BonusAbilitys[i + 11] = 'ZxFb' // +2048
set BonusAbilitys[i + 12] = 'ZxFc' // -4096
// Bonus Mod - Hero AGI abilitys
set i = BONUS_HERO_AGI * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxG0' // +1
set BonusAbilitys[i + 1] = 'ZxG1' // +2
set BonusAbilitys[i + 2] = 'ZxG2' // +4
set BonusAbilitys[i + 3] = 'ZxG3' // +8
set BonusAbilitys[i + 4] = 'ZxG4' // +16
set BonusAbilitys[i + 5] = 'ZxG5' // +32
set BonusAbilitys[i + 6] = 'ZxG6' // +64
set BonusAbilitys[i + 7] = 'ZxG7' // +128
set BonusAbilitys[i + 8] = 'ZxG8' // +256
set BonusAbilitys[i + 9] = 'ZxG9' // +512
set BonusAbilitys[i + 10] = 'ZxGa' // +1024
set BonusAbilitys[i + 11] = 'ZxGb' // +2048
set BonusAbilitys[i + 12] = 'ZxGc' // -4096
// Bonus Mod - Hero INT abilitys
set i = BONUS_HERO_INT * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxH0' // +1
set BonusAbilitys[i + 1] = 'ZxH1' // +2
set BonusAbilitys[i + 2] = 'ZxH2' // +4
set BonusAbilitys[i + 3] = 'ZxH3' // +8
set BonusAbilitys[i + 4] = 'ZxH4' // +16
set BonusAbilitys[i + 5] = 'ZxH5' // +32
set BonusAbilitys[i + 6] = 'ZxH6' // +64
set BonusAbilitys[i + 7] = 'ZxH7' // +128
set BonusAbilitys[i + 8] = 'ZxH8' // +256
set BonusAbilitys[i + 9] = 'ZxH9' // +512
set BonusAbilitys[i + 10] = 'ZxHa' // +1024
set BonusAbilitys[i + 11] = 'ZxHb' // +2048
set BonusAbilitys[i + 12] = 'ZxHc' // -4096
// Bonus Mod - Move Speed Abilities
set i = BONUS_SPEED_MOVE * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxI0' // +1
set BonusAbilitys[i + 1] = 'ZxI1' // +2
set BonusAbilitys[i + 2] = 'ZxI2' // +4
set BonusAbilitys[i + 3] = 'ZxI3' // +8
set BonusAbilitys[i + 4] = 'ZxI4' // +16
set BonusAbilitys[i + 5] = 'ZxI5' // +32
set BonusAbilitys[i + 6] = 'ZxI6' // +64
set BonusAbilitys[i + 7] = 'ZxI7' // +128
set BonusAbilitys[i + 8] = 'ZxI8' // +256
set BonusAbilitys[i + 9] = 'ZxI9' // +512
set BonusAbilitys[i + 10] = 'ZxIa' // +1024
set BonusAbilitys[i + 11] = 'ZxIb' // +2048
set BonusAbilitys[i + 12] = 'ZxIc' // -4096
// Bonus Mod - Attack Speed Abilities
set i = BONUS_SPEED_ATTACK * ABILITY_COUNT
set BonusAbilitys[i + 0] = 'ZxJ0' // +1
set BonusAbilitys[i + 1] = 'ZxJ1' // +2
set BonusAbilitys[i + 2] = 'ZxJ2' // +4
set BonusAbilitys[i + 3] = 'ZxJ3' // +8
set BonusAbilitys[i + 4] = 'ZxJ4' // +16
set BonusAbilitys[i + 5] = 'ZxJ5' // +32
set BonusAbilitys[i + 6] = 'ZxJ6' // +64
set BonusAbilitys[i + 7] = 'ZxJ7' // +128
set BonusAbilitys[i + 8] = 'ZxJ8' // +256
set BonusAbilitys[i + 9] = 'ZxJ9' // +512
set BonusAbilitys[i + 10] = 'ZxJa' // +1024
set BonusAbilitys[i + 11] = 'ZxJb' // +2048
set BonusAbilitys[i + 12] = 'ZxJc' // -4096
endfunction
//========================================================================================
// System Code
//----------------------------------------------------------------------------------------
// Do not edit below this line unless you wish to change the way the system works.
//========================================================================================
globals
// Contains all abilitys in a two-dimensional structure:
private integer array BonusAbilitys
// Precomputed powers of two to avoid speed and rounding issues with Pow():
private integer array PowersOf2
// Range constants (Read only please):
public integer MaxBonus
public integer MinBonus
endglobals
function UnitClearBonus takes unit u, integer bonusType returns nothing
local integer i = 0
loop
call UnitRemoveAbility(u, BonusAbilitys[bonusType * ABILITY_COUNT + i])
set i = i + 1
exitwhen i == ABILITY_COUNT - 2
endloop
endfunction
function UnitSetBonus takes unit u, integer bonusType, integer ammount returns boolean
local integer i = ABILITY_COUNT - 2
if ammount < MinBonus or ammount > MaxBonus then
debug call BJDebugMsg("BonusSystem Error: Bonus too high or low (" + I2S(ammount) + ")")
return false
elseif bonusType < 0 or bonusType >= BONUS_TYPES then
debug call BJDebugMsg("BonusSystem Error: Invalid bonus type (" + I2S(bonusType) + ")")
return false
endif
if ammount < 0 then
set ammount = MaxBonus + ammount + 1
call UnitAddAbility(u, BonusAbilitys[bonusType * ABILITY_COUNT + ABILITY_COUNT - 1])
call UnitMakeAbilityPermanent(u, true, BonusAbilitys[bonusType * ABILITY_COUNT + ABILITY_COUNT - 1])
else
call UnitRemoveAbility(u, BonusAbilitys[bonusType * ABILITY_COUNT + ABILITY_COUNT - 1])
endif
loop
if ammount >= PowersOf2[i] then
call UnitAddAbility(u, BonusAbilitys[bonusType * ABILITY_COUNT + i])
call UnitMakeAbilityPermanent(u, true, BonusAbilitys[bonusType * ABILITY_COUNT + i])
set ammount = ammount - PowersOf2[i]
else
call UnitRemoveAbility(u, BonusAbilitys[bonusType * ABILITY_COUNT + i])
endif
set i = i - 1
exitwhen i < 0
endloop
return true
endfunction
function UnitGetBonus takes unit u, integer bonusType returns integer
local integer i = 0
local integer ammount = 0
if GetUnitAbilityLevel(u, BonusAbilitys[bonusType * ABILITY_COUNT + ABILITY_COUNT - 1]) > 0 then
set ammount = MinBonus
endif
loop
if GetUnitAbilityLevel(u, BonusAbilitys[bonusType * ABILITY_COUNT + i]) > 0 then
set ammount = ammount + PowersOf2[i]
endif
set i = i + 1
exitwhen i == ABILITY_COUNT - 2
endloop
return ammount
endfunction
function UnitAddBonus takes unit u, integer bonusType, integer ammount returns boolean
return UnitSetBonus(u, bonusType, UnitGetBonus(u, bonusType) + ammount)
endfunction
private function Initialize takes nothing returns nothing
local integer i = 1
local unit u
set PowersOf2[0] = 1
loop
set PowersOf2[i] = PowersOf2[i - 1] * 2
set i = i + 1
exitwhen i == ABILITY_COUNT
endloop
set MaxBonus = PowersOf2[ABILITY_COUNT - 1] - 1
set MinBonus = -PowersOf2[ABILITY_COUNT - 1]
call InitializeAbilitys()
if PRELOAD_ABILITYS then
set u = CreateUnit(Player(15), PRELOAD_DUMMY_UNIT, 0, 0, 0)
set i = 0
loop
exitwhen i == BONUS_TYPES * ABILITY_COUNT
call UnitAddAbility(u, BonusAbilitys[i])
set i = i + 1
endloop
call RemoveUnit(u)
endif
endfunction
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library AttMod requires BonusMod, SetUnitMaxState
globals
unit TMP_UNIT = null
endglobals
//== ATTACHMENT OBJECT =====================>
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: AttachMod
//: #=#=#=#=#=#=#=#=#=#=#=#=
struct AttributeMod
integer amr = 0 // Armor Bonus
integer dmg = 0 // Damage Bonus
integer sight = 0 // Sight Range Bonus
integer manareg = 0 // Mana Regeneration Bonus (A % value)
integer lifereg = 0 // Life Regeneration Bonus (An absolute value)
integer str = 0 // Strength Bonus
integer agy = 0 // Agility Bonus
integer int = 0 // Intelligence Bonus
integer ms = 0 // Move Speed Bonus
integer as = 0 //Attack Speed Bonus
real hp = 0. // Hitpoint Bonus
real mp = 0. // Mana Bonus
public method apply takes nothing returns nothing
call UnitAddBonus(TMP_UNIT, BONUS_ARMOR, .amr)
call UnitAddBonus(TMP_UNIT, BONUS_DAMAGE, .dmg)
call UnitAddBonus(TMP_UNIT, BONUS_SIGHT_RANGE, .sight)
call UnitAddBonus(TMP_UNIT, BONUS_MANA_REGEN, .manareg)
call UnitAddBonus(TMP_UNIT, BONUS_LIFE_REGEN, .lifereg)
call UnitAddBonus(TMP_UNIT, BONUS_HERO_STR, .str)
call UnitAddBonus(TMP_UNIT, BONUS_HERO_AGI, .agy)
call UnitAddBonus(TMP_UNIT, BONUS_HERO_INT, .int)
call UnitAddBonus(TMP_UNIT, BONUS_SPEED_MOVE, .ms)
call UnitAddBonus(TMP_UNIT, BONUS_SPEED_ATTACK, .as)
call AddUnitMaxState(TMP_UNIT, UNIT_STATE_MAX_LIFE, .hp)
call AddUnitMaxState(TMP_UNIT, UNIT_STATE_MAX_MANA, .mp)
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [apply]: Unit with ID " + I2S(GetHandleId(TMP_UNIT)) + " has loaded itemdata.")
endmethod
public method remove takes nothing returns nothing
call UnitAddBonus(TMP_UNIT, BONUS_ARMOR, -(.amr))
call UnitAddBonus(TMP_UNIT, BONUS_DAMAGE, -(.dmg))
call UnitAddBonus(TMP_UNIT, BONUS_SIGHT_RANGE, -(.sight))
call UnitAddBonus(TMP_UNIT, BONUS_MANA_REGEN, -(.manareg))
call UnitAddBonus(TMP_UNIT, BONUS_LIFE_REGEN, -(.lifereg))
call UnitAddBonus(TMP_UNIT, BONUS_HERO_STR, -(.str))
call UnitAddBonus(TMP_UNIT, BONUS_HERO_AGI, -(.agy))
call UnitAddBonus(TMP_UNIT, BONUS_HERO_INT, -(.int))
call UnitAddBonus(TMP_UNIT, BONUS_SPEED_MOVE, -(.ms))
call UnitAddBonus(TMP_UNIT, BONUS_SPEED_ATTACK, -(.as))
call AddUnitMaxState(TMP_UNIT, UNIT_STATE_MAX_LIFE, -(.hp))
call AddUnitMaxState(TMP_UNIT, UNIT_STATE_MAX_MANA, -(.mp))
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [apply]: Unit with ID " + I2S(GetHandleId(TMP_UNIT)) + " has unloaded itemdata.")
endmethod
endstruct
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//////////////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@ SetUnitMaxState
//@=======================================================================================
//@ Credits:
//@---------------------------------------------------------------------------------------
//@ Written by:
//@ Earth-Fury
//@ Based on the work of:
//@ Blade.dk
//@
//@ If you use this system, please credit all of the people mentioned above in your map.
//@=======================================================================================
//@ SetUnitMaxState Readme
//@---------------------------------------------------------------------------------------
//@
//@ SetUnitMaxState() is a function origionally written by Blade.dk. It takes advantage of
//@ a bug which was introduced in one of the patches: Bonus life and mana abilitys will
//@ only ever add the bonus ammount for level 1. However, when removed, they will remove
//@ the ammount they should have added at their current level. This allows you to change a
//@ units maximum life and mana, without adding a perminent ability to the unit.
//@
//@---------------------------------------------------------------------------------------
//@ Adding SetUnitMaxState to your map:
//@
//@ Simply copy this library in to a trigger which has been converted to custom text.
//@ After that, you must copy over the abilitys. This is made easy by the ObjectMerger in
//@ JASS NewGen. Distributed with this system are //! external calls to the ObjectMerger.
//@ Simply copy both of them in to your map, save your map, close and reopen your map in
//@ the editor, and remove the external calls. (Or otherwise disable them. Removing the !
//@ after the // works.)
//@
//@---------------------------------------------------------------------------------------
//@ Using SetUnitMaxState:
//@
//@ nothing SetUnitMaxState(unit <target>, unitstate <state>, real <new value>)
//@
//@ This function changes <target>'s unitstate <state> to be eqal to <new value>. Note
//@ that the only valid unitstates this function will use are UNIT_STATE_MAX_MAN and
//@ UNIT_STATE_MAX_LIFE. Use SetUnitState() to change other unitstates.
//@
//@ nothing AddUnitMaxState(unit <target>, unitstate <state>, real <add value>)
//@
//@ This function adds <add value> to <target>'s <state> unitstate. <add value> can be
//@ less than 0, making this function reduce the specified unitstate. This function will
//@ only work with the unitstates UNIT_STATE_MAX_LIFE and UNIT_STATE_MAX_MANA.
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//////////////////////////////////////////////////////////////////////////////////////////
library SetUnitMaxState initializer Initialize
globals
//========================================================================================
// Configuration
//========================================================================================
// The rawcode of the life ability:
private constant integer MAX_STATE_LIFE_ABILITY = 'Zx01'
// The rawcode of the mana ability:
private constant integer MAX_STATE_MANA_ABILITY = 'Zx00'
// The maximum power of two the abilitys use:
private constant integer MAX_STATE_MAX_POWER = 8
endglobals
//========================================================================================
// System Code
//----------------------------------------------------------------------------------------
// Do not edit below this line unless you wish to change the way the system works.
//========================================================================================
globals
private integer array PowersOf2
endglobals
function SetUnitMaxState takes unit u, unitstate state, real newValue returns nothing
local integer stateAbility
local integer newVal = R2I(newValue)
local integer i = MAX_STATE_MAX_POWER
local integer offset
if state == UNIT_STATE_MAX_LIFE then
set stateAbility = MAX_STATE_LIFE_ABILITY
elseif state == UNIT_STATE_MAX_MANA then
set stateAbility = MAX_STATE_MANA_ABILITY
else
debug call BJDebugMsg("SetUnitMaxState Error: Invalid unitstate")
return
endif
set newVal = newVal - R2I(GetUnitState(u, state))
if newVal > 0 then
set offset = MAX_STATE_MAX_POWER + 3
elseif newVal < 0 then
set offset = 2
set newVal = -newVal
else
return
endif
loop
exitwhen newVal == 0 or i < 0
if newVal >= PowersOf2[i] then
call UnitAddAbility(u, stateAbility)
call SetUnitAbilityLevel(u, stateAbility, offset + i)
call UnitRemoveAbility(u, stateAbility)
set newVal = newVal - PowersOf2[i]
else
set i = i - 1
endif
endloop
endfunction
function AddUnitMaxState takes unit u, unitstate state, real addValue returns nothing
call SetUnitMaxState(u, state, GetUnitState(u, state) + addValue)
endfunction
private function Initialize takes nothing returns nothing
local integer i = 1
set PowersOf2[0] = 1
loop
set PowersOf2[i] = PowersOf2[i - 1] * 2
set i = i + 1
exitwhen i == MAX_STATE_MAX_POWER + 3
endloop
endfunction
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//:-----<-->----<-->----<-->----<-->----<-->----<-->----
//: AdvancedInventoryHandling
//: by dhk_undead_lord / aka Anachron
//:
//: Table of Content
//: *==============*
//: 1.) About
//: 2.) Importing
//: 3.) Features
//: 4.) Misc
//:
//: > ABOUT
//: --------
//:
//: This system allows to create dynamically inventories
//: which can held item and its effects.
//:
//: This system also allows you, the user, to create any
//: aspect of the item easily. If you want drop, pick or
//: use events, you can simply define them at item creation.
//:
//: Please note that this is the first Beta, so it might
//: has less features, but it works and I think its very nice.
//:
//: > IMPORTING
//: --------------
//:
//: I.) Copy this code.
//: II.) Paste it into the head of your map.
//: (Therefor go to the Trigger Editor, select the mapname and paste
//: into the area on the right)
//: III.) Save your map!
//: (With File - Save Map (S) or control + S. DO NOT SAVE WITH SAVE AS!)
//: IV.) You got it! You imported the system.
//:
//: To make sure this system works, you should try a few tests!
//:
//: > FEATURES
//: --------------
//:
//: * Create endless item wildcards
//: * Let the system automaticly handle items
//: * Load / Save Inventories easily
//: * Many more!
//:
//: > MISC
//: ----------
//:
//: Version: 1.00 Beta
//: A better docu to come!
//:
//:-----<-->----<-->----<-->----<-->----<-->----<-->----
library AdInvHan initializer init requires Table, AttMod
//==#=======================================#
//== USER CONFIGURATEABLE AREA =============>
//==#=======================================#
globals
//: Define the amount of maximum items
//: being in an inventory
//: DEFAULT: bj_MAX_INVENTORY
constant integer INV_PLACES = 6
//: Define whether items should be dropped
//: on inventory object destruction or not.
//: If not dropped, the items will be removed.
//: DEFAULT: false
constant boolean INV_DROP_ON_DESTROY = false
//: Sets whether all units on the map
//: automaticly gets inventory objects or not.
//: WARNING: IF YOU SET THIS TO FALSE AND THE
//: UNIT HAS NO INVENTORY, ITEMS WILL NOT
//: WORK FOR IT!
//: DEFAULT: true
constant boolean INV_GENERATE_AUTO = true
//: Sets whether all units on the map
//: automaticly loose inventory objects or not.
//: WARNING: IF YOU SET THIS TO TRUE, ITEMs
//: WILL NOT WORK FOR IT!
//: DEFAULT: true
constant boolean INV_REMOVE_AUTO = true
//: Sets whether the item should be checked
//: to apply to the condition function or not.
//: If the ConditionFunction returns false,
//: the itemObj instance can't created.
//: DEFAULT: true
constant boolean ITEMOBJ_CHECK_AUTO = true
//: Sets whether itemobjects should be
//: automaticly created on pickup or not.
//: DEFAULT: true
constant boolean ITEMOBJ_GENERATE_AUTO = true
//: Sets whether itemobjects should be
//: automaticly destroyed on drop or not.
//: DEFAULT: true
constant boolean ITEMOBJ_REMOVE_AUTO = true
//: Sets whether the statmod should be applied
//: automaticly on pickup
//: DEFAULT: true
constant boolean ADDMOD_PICKUP_APPLIES = true
//: Sets whether the statmod should be removed
//: automaticly on drop
//: DEFAULT: true
constant boolean ADDMOD_DROP_REMOVES = true
endglobals
//==#=======================================\\
//== DO NOT TOUCH THIS! ====================\\
//==#=======================================\\
globals
private trigger SYSTEM_TRIG = CreateTrigger()
private constant integer ID_NULL = -1
endglobals
//== GENERAL ITEM INTERFACES ====================>
//== GENERAL ITEM INTERFACES ====================>
function interface onPickup takes nothing returns nothing
function interface onDrop takes nothing returns nothing
function interface onUse takes nothing returns nothing
function interface onCheck takes nothing returns boolean
//== ITEM WILDCARD ===================>
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: ItemWildcard
//: #=#=#=#=#=#=#=#=#=#=#=#=
struct itemWC
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Storage members
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
integer itemID = 0
item dummy = null
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Attached itemdata
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
AttributeMod AttMod = ID_NULL
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Attached interface for advanced usage
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
onPickup pickAct = ID_NULL
onDrop dropAct = ID_NULL
onUse useAct = ID_NULL
onCheck checkAct = ID_NULL
public static method create takes integer itID, AttributeMod mod returns thistype
local thistype itwc = thistype.allocate()
set itwc.itemID = itID
set itwc.AttMod = mod
set itwc.dummy = CreateItem(itID, 0., 0.)
call SetItemVisible(itwc.dummy, false)
call SetItemInvulnerable(itwc.dummy, true)
return itwc
endmethod
endstruct
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: Load & Save Wildcards
//: #=#=#=#=#=#=#=#=#=#=#=#=
globals
private Table itWcTab = 0
endglobals
public function LoadWildCard takes item it returns itemWC
return itemWC(itWcTab[GetItemTypeId(it)])
endfunction
public function SaveWildCard takes itemWC itWC returns nothing
set itWcTab[GetItemTypeId(itWC.dummy)] = integer(itWC)
endfunction
public function DestroyWildCard takes item it returns nothing
call itWcTab.flush(GetItemTypeId(it))
endfunction
//== ITEM OBJECT =====================>
//: #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=
//: Create items based on WildCard
//: #=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=
public function CreateItemObj takes item it, unit u returns itemObj
local itemObj io = itemObj.create(it, u)
local itemWC iwc = ID_NULL
set iwc = LoadWildCard(it)
if iwc != ID_NULL and io != ID_NULL then
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [CreateItemObj]: Loaded wildcard for item with type " + GetItemName(it) + ".")
set io.AttMod = iwc.AttMod
set io.pickAct = iwc.pickAct
set io.dropAct = iwc.dropAct
set io.useAct = iwc.useAct
set io.checkAct = iwc.checkAct
else
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [CreateItemObj]: Could not load wildcard for item with type " + GetItemName(it) + ".")
endif
if ITEMOBJ_CHECK_AUTO then
if not io.onCheckEvent() then
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [create]: ItemObj has been destroyed (False return).")
call DisableTrigger(SYSTEM_TRIG)
call SetItemPosition(it, GetUnitX(u), GetUnitY(u))
call EnableTrigger(SYSTEM_TRIG)
call io.destroy()
set io = ID_NULL
endif
endif
return io
endfunction
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: ItemObject
//: #=#=#=#=#=#=#=#=#=#=#=#=
struct itemObj
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Item attributes saved in object
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
integer Type = 0
player Owner = null
item Handle = null
integer Charges = 0
integer Level = 0
string Name = null
integer UserData = 0
real LocX = 0.
real LocY = 0.
itemtype Class = null
unit Carrier = null
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Attached itemdata
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
AttributeMod AttMod = ID_NULL
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Attached interface for advanced usage
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
onPickup pickAct = ID_NULL
onDrop dropAct = ID_NULL
onUse useAct = ID_NULL
onCheck checkAct = ID_NULL
//: =-=-=-=-=-=-=-=-=-=-
//: General Object
//: =-=-=-=-=-=-=-=-=-=-
integer objID = ID_NULL
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: Object Methods
//: #=#=#=#=#=#=#=#=#=#=#=#=
public method onCheckEvent takes nothing returns boolean
if .checkAct != ID_NULL then
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [onCheckEvent]: Check stats.")
return .checkAct.evaluate()
else
return true
endif
endmethod
public method onPickEvent takes nothing returns nothing
if .pickAct != ID_NULL then
call .pickAct.execute()
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [onPickEvent]: Run interface.")
endif
if .AttMod != ID_NULL then
if ADDMOD_PICKUP_APPLIES then
set TMP_UNIT = .Carrier
call .AttMod.apply()
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [onPickEvent]: Itemstats applied to hero.")
endif
endif
endmethod
public method onDropEvent takes nothing returns nothing
if .dropAct != ID_NULL then
call .dropAct.execute()
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [onDropEvent]: Run interface.")
endif
if .AttMod != ID_NULL then
if ADDMOD_DROP_REMOVES then
set TMP_UNIT = .Carrier
call .AttMod.remove()
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [onPickEvent]: Itemstats removed from hero.")
endif
endif
endmethod
public method onUseEvent takes nothing returns nothing
call .useAct.execute()
endmethod
public method updateData takes nothing returns nothing
set .Charges = GetItemCharges(.Handle)
set .Level = GetItemLevel(.Handle)
set .Name = GetItemName(.Handle)
set .UserData = GetItemUserData(.Handle)
set .LocX = GetItemX(.Handle)
set .LocY = GetItemY(.Handle)
set .Class = GetItemType(.Handle)
set .Type = GetItemTypeId(.Handle)
set .Owner = GetItemPlayer(.Handle)
endmethod
public method updateHandles takes item i, unit u returns nothing
set .Handle = i
set .Carrier = u
endmethod
public static method create takes item i, unit u returns thistype
local thistype iO = thistype.allocate()
call iO.updateData()
call iO.updateHandles(i, u)
return iO
endmethod
endstruct
//== INVENTORY OBJECT =====================>
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: InventoryObject
//: #=#=#=#=#=#=#=#=#=#=#=#=
struct InventoryObj
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//: Inventory data saved in object
//: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
itemObj array itemObjects[INV_PLACES]
integer itemInt = 0
unit owner = null
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: Object Methods
//: #=#=#=#=#=#=#=#=#=#=#=#=
public static method create takes unit u returns thistype
local thistype inv = thistype.allocate()
set inv.owner = u
return inv
endmethod
public method loadItems takes nothing returns nothing
local integer i = 0
local boolean e = false
local item it = null
loop
exitwhen e
set it = UnitItemInSlot(.owner, i)
if it != null then
call .addItem(it)
endif
if i >= 6 then
set e = true
else
set i = i + 1
endif
endloop
endmethod
public static method createAndLoad takes unit u returns thistype
local thistype inv = thistype.create(u)
call inv.loadItems()
return inv
endmethod
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: Add and remove items
//: #=#=#=#=#=#=#=#=#=#=#=#=
public method addItem takes item it returns nothing
local itemObj tmp = CreateItemObj(it, .owner)
if tmp != ID_NULL then
call tmp.onPickEvent()
set .itemObjects[.itemInt] = tmp
set .itemInt = .itemInt + 1
else
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE [addItem]: ItemObj could not be created.")
endif
endmethod
public method removeItem takes item it returns nothing
local integer i = 0
local itemObj tmp = 0
local boolean e = false
loop
exitwhen e
set tmp = .itemObjects[i]
if tmp.Handle == it then
call tmp.onDropEvent()
call tmp.destroy()
set .itemObjects[i] = .itemObjects[.itemInt]
set .itemInt = .itemInt - 1
set e = true
else
if i >= .itemInt then
set e = true
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR [removeItem]: The item was not found.")
else
set i = i + 1
endif
endif
endloop
endmethod
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: GetItemsFromInventory
//: #=#=#=#=#=#=#=#=#=#=#=#=
public method getItemObjFromSlot takes integer i returns itemObj
if i <= .itemInt and i >= 0 then
return .itemObjects[i]
else
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR [getItemObjFromSlot]: All slots are already taken.")
return ID_NULL
endif
endmethod
public method getItemObjFromItem takes item it returns itemObj
local itemObj io = 0
local integer i = 0
local boolean e = false
loop
exitwhen e
set io = .itemObjects[i]
if io.Handle == it then
set e = true
else
if i >= .itemInt then
set e = true
set io = -1
else
set i = i + 1
endif
endif
endloop
return io
endmethod
public method getItemFromSlot takes integer i returns item
if i <= .itemInt and i >= 0 then
return .itemObjects[i].Handle
else
return null
endif
endmethod
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: Destructor Method
//: #=#=#=#=#=#=#=#=#=#=#=#=
private method onDestroy takes nothing returns nothing
local itemObj io = 0
local integer i = 0
local boolean e = false
loop
exitwhen e
set io = .itemObjects[i]
if INV_DROP_ON_DESTROY then
call UnitDropItem(.owner, io.Type)
else
call io.destroy()
call RemoveItem(io.Handle)
endif
if i >= .itemInt then
set e = true
else
set i = i + 1
endif
endloop
endmethod
endstruct
//: #=#=#=#=#=#=#=#=#=#=#=#=
//: Load & Save Inventories
//: #=#=#=#=#=#=#=#=#=#=#=#=
globals
private HandleTable invTab = 0
endglobals
public function LoadInventory takes unit u returns InventoryObj
return InventoryObj(invTab[u])
endfunction
public function SaveInventory takes InventoryObj inv returns nothing
set invTab[inv.owner] = integer(inv)
endfunction
public function DestroyInventory takes unit u returns nothing
call invTab.flush(u)
endfunction
//== SYSTEM FUNCTIONS ======================>
private function sys_PickUpItem takes nothing returns nothing
local InventoryObj inv = LoadInventory(GetTriggerUnit())
if inv != ID_NULL then
call inv.addItem(GetManipulatedItem())
else
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR [sys_PickUpItem]: Unit has no inventory")
endif
endfunction
private function sys_DropItem takes nothing returns nothing
local InventoryObj inv = LoadInventory(GetTriggerUnit())
if inv != ID_NULL then
call inv.removeItem(GetManipulatedItem())
else
debug call BJDebugMsg(SCOPE_PREFIX + "ERROR [sys_DropItem]: Unit has no inventory")
endif
endfunction
private function sys_registerUnit takes nothing returns nothing
call SaveInventory(InventoryObj.create(GetTriggerUnit()))
endfunction
private function sys_unregisterUnit takes nothing returns nothing
call DestroyInventory(GetTriggerUnit())
endfunction
private function eventHandler takes nothing returns nothing
local eventid eventID = GetTriggerEventId()
if eventID == EVENT_PLAYER_UNIT_PICKUP_ITEM then
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE -> PICKUP ITEM")
call sys_PickUpItem()
elseif eventID == EVENT_PLAYER_UNIT_DROP_ITEM then
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE -> DROP ITEM")
call sys_DropItem()
elseif eventID == EVENT_PLAYER_UNIT_DEATH then
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE -> DESTROY INVENTORY")
call sys_unregisterUnit()
else
debug call BJDebugMsg(SCOPE_PREFIX + "NOTICE -> CREATE INVENTORY")
call sys_registerUnit()
endif
endfunction
private function onlyHeroes takes nothing returns boolean
return not IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO)
endfunction
private function returnTrue takes nothing returns boolean
return true
endfunction
private function init takes nothing returns nothing
local integer i = 0
local rect rec = bj_mapInitialPlayableArea
local region reg = CreateRegion()
local boolexpr expr = Condition(function onlyHeroes)
call TriggerAddAction(SYSTEM_TRIG, function eventHandler)
if ITEMOBJ_GENERATE_AUTO then
call RegionAddRect(reg, rec)
call TriggerRegisterEnterRegion(SYSTEM_TRIG, reg, expr)
endif
call DestroyBoolExpr(expr)
set expr = Condition(function returnTrue)
loop
exitwhen i > 15
if ITEMOBJ_GENERATE_AUTO then
call TriggerRegisterPlayerUnitEvent(SYSTEM_TRIG, Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, expr)
endif
if ITEMOBJ_REMOVE_AUTO then
call TriggerRegisterPlayerUnitEvent(SYSTEM_TRIG, Player(i), EVENT_PLAYER_UNIT_DROP_ITEM, expr)
endif
if INV_REMOVE_AUTO then
call TriggerRegisterPlayerUnitEvent(SYSTEM_TRIG, Player(i), EVENT_PLAYER_UNIT_DEATH, expr)
endif
set i = i + 1
endloop
//: Initialisate the tables!
set itWcTab = Table.create()
set invTab = HandleTable.create()
//call RemoveRect(rec)
//call RemoveRegion(reg)
call DestroyBoolExpr(expr)
set rec = null
set reg = null
set expr = null
endfunction
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library example initializer init requires AdInvHan
private function createUnit takes nothing returns nothing
call CreateUnit(Player(0), 'Hpal', 0., 0., 0.)
call SetHeroLevel(CreateUnit(Player(0), 'Hblm', 0., 0., 0.), 6, false)
endfunction
public function onPick takes nothing returns nothing
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl", GetTriggerUnit(), "origin"))
endfunction
public function level takes nothing returns boolean
local boolean allow = GetHeroLevel(GetTriggerUnit()) > 5
if not allow then
call BJDebugMsg("ERROR: Your hero has a to low level to carry this item!")
endif
return allow
endfunction
private function init takes nothing returns nothing
local AttributeMod amo = 0
local itemWC iwc = 0
local itemObj io = 0
local item i = null
local unit u = null
local integer itemID = 0
//: Create a new attribute modifier
set amo = AttributeMod.create()
//: Modify its strengh to 10 and dmg to 5
set amo.str = 10
set amo.dmg = 5
set amo.ms = 128
//: Do something for items of type i000
set itemID = 'I000'
//: Create an new item wildcard (Dummy)
set iwc = itemWC.create(itemID, amo)
//: Create an onPick action
set iwc.checkAct = level
//: Save the wildcard.
call AdInvHan_SaveWildCard(iwc)
//: Create an new example item handle
set i = CreateItem(itemID, 0., 0.)
set i = CreateItem(itemID, 0., 0.)
set i = CreateItem(itemID, 0., 0.)
set i = CreateItem(itemID, 0., 0.)
call TimerStart(CreateTimer(), 0.001, false, function createUnit)
endfunction
endlibrary