//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
hero | unit | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
/*Changelogs:
Version 2.01b:
Demo Map:
- added a computer bot to demo map, so it can be runned direct through warcraft
//////////////////////////////////////////
// OLD CHANGELOGS: //
//////////////////////////////////////////
Version 2.01:
Inventory System:
- added two new globals for movement speed
Item List:
- added movement speed bonus
- fixed bug in addNormelItem method
Version 2.00:
Inventory System:
- added a 8 slot backpack
- added a auto stack detection system
- added fully triggered item pickup
- ALOT code changes and improvements
- Added some more constants
- now uses TimerUtils
- Item now can be equipped when the equipment menu is opened (through auto equip for example)
Item List:
- added more configurations
- removed / delated methods which are not required
- added some new methods / operators for handling with "Items"
- made some struct member private
- added possibility to add potions to the system (uses the new configurations)
- added the possibility to add "special efffects" to items (only for Equipment)
Demo Map:
- added 6 new Items
Version 1.02:
Inventory System:
-added auto equip to the system
-added normal functions to add heroes to the system, get its Inventory and specific items in slots
-some small code changes
Item List:
-added functions to add items directly to their Slot
Demo Map:
-added 3 example items
Version 1.01:
Inventory System:
-added custom Icons for "Emtpy Slots".
-you now can setup the position of the 'Inventory-Item'.
-After closing the inventory, the items now will be added to the place they where before closing.
-When equiping an item and its slot is full, the item will be switched to the same slot, the new equipped item was
*/
//TESH.scrollpos=0
//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=0
//TESH.alwaysfold=0
library SimError initializer init
//**************************************************************************************************
//*
//* SimError
//*
//* Mimic an interface error message
//* call SimError(ForPlayer, msg)
//* ForPlayer : The player to show the error
//* msg : The error
//*
//* To implement this function, copy this trigger and paste it in your map.
//* Unless of course you are actually reading the library from wc3c's scripts section, then just
//* paste the contents into some custom text trigger in your map.
//*
//**************************************************************************************************
//==================================================================================================
globals
private sound error
endglobals
//====================================================================================================
function SimError takes player ForPlayer, string msg returns nothing
set msg="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00"+msg+"|r"
if (GetLocalPlayer() == ForPlayer) then
call ClearTextMessages()
call DisplayTimedTextToPlayer( ForPlayer, 0.52, 0.96, 2.00, msg )
call StartSound( error )
endif
endfunction
private function init takes nothing returns nothing
set error=CreateSoundFromLabel("InterfaceError",false,false,false,10,10)
//call StartSound( error ) //apparently the bug in which you play a sound for the first time
//and it doesn't work is not there anymore in patch 1.22
endfunction
endlibrary
//TESH.scrollpos=118
//TESH.alwaysfold=0
library_once TimerUtils initializer redInit
//*********************************************************************
//* TimerUtils (Red flavo for 1.23b)
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3campaigns.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Red flavor: Fastest, method in existence for timer attaching,
//* only takes an array lookup, GetHandleId and subtraction.
//* However, all the code in your map requires extra care
//* not to forget to call ReleaseTimer. It also requires
//* to preload a lot of timers at map init, they use
//* memory and handle ids.
//*
//* I recommend you run your map in debug mode the first
//* time after adding it, make sure you can see map init messages
//* if nothing appears, all is done, if an error appears, it might
//* suggest you a value with OFFSET, in that case, update that value
//* if it still does not work after updating (rare), try a bigger
//* OFFSET by 1000 for example. (Sounds hard? Then use blue or purple
//* timerutils that are friendlier though not as fast)
//*
//********************************************************************
//================================================================
globals
private constant integer OFFSET = 0x100000
private constant integer QUANTITY = 256
private constant integer ARRAY_SIZE = 8191 //changing this to a higher value would effectively
//cripple the performance making this thing irrelevant
endglobals
//==================================================================================================
globals
private integer array data[ARRAY_SIZE]
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
debug if(GetHandleId(t)-OFFSET<0) then
debug call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
debug endif
set data[GetHandleId(t)-OFFSET]=value
endfunction
function GetTimerData takes timer t returns integer
debug if(GetHandleId(t)-OFFSET<0) then
debug call BJDebugMsg("GetTimerData: Wrong handle id, only use GetTimerData on timers created by NewTimer")
debug endif
return data[GetHandleId(t)-OFFSET]
endfunction
//==========================================================================================
globals
private timer array tT
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
endglobals
//==========================================================================================
function NewTimer takes nothing returns timer
if (tN==0) then
//If this happens then the QUANTITY rule has already been broken, try to fix the
// issue, else fail.
debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, please increase it for your map, fix your map's timer leaks or switch to blue flavor when applicable")
set tT[0]=CreateTimer()
if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably switch to the blue flavor or fix timer leaks.")
return null
endif
else
set tN=tN-1
endif
call SetTimerData(tT[tN],0)
return tT[tN]
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==8191) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function redInit takes nothing returns nothing
local integer i=0
local integer bestoffset=-1
loop
exitwhen (i==QUANTITY)
set tT[i] = CreateTimer()
if(i==0) then
set bestoffset=GetHandleId(tT[i])
endif
if (GetHandleId(tT[i])-OFFSET>=ARRAY_SIZE) then
debug call BJDebugMsg("TimerUtils_redInit: Failed a initializing attempt")
debug call BJDebugMsg("The timer limit is "+I2S(i))
debug call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low, to change OFFSET to "+I2S(bestoffset) )
exitwhen true
endif
if (GetHandleId(tT[i])-OFFSET>=0) then
set i=i+1
endif
endloop
set tN=i
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//////////////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@ Bonus Mod
//@=======================================================================================
//@ Credits:
//@---------------------------------------------------------------------------------------
//@ Written by:
//@ Earth-Fury
//@ Based on the work of:
//@ 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_ATTACK_SPEED = 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
// The number of bonus type constants above:
constant integer BONUS_TYPES = 8
//========================================================================================
// 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 - Attack Speed abilitys
set i = BONUS_ATTACK_SPEED * 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
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)
set u = null
endif
endfunction
endlibrary
//TESH.scrollpos=45
//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
//The dummy unit of your map
private constant integer DUMMY_ID = 'h000'
private constant boolean PRELOAD_ABILITYS = true
private constant integer PRELOAD_DUMMY_UNIT = 'hpea'
//========================================================================================
// System Code
//----------------------------------------------------------------------------------------
// Do not edit below this line unless you wish to change the way the system works.
//========================================================================================
endglobals
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
local unit u
set PowersOf2[0] = 1
loop
set PowersOf2[i] = PowersOf2[i - 1] * 2
set i = i + 1
exitwhen i == MAX_STATE_MAX_POWER + 3
endloop
if PRELOAD_ABILITYS then
set u = CreateUnit(Player(15), PRELOAD_DUMMY_UNIT, 0, 0, 0)
call UnitAddAbility(u, MAX_STATE_LIFE_ABILITY)
call UnitAddAbility(u, MAX_STATE_MANA_ABILITY)
call RemoveUnit(u)
set u = null
endif
endfunction
endlibrary
//TESH.scrollpos=23
//TESH.alwaysfold=0
library SearchString
//**************************************************************************************************#
//* By D1000
//*
//*
//* SearchString
//*
//* Searches a string for antother
//* call SearchString(WhichString, ForWhat)
//* WhichString : The string, the function should check
//* ForWhat : What should be searched in WhichString
//*
//* returns : True, if the ForWhat was found in WhichString
//*
//* CountSignInString
//*
//* Counts the given Signs in a string
//* call CountSignInString(WhichString, WhichSign)
//* WhichString : The string, the function searches
//* WhichSign : Which Sign should be searched for
//* returns : The Number of counted Signs
//*
//**************************************************************************************************
function SearchString takes string WhichString, string ForWhat returns boolean
local integer BaseLength = StringLength(WhichString)
local integer SearchLength = StringLength(ForWhat)
local integer i = 0
loop
exitwhen ForWhat == SubString(WhichString, i, i + SearchLength)
set i = i + 1
if i+SearchLength > BaseLength then
return false
endif
endloop
return true
endfunction
function CountSignInString takes string WhichString, string WhichSign returns integer
local integer BaseLength = StringLength(WhichString)
local integer SearchLength = StringLength(WhichSign)
local integer i = 0
local integer numb = 0
loop
exitwhen i >= BaseLength
if WhichSign == SubString(WhichString, i, i + SearchLength) then
set numb = numb + 1
endif
set i = i + 1
endloop
return numb
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library InventorySystem requires Table, ItemList, SimError, BonusMod, SetUnitMaxState, SearchString
globals
//The Rawcodes of the Items for opening the backpack and equipment
private constant integer EQUIPMENT_OPEN_ID = 'I000'
private constant integer BACKPACK_OPEN_ID = 'I00R'
//The rawcodes of the Items for closing the backpack and equipment
private constant integer EQUIPMENT_CLOSE_ID = 'I001'
private constant integer BACKPACK_CLOSE_ID = 'I00S'
//The rawcodes of the Items changing the pages of the backpack and equipment menu
private constant integer EQUIPMENT_PAGE_1 = 'I003'
private constant integer BACKPACK_PAGE_1 = 'I00T'
private constant integer EQUIPMENT_PAGE_2 = 'I002'
private constant integer BACKPACK_PAGE_2 = 'I00U'
//The slots, where the items for opening backpack and equipment menu should be created
private constant integer EQUIPMENT_SLOT = 4
private constant integer BACKPACK_SLOT = 5
//The place, where required items should be stored
private constant real STORE_ITEM_X = 0.
private constant real STORE_ITEM_Y = 0.
//The Maximum Movespeed a unit can have
private constant real MAX_MOVEMENT_SPEED = 400.
//The Minimum Movespeed a unit can have
private constant real MIN_MOVEMENT_SPEED = 150.
//The Max Number of Charges, an item can has maximum
constant integer MAX_ITEM_CHARGES = 8
//If true, the equipment menu will change to first page when opened
private constant boolean CHANGE_TO_FIRST = true
//If trie, an item being picked up will be auto equipped, if its slot is emtpy and the hero can wear it
private constant boolean AUTO_EQUIP = true
//The distance, an item can be picked up by a hero
private constant real ITEM_PICKUP_DIST = 225.00
//Don't change this!!!
private integer array DUMMY_ITEMS[8]
endglobals
private function SETUP_DUMMY_ITEMS takes nothing returns nothing
set DUMMY_ITEMS[0] = 'I004' //Head
set DUMMY_ITEMS[1] = 'I005' //Chest
set DUMMY_ITEMS[2] = 'I006' //Main Hand
set DUMMY_ITEMS[3] = 'I007' //Secondary Hand
set DUMMY_ITEMS[4] = 'I008' //Gloves
set DUMMY_ITEMS[5] = 'I009' //Feet
set DUMMY_ITEMS[6] = 'I00A' //First Acessory
set DUMMY_ITEMS[7] = 'I00B' //Second Acessory
endfunction
//EVERYTHING BELOW HERE IS SYSTEM CODE!!!
private keyword addItem
//This is the triggered item pickup and stack detection System.
private struct StackData
private delegate Inventory inv = 0
item item = null
real x = 0
real y = 0
integer order = 0
private static integer count = 0
private static thistype array datas
private static trigger walkTo
//creates a new instance of the stackdata
static method create takes unit hero, item which returns StackData
local StackData this = StackData.allocate()
set .inv = Inventory.table[hero]
set .item = which
set .x = GetItemX(.item)
set .y = GetItemY(.item)
call IssuePointOrder(.Owner, "move", .x, .y)
set .order = GetUnitCurrentOrder(.Owner)
set .datas[.count] = this
set .count = .count + 1
return this
endmethod
//checks if the issued target was an item and the order is correct
static method check takes nothing returns boolean
if GetOrderTargetItem() != null and (GetIssuedOrderId() == 851971) then
call StackData.create(GetTriggerUnit(), GetOrderTargetItem())
return true
endif
return false
endmethod
//just sorts and checks each stackdata...
static method periodic takes nothing returns nothing
local integer i = .count - 1
loop
exitwhen i < 0
if not .datas[i].control() then
set .count = .count - 1
if .count < 0 then
set .count = 0
else
set .datas[i] = .datas[.count]
endif
endif
set i = i - 1
endloop
endmethod
//checks the hero and the item every interval
method control takes nothing returns boolean
local real dx = GetUnitX(.Owner) - .x
local real dy = GetUnitY(.Owner) - .y
local Item it = Item.getItemById(GetItemTypeId(.item))
if GetUnitCurrentOrder(.Owner) != .order or GetItemX(.item) != .x or GetItemY(.item) != .y or GetWidgetLife(.Owner) <= 0.405 then
return false
elseif SquareRoot(dx * dx + dy * dy) <= ITEM_PICKUP_DIST and GetItemX(.item) == .x or GetItemY(.item) == .y and GetWidgetLife(.Owner) > 0.405 then
call IssueImmediateOrder(.Owner, "stop")
if (AUTO_EQUIP and it.equippable and .isSlotEmpty(it.slot) and .checkHero(it, false) and .allowauto) then
return Inventory.equipItem(.Owner, .item, it)
endif
if not .checkItemForStack(.item) then
if not .getSlotForItem(.item) then
call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
return false
endif
endif
return false
elseif SquareRoot(dx * dx + dy * dy) > ITEM_PICKUP_DIST then
return true
endif
return false
endmethod
//self explanatory..
static method onInit takes nothing returns nothing
set .walkTo = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(.walkTo, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(.walkTo, Condition(function thistype.check))
call TimerStart(NewTimer(), 0.05, true, function thistype.periodic)
endmethod
endstruct
//private struct required to "recreate" items in their slots when their are dragged or dropped incrorrect
private struct addItem
delegate Inventory inv
integer id
integer charges
integer slot
private timer t
//creates a new instance for an item to a move it to a slot
static method create takes item it, integer slot, Inventory inv returns thistype
local thistype this = thistype.allocate()
set .inv = inv
set .id = GetItemTypeId(it)
set .charges = GetItemCharges(it)
set .slot = slot
set .dropped = false
call RemoveItem(it)
set .dropped = true
set .t = NewTimer()
call SetTimerData(.t, this)
call TimerStart(.t, 0.0, false, function thistype.expire)
return this
endmethod
//0.0 second tiemr interval is required...
private static method expire takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
call UnitAddItemToSlotById(.Owner, .id, .slot)
call SetItemCharges(UnitItemInSlot(.Owner, .slot), .charges)
call ReleaseTimer(.t)
call .destroy()
endmethod
endstruct
//The Inventory struct..
struct Inventory
unit Owner
string HeroClass = ""
string ItemClasses = ""
item array equip[8]
integer array items[6]
integer array backp[8]
integer array charges[6]
integer array bcharges[8]
boolean allowauto = true
integer bfree = 8
boolean dropped = true
private effect array fx[8]
private boolean open = false
private boolean bopen = false
private integer page = 1
private integer bpage = 1
private real array MsBoni[8]
public static HandleTable table
private static trigger Use = CreateTrigger()
private static trigger Pickup = CreateTrigger()
private static trigger Drag = CreateTrigger()
private static trigger Drop = CreateTrigger()
//creates a new Inventory for the unit
static method create takes unit whichUnit, string heroClass, string availableItemClasses returns thistype
local thistype this = 0
local integer i = 0
if not .table.exists(whichUnit) then
set this = thistype.allocate()
set .Owner = whichUnit
set .HeroClass = heroClass
set .ItemClasses = availableItemClasses
loop
exitwhen i > 8
set .equip[i] = CreateItem(DUMMY_ITEMS[i], STORE_ITEM_X, STORE_ITEM_Y)
call SetItemVisible(.equip[i], false)
set i = i + 1
endloop
call TriggerRegisterUnitEvent(.Use, .Owner, EVENT_UNIT_USE_ITEM)
call TriggerRegisterUnitEvent(.Pickup, .Owner, EVENT_UNIT_PICKUP_ITEM)
call TriggerRegisterUnitEvent(.Drag, .Owner, EVENT_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterUnitEvent(.Drop, .Owner, EVENT_UNIT_DROP_ITEM)
call UnitAddItemToSlotById(.Owner, EQUIPMENT_OPEN_ID, EQUIPMENT_SLOT)
call UnitAddItemToSlotById(.Owner, BACKPACK_OPEN_ID, BACKPACK_SLOT)
call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
set .table[.Owner] = this
return this
endif
return 0
endmethod
//opens the backpack for the unit
public static method openBackpack takes unit whichUnit returns boolean
local integer i = 0
local integer i2 = 0
local thistype this = .table[whichUnit]
local item temp = null
local integer add = 0
if not .table.exists(whichUnit) then
return false
elseif not .bopen and not .open then
set .bopen = true
set .allowauto = false
loop
exitwhen i > 5
set temp = UnitItemInSlot(.Owner, i)
set .charges[i] = GetItemCharges(temp)
set .items[i] = GetItemTypeId(temp)
call RemoveItem(temp)
set i = i + 1
endloop
call UnitAddItemToSlotById(.Owner, BACKPACK_CLOSE_ID, 5)
if .bpage <= 1 then
set i = 0
loop
exitwhen i > 3
if .backp[i] != 0 then
call UnitAddItemToSlotById(.Owner, .backp[i], i)
call SetItemCharges(UnitItemInSlot(.Owner, i), .bcharges[i])
endif
set i = i + 1
endloop
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
elseif .bpage >= 2 then
set i = 0
loop
exitwhen i > 3
if .backp[i+4] != 0 then
call UnitAddItemToSlotById(.Owner, .backp[i+4], i)
call SetItemCharges(UnitItemInSlot(.Owner, i), .bcharges[i+4])
endif
set i = i + 1
endloop
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
endif
set temp = null
set .allowauto = true
return true
endif
return true
endmethod
//opens the equipment menu
public static method openEquipment takes unit whichUnit returns boolean
local integer i = 0
local thistype this = .table[whichUnit]
local item temp = null
if not .table.exists(whichUnit) then
return false
elseif not .open and not .bopen then
set .open = true
set .allowauto = false
if .page <= 1 or CHANGE_TO_FIRST then
loop
exitwhen i > 5
set temp = UnitItemInSlot(.Owner, i)
set .charges[i] = GetItemCharges(temp)
set .items[i] = GetItemTypeId(temp)
call RemoveItem(temp)
if i < 4 then
call SetItemVisible(.equip[i], true)
call UnitAddItem(.Owner, .equip[i])
endif
set i = i + 1
endloop
call UnitAddItemToSlotById(.Owner, EQUIPMENT_PAGE_2, 4)
elseif .page >= 2 and not CHANGE_TO_FIRST then
loop
exitwhen i > 5
set temp = UnitItemInSlot(.Owner, i)
set .charges[i] = GetItemCharges(temp)
set .items[i] = GetItemTypeId(temp)
call RemoveItem(temp)
if i < 4 then
call SetItemVisible(.equip[i+4], true)
call UnitAddItem(.Owner, .equip[i+4])
endif
set i = i + 1
endloop
call UnitAddItemToSlotById(.Owner, EQUIPMENT_PAGE_1, 4)
endif
call UnitAddItemToSlotById(.Owner, EQUIPMENT_CLOSE_ID, 5)
set .allowauto = true
return true
endif
return true
endmethod
//closes the hero's backpack
public static method closeBackpack takes unit whichUnit returns boolean
local integer i = 0
local item t = null
local thistype this = .table[whichUnit]
local item temp = null
if not .table.exists(whichUnit) then
return false
elseif .bopen then
set .bopen = false
set .allowauto = false
call RemoveItem(UnitItemInSlot(.Owner, 5))
call RemoveItem(UnitItemInSlot(.Owner, 4))
if .bpage <= 1 then
loop
exitwhen i > 3
set temp = UnitRemoveItemFromSlot(.Owner, i)
set .backp[i] = GetItemTypeId(temp)
set .bcharges[i] = GetItemCharges(temp)
call RemoveItem(temp)
set i = i + 1
endloop
elseif .bpage >= 2 then
loop
exitwhen i > 3
set temp = UnitRemoveItemFromSlot(.Owner, i)
set .backp[i+4] = GetItemTypeId(temp)
set .bcharges[i+4] = GetItemCharges(temp)
call RemoveItem(temp)
set i = i + 1
endloop
endif
set i = 0
loop
exitwhen i > 5
if .items[i] != 0 then
call UnitAddItemToSlotById(.Owner, .items[i], i)
call SetItemCharges(UnitItemInSlot(.Owner, i), .charges[i])
endif
set i = i + 1
endloop
set .bfree = .getBackpackPlace()
call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
set .allowauto = true
set temp = null
return true
endif
return false
endmethod
//closes the hero's equipment menu
public static method closeEquipment takes unit whichUnit returns boolean
local integer i = 0
local item t = null
local thistype this = .table[whichUnit]
local integer add = 0
if not .table.exists(whichUnit) then
return false
elseif .open then
set .open = false
set .allowauto = false
if .page >= 2 then
set add = 4
endif
loop
exitwhen i > 3
set .equip[i+add] = UnitRemoveItemFromSlot(.Owner, i)
call SetItemPosition(.equip[i+add], STORE_ITEM_X, STORE_ITEM_Y)
call SetItemVisible(.equip[i+add], false)
set i = i + 1
endloop
call RemoveItem(UnitItemInSlot(.Owner, 5))
call RemoveItem(UnitItemInSlot(.Owner, 4))
set i = 0
loop
exitwhen i > 5
if .items[i] != 0 then
call UnitAddItemToSlotById(.Owner, .items[i], i)
call SetItemCharges(UnitItemInSlot(.Owner, i), .charges[i])
endif
set i = i + 1
endloop
call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
if CHANGE_TO_FIRST then
set .page = 1
endif
set .allowauto = true
return true
endif
return false
endmethod
//changes the backpack pages of the unit
public static method changePageBackpack takes unit whichUnit returns boolean
local integer i = 0
local thistype this = .table[whichUnit]
local item temp = null
if .bopen and this != 0 then
set .dropped = false
call RemoveItem(UnitItemInSlot(.Owner, 4))
set .dropped = true
set .allowauto = false
if .bpage <= 1 then
loop
exitwhen i > 3
set temp = UnitRemoveItemFromSlot(.Owner, i)
set .backp[i] = GetItemTypeId(temp)
set .bcharges[i] = GetItemCharges(temp)
call UnitAddItemToSlotById(.Owner, .backp[i+4], i)
call SetItemCharges(UnitItemInSlot(.Owner, i), .bcharges[i+4])
call RemoveItem(temp)
set i = i + 1
endloop
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
set .bpage = 2
elseif .bpage >= 2 then
loop
exitwhen i > 3
set temp = UnitRemoveItemFromSlot(.Owner, i)
set .backp[i+4] = GetItemTypeId(temp)
set .bcharges[i+4] = GetItemCharges(temp)
call UnitAddItemToSlotById(.Owner, .backp[i], i)
call SetItemCharges(UnitItemInSlot(.Owner, i), .bcharges[i])
call RemoveItem(temp)
set i = i + 1
endloop
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
set .bpage = 1
endif
set .allowauto = true
set temp = null
return true
endif
return false
endmethod
//changes the equipment menu pages for the unit
public static method changePageEquipment takes unit whichUnit returns boolean
local integer i = 0
local thistype this = .table[whichUnit]
local integer add = 0
if .open and this != 0 then
if .page >= 2 then
set add = 4
endif
set .allowauto = false
loop
exitwhen i > 3
set .equip[i+add] = UnitRemoveItemFromSlot(.Owner, i)
call SetItemPosition(.equip[i+add], STORE_ITEM_X, STORE_ITEM_Y)
call SetItemVisible(.equip[i+add], false)
call UnitAddItem(.Owner, .equip[i+4-add])
set i = i + 1
endloop
set .dropped = false
call RemoveItem(UnitItemInSlot(.Owner, 4))
set .dropped = true
if .page >= 2 then
call UnitAddItemToSlotById(.Owner, EQUIPMENT_PAGE_2, 4)
set .page = 1
elseif .page <= 1 then
call UnitAddItemToSlotById(.Owner, EQUIPMENT_PAGE_1, 4)
set .page = 2
endif
set .allowauto = true
return true
endif
return false
endmethod
//Only call this method, if you can be shure, that the Item's slot is empty or it will bug!
public static method quickEquip takes unit u, Item it returns boolean
local thistype this = .table[u]
if .checkHero(it, true) then
set .equip[it.slot] = CreateItem(it.itemId, STORE_ITEM_X, STORE_ITEM_Y)
call SetItemVisible(.equip[it.slot], false)
call SetItemDroppable(.equip[it.slot], false)
call .applyItemStats(it)
return true
endif
return false
endmethod
//equips an item for a hero
public static method equipItem takes unit u, item t, Item it returns boolean
local thistype this = .table[u]
local integer itd1 = 0
local integer itd2 = 0
local integer slot = 0
local integer i = 0
if .checkHero(it, true) then
if not .isItemEquipped(t) and .isSlotEmpty(it.slot) then
if not .open then
call RemoveItem(.equip[it.slot])
set .equip[it.slot] = t
call SetItemPosition(.equip[it.slot], STORE_ITEM_X, STORE_ITEM_Y)
call SetItemVisible(.equip[it.slot], false)
call SetItemDroppable(.equip[it.slot], false)
call .applyItemStats(it)
return true
elseif .open then
set .dropped = false
if .page <= 1 then
if it.slot <= 3 then
if not (GetItemTypeId(UnitItemInSlot(.Owner, it.slot)) == DUMMY_ITEMS[it.slot]) then
if not .getSlotForItem(UnitItemInSlot(.Owner, it.slot)) then
call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
return false
endif
else
call RemoveItem(UnitItemInSlot(.Owner, it.slot))
endif
call UnitAddItemToSlotById(.Owner, it.itemId, it.slot)
call .applyItemStats(it)
return true
elseif it.slot > 3 then
if not (GetItemTypeId(.equip[it.slot]) == DUMMY_ITEMS[it.slot]) then
if not .getSlotForItem(.equip[it.slot]) then
call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
return false
endif
else
call RemoveItem(.equip[it.slot])
endif
set .equip[it.slot] = t
call SetItemPosition(.equip[it.slot], STORE_ITEM_X, STORE_ITEM_Y)
call SetItemVisible(.equip[it.slot], false)
call SetItemDroppable(.equip[it.slot], false)
call .applyItemStats(it)
return true
endif
elseif .page >= 2 then
if it.slot > 3 then
if not (GetItemTypeId(UnitItemInSlot(.Owner, it.slot - 4)) == DUMMY_ITEMS[it.slot]) then
if not .getSlotForItem(UnitItemInSlot(.Owner, it.slot - 4)) then
call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
return false
endif
else
call RemoveItem(UnitItemInSlot(.Owner, it.slot - 4))
endif
call UnitAddItemToSlotById(.Owner, it.itemId, it.slot - 4)
call .applyItemStats(it)
return true
elseif it.slot <= 3 then
if not (GetItemTypeId(.equip[it.slot]) == DUMMY_ITEMS[it.slot]) then
if not .getSlotForItem(UnitItemInSlot(.Owner, it.slot)) then
call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
return false
endif
else
call RemoveItem(.equip[it.slot])
endif
set .equip[it.slot] = t
call SetItemPosition(.equip[it.slot], STORE_ITEM_X, STORE_ITEM_Y)
call SetItemVisible(.equip[it.slot], false)
call SetItemDroppable(.equip[it.slot], false)
call .applyItemStats(it)
return true
endif
endif
endif
elseif not .isSlotEmpty(it.slot) then
set itd1 = GetItemTypeId(t)
set slot = .getItemSlot(t)
call RemoveItem(t)
set itd2 = GetItemTypeId(.equip[it.slot])
call RemoveItem(.equip[it.slot])
call .removeItemStats(Item.getItemById(itd2))
call .applyItemStats(it)
set .equip[it.slot] = CreateItem(itd1, STORE_ITEM_X, STORE_ITEM_Y)
call SetItemVisible(.equip[it.slot], false)
call UnitAddItemToSlotById(.Owner, itd2, slot)
call SetItemDroppable(.equip[it.slot], false)
return true
endif
endif
return false
endmethod
//un-equips an item for the hero
public static method unequipItem takes unit u, item t, Item it returns boolean
local thistype this = .table[u]
if not .getSlotForItem(t) then
call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
return false
else
call .removeItemStats(it)
set .equip[it.slot] = UnitAddItemById(.Owner, DUMMY_ITEMS[it.slot])
return true
endif
endmethod
//Returns true, if the given item is equipped (or an item with the same ItemTypeId)
public method isItemEquipped takes item whichItem returns boolean //INLINE FRIENDLY
return GetItemTypeId(.equip[Item.getItemById(GetItemTypeId(whichItem)).slot]) == GetItemTypeId(whichItem)
endmethod
//Returns true, if the given slot is empty
public method isSlotEmpty takes integer Slot returns boolean //INLINE FRIENDLY
return GetItemTypeId(.equip[Slot]) == DUMMY_ITEMS[Slot]
endmethod
//checks, if the hero has the possibility to stack the given item with another
public method checkItemForStack takes item for returns boolean
local integer i = 0
local integer id = GetItemTypeId(for)
local integer bonus = 0
local Item it = Item.getItemById(GetItemTypeId(for))
if not .open and not .bopen and not it.equippable then
loop
exitwhen i > 5
if GetItemTypeId(UnitItemInSlot(.Owner, i)) == id and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= MAX_ITEM_CHARGES and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
call RemoveItem(for)
call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(UnitItemInSlot(.Owner, i)) + bonus)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 7
if .backp[i] == id and .bcharges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
set .bcharges[i] = .bcharges[i] + bonus
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
elseif .open then
loop
exitwhen i > 5
if .items[i] == id and .charges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .charges[i] + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
call RemoveItem(for)
set .charges[i] = .charges[i] + bonus
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 7
if .backp[i] == id and .bcharges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
call RemoveItem(for)
set .bcharges[i] = .bcharges[i] + bonus
return true
endif
set i = i + 1
endloop
elseif .bopen then
loop
exitwhen i > 5
if .items[i] == id and .charges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .charges[i] + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
call RemoveItem(for)
set .charges[i] = .charges[i] + bonus
return true
endif
set i = i + 1
endloop
if .bpage <= 1 then
set i = 0
loop
exitwhen i > 3
if GetItemTypeId(UnitItemInSlot(.Owner, i)) == id and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= MAX_ITEM_CHARGES and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
call RemoveItem(for)
call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(UnitItemInSlot(.Owner, i)) + bonus)
return true
endif
set i = i + 1
endloop
set i = 4
loop
exitwhen i > 7
if .backp[i] == id and .bcharges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
call RemoveItem(for)
set .bcharges[i] = .bcharges[i] + bonus
return true
endif
set i = i + 1
endloop
elseif .bpage >= 2 then
set i = 0
loop
exitwhen i > 3
if GetItemTypeId(UnitItemInSlot(.Owner, i)) == id and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= MAX_ITEM_CHARGES and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
call RemoveItem(for)
call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(UnitItemInSlot(.Owner, i)) + bonus)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 3
if .backp[i] == id and .bcharges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(for) <= it.maxCharges then
set bonus = GetItemCharges(for)
set .bcharges[i] = .bcharges[i] + bonus
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
endif
endif
return false
endmethod
//checks if the hero has a empty item slot
public method getSlotForItem takes item for returns boolean
local integer i = 0
local integer id = GetItemTypeId(for)
if not .open and not .bopen then
loop
exitwhen i > 5
if UnitItemInSlot(.Owner, i) == null then
call UnitAddItemToSlotById(.Owner, id, i)
call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(for))
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 7
if .backp[i] == 0 then
set .backp[i] = id
set .bcharges[i] = GetItemCharges(for)
call RemoveItem(for)
set .bfree = .bfree - 1
if not .open or .bopen then
call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
endif
return true
endif
set i = i + 1
endloop
elseif .open then
loop
exitwhen i > 5
if .items[i] == 0 then
set .items[i] = id
set .charges[i] = GetItemCharges(for)
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 7
if .backp[i] == 0 then
set .backp[i] = id
set .bcharges[i] = GetItemCharges(for)
call RemoveItem(for)
set .bfree = .bfree - 1
if not .open or .bopen then
call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
endif
return true
endif
set i = i + 1
endloop
elseif .bopen then
if .bpage <= 1 then
set i = 0
loop
exitwhen i > 3
if UnitItemInSlot(.Owner, i) == null then
call UnitAddItemToSlotById(.Owner, id, i)
call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(for))
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
set i = 4
loop
exitwhen i > 7
if .backp[i] == 0 then
set .backp[i] = id
set .bcharges[i] = GetItemCharges(for)
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 5
if .items[i] == 0 then
set .items[i] = id
set .charges[i] = GetItemCharges(for)
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
elseif .bpage >= 2 then
set i = 0
loop
exitwhen i > 3
if UnitItemInSlot(.Owner, i) == null then
call UnitAddItemToSlotById(.Owner, id, i)
call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(for))
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 3
if .backp[i] == 0 then
set .backp[i] = id
set .bcharges[i] = GetItemCharges(for)
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 5
if .items[i] == 0 then
set .items[i] = id
set .charges[i] = GetItemCharges(for)
call RemoveItem(for)
return true
endif
set i = i + 1
endloop
endif
endif
return false
endmethod
//Applies the item's stats to the hero
private method applyItemStats takes Item it returns nothing
if it.Ms + GetUnitMoveSpeed(.Owner) > MAX_MOVEMENT_SPEED then
set .MsBoni[it.slot] = MAX_MOVEMENT_SPEED - GetUnitMoveSpeed(.Owner)
else
set .MsBoni[it.slot] = it.Ms
endif
call SetUnitMoveSpeed(.Owner, GetUnitMoveSpeed(.Owner) + .MsBoni[it.slot])
call UnitAddBonus(.Owner, 0, it.Armor)
call UnitAddBonus(.Owner, 1, it.Dmg)
call UnitAddBonus(.Owner, 2, it.As)
call UnitAddBonus(.Owner, 3, it.MpReg)
call UnitAddBonus(.Owner, 4, it.HpReg)
call UnitAddBonus(.Owner, 5, it.Str)
call UnitAddBonus(.Owner, 6, it.Agi)
call UnitAddBonus(.Owner, 7, it.Int)
call AddUnitMaxState(.Owner, UNIT_STATE_MAX_LIFE, it.Life)
call AddUnitMaxState(.Owner, UNIT_STATE_MAX_MANA, it.Mana)
if it.Effect != "" and it.EffectAttach != "" then
set .fx[it.slot] = AddSpecialEffectTarget(it.Effect, .Owner, it.EffectAttach)
endif
if it.Abil != 0 then
call UnitAddAbility(.Owner, it.Abil)
endif
endmethod
//removes the ItemStats for the hero
private method removeItemStats takes Item it returns nothing
if GetUnitMoveSpeed(.Owner) - .MsBoni[it.slot] < MIN_MOVEMENT_SPEED then
call SetUnitMoveSpeed(.Owner, MIN_MOVEMENT_SPEED)
else
call SetUnitMoveSpeed(.Owner, GetUnitMoveSpeed(.Owner) - .MsBoni[it.slot])
endif
set .MsBoni[it.slot] = 0.
call UnitAddBonus(.Owner, 0, -(it.Armor))
call UnitAddBonus(.Owner, 1, -(it.Dmg))
call UnitAddBonus(.Owner, 2, -(it.As))
call UnitAddBonus(.Owner, 3, -(it.MpReg))
call UnitAddBonus(.Owner, 4, -(it.HpReg))
call UnitAddBonus(.Owner, 5, -(it.Str))
call UnitAddBonus(.Owner, 6, -(it.Agi))
call UnitAddBonus(.Owner, 7, -(it.Int))
call AddUnitMaxState(.Owner, UNIT_STATE_MAX_LIFE, -(it.Life))
call AddUnitMaxState(.Owner, UNIT_STATE_MAX_MANA, -(it.Mana))
if it.Effect != "" and it.EffectAttach != "" then
call DestroyEffect(.fx[it.slot])
endif
if it.Abil != 0 then
call UnitRemoveAbility(.Owner, it.Abil)
endif
endmethod
//returns the slot of an item
private method getItemSlot takes item it returns integer
local item temp = null
local integer i = 0
loop
set temp = UnitItemInSlot(.Owner, i)
exitwhen i > 5 or temp == it
set i = i + 1
endloop
set temp = null
return i
endmethod
//Returns the first free Inventory slot of the hero
private method getFreeSlot takes nothing returns integer
local integer i = 0
local integer free
loop
exitwhen i > 4
if .items[i] == 0 then
set free = i
endif
exitwhen .items[i] == 0
set i = i + 1
endloop
return free
endmethod
//Returns the first free backpack slot of the hero
private method getFreeBackpackSlot takes nothing returns integer
local integer i = 0
local integer free
loop
exitwhen i > 7
if .backp[i] == 0 then
set free = i
endif
exitwhen .backp[i] == 0
set i = i + 1
endloop
return free
endmethod
//Returns the free place of the hero's backpack
private method getBackpackPlace takes nothing returns integer
local integer i = 0
local integer i2 = 8
loop
exitwhen i > 7
if .backp[i] != 0 then
set i2 = i2 - 1
endif
set i = i + 1
endloop
return i2
endmethod
//Returns the free place of the hero's Inventory
private method getInventoryPlace takes nothing returns integer
local integer i = 0
local integer i2 = 4
loop
exitwhen i > 3
if .items[i] != 0 then
set i2 = i2 - 1
endif
set i = i + 1
endloop
return i2
endmethod
//moves an item to the hero's backpack
private method moveToBackpack takes item Moved, item Bag returns boolean
local integer i = 0
local integer id = GetItemTypeId(Moved)
local integer Slot
if .getBackpackPlace() > 0 then
loop
exitwhen i > 7
if .backp[i] == id and .bcharges[i] + GetItemCharges(Moved) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(Moved) <= Item.getItemById(GetItemTypeId(Moved)).maxCharges then
set .bcharges[i] = .bcharges[i] + GetItemCharges(Moved)
call RemoveItem(Bag)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_OPEN_ID, BACKPACK_SLOT)
call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 7
if .backp[i] == 0 then
set .backp[i] = id
set .bcharges[i] = GetItemCharges(Moved)
set .bfree = .bfree - 1
call RemoveItem(Bag)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_OPEN_ID, BACKPACK_SLOT)
call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
return true
endif
set i = i + 1
endloop
elseif .getBackpackPlace() <= 0 then
set Slot = .getItemSlot(Moved)
set i = GetItemCharges(Moved)
call RemoveItem(Bag)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_OPEN_ID, BACKPACK_SLOT)
call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
call UnitAddItemToSlotById(.Owner, id, Slot)
call SetItemCharges(UnitItemInSlot(.Owner, Slot), i)
call SimError(GetOwningPlayer(.Owner), "Backpack is full!")
return false
endif
return false
endmethod
//moves an item from the first page to the second page
private method moveToSecondPage takes item Moved, item Second returns boolean
local integer i = 0
local integer id = GetItemTypeId(Moved)
local integer Slot
loop
exitwhen i > 3
if .backp[i+4] == id and .bcharges[i+4] + GetItemCharges(Moved) <= MAX_ITEM_CHARGES and .bcharges[i+4] + GetItemCharges(Moved) <= Item.getItemById(GetItemTypeId(Moved)).maxCharges then
set .bcharges[i+4] = .bcharges[i+4] + GetItemCharges(Moved)
call RemoveItem(Second)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 3
if .backp[i+4] == 0 then
set .backp[i+4] = id
set .bcharges[i+4] = GetItemCharges(Moved)
call RemoveItem(Second)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
return true
endif
set i = i + 1
endloop
set Slot = .getItemSlot(Moved)
set i = GetItemCharges(Moved)
call RemoveItem(Second)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
call UnitAddItemToSlotById(.Owner, id, Slot)
call SetItemCharges(UnitItemInSlot(.Owner, Slot), i)
call SimError(GetOwningPlayer(.Owner), "Cannot move item to a full page!")
return false
endmethod
//moves an item from the second page to the first page
private method moveToFirstPage takes item Moved, item First returns boolean
local integer i = 0
local integer id = GetItemTypeId(Moved)
local integer Slot
loop
exitwhen i > 3
if .backp[i] == id and .bcharges[i] + GetItemCharges(Moved) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(Moved) <= Item.getItemById(GetItemTypeId(Moved)).maxCharges then
set .bcharges[i] = .bcharges[i] + GetItemCharges(Moved)
call RemoveItem(First)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
return true
endif
set i = i + 1
endloop
set i = 0
loop
exitwhen i > 3
if .backp[i] == 0 then
set .backp[i] = id
set .bcharges[i] = GetItemCharges(Moved)
call RemoveItem(First)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
return true
endif
set i = i + 1
endloop
set Slot = .getItemSlot(Moved)
set i = GetItemCharges(Moved)
call RemoveItem(First)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
call UnitAddItemToSlotById(.Owner, id, Slot)
call SetItemCharges(UnitItemInSlot(.Owner, Slot), i)
call SimError(GetOwningPlayer(.Owner), "Cannot move item to a full page!")
return false
endmethod
//moves an item to the heroes inventory
private method moveToInventory takes item Moved, item Close returns boolean
local integer i = 0
local integer id = GetItemTypeId(Moved)
local integer Slot
if .getInventoryPlace() > 0 then
loop
exitwhen i > 3
if .items[i] == id and .charges[i] + GetItemCharges(Moved) <= MAX_ITEM_CHARGES and .charges[i] + GetItemCharges(Moved) <= Item.getItemById(GetItemTypeId(Moved)).maxCharges then
set .charges[i] = .charges + GetItemCharges(Moved)
set .bfree = .bfree + 1
call RemoveItem(Close)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_CLOSE_ID, 5)
return true
endif
set i = i + 1
endloop
set i = .getFreeSlot()
set .items[i] = id
set .charges[i] = GetItemCharges(Moved)
set .bfree = .bfree + 1
call RemoveItem(Close)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_CLOSE_ID, 5)
return true
elseif .getInventoryPlace() <= 0 then
set Slot = .getItemSlot(Moved)
set i = GetItemCharges(Moved)
call RemoveItem(Close)
call RemoveItem(Moved)
call UnitAddItemToSlotById(.Owner, BACKPACK_CLOSE_ID, 5)
call UnitAddItemToSlotById(.Owner, id, Slot)
call SetItemCharges(UnitItemInSlot(.Owner, Slot), i)
call SimError(GetOwningPlayer(.Owner), "Inventory is full!")
return false
endif
return false
endmethod
//checks, if a hero can equip an item
public method checkHero takes Item it, boolean UseError returns boolean
if it.HeroClasses != "" then
if not SearchString(it.HeroClasses, .HeroClass) then
if UseError then
call SimError(GetOwningPlayer(.Owner), "Only " + it.HeroClasses + " can equip this item.")
endif
return false
endif
endif
if it.ItemClass != "" then
if not SearchString(.ItemClasses, it.ItemClass) then
if UseError then
call SimError(GetOwningPlayer(.Owner), "This unit can't equip " + it.ItemClass + ".")
endif
return false
endif
endif
if GetHeroLevel(.Owner) >= it.Level then
return true
else
if UseError then
call SimError(GetOwningPlayer(.Owner), "This item requires a hero level of " + I2S(it.Level) + " or greater.")
endif
endif
return false
endmethod
//will be runned, whenever an item is used
private static method useItem takes nothing returns boolean
local thistype this = .table[GetTriggerUnit()]
local Item it = Item.getItemById(GetItemTypeId(GetManipulatedItem()))
if GetItemTypeId(GetManipulatedItem()) == EQUIPMENT_OPEN_ID then
return .openEquipment(GetTriggerUnit())
elseif GetItemTypeId(GetManipulatedItem()) == BACKPACK_OPEN_ID then
return .openBackpack(GetTriggerUnit())
elseif GetItemTypeId(GetManipulatedItem()) == EQUIPMENT_CLOSE_ID or GetItemTypeId(GetManipulatedItem()) == BACKPACK_CLOSE_ID then
if .open then
return .closeEquipment(GetTriggerUnit())
elseif .bopen then
return .closeBackpack(GetTriggerUnit())
endif
elseif GetItemTypeId(GetManipulatedItem()) == EQUIPMENT_PAGE_1 or GetItemTypeId(GetManipulatedItem()) == EQUIPMENT_PAGE_2 or GetItemTypeId(GetManipulatedItem()) == BACKPACK_PAGE_1 or GetItemTypeId(GetManipulatedItem()) == BACKPACK_PAGE_2 then
if .open then
return .changePageEquipment(GetTriggerUnit())
elseif .bopen then
return .changePageBackpack(GetTriggerUnit())
endif
elseif it.equippable and not .isItemEquipped(GetManipulatedItem()) then
return .equipItem(GetTriggerUnit(), GetManipulatedItem(), it)
elseif it.equippable and .isItemEquipped(GetManipulatedItem()) then
return .unequipItem(GetTriggerUnit(), GetManipulatedItem(), it)
endif
return false
endmethod
//Will be runned, whenever an item is dragged on another item or on an empty slot
private static method dragItem takes nothing returns boolean
local item manipul = GetOrderTargetItem()
local integer slot = GetIssuedOrderId() - 852002
local thistype this = .table[GetTriggerUnit()]
local item dropped = UnitItemInSlot(.Owner, slot)
local integer id = GetItemTypeId(manipul)
local integer idd = GetItemTypeId(dropped)
if (GetIssuedOrderId() > 852001) and (GetIssuedOrderId() < 852008) and this != 0 then
if manipul != dropped and id != BACKPACK_PAGE_1 and id != BACKPACK_PAGE_2 and id != BACKPACK_CLOSE_ID and id != BACKPACK_OPEN_ID then
if idd == BACKPACK_OPEN_ID then
set .dropped = false
call .moveToBackpack(manipul, dropped)
set .dropped = true
set manipul = null
set dropped = null
return false
elseif idd == BACKPACK_CLOSE_ID then
set .dropped = false
call .moveToInventory(manipul, dropped)
set .dropped = true
set manipul = null
set dropped = null
return false
elseif idd == BACKPACK_PAGE_2 then
set .dropped = false
call .moveToSecondPage(manipul, dropped)
set .dropped = true
set manipul = null
set dropped = null
return false
elseif idd == BACKPACK_PAGE_1 then
set .dropped = false
call .moveToFirstPage(manipul, dropped)
set .dropped = true
set manipul = null
set dropped = null
return false
endif
endif
endif
if id == BACKPACK_OPEN_ID or id == BACKPACK_CLOSE_ID or id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 and dropped == null then
if id == BACKPACK_OPEN_ID and not .bopen and not .open then
call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
call addItem.create(manipul, BACKPACK_SLOT, this)
set manipul = null
set dropped = null
return false
elseif id == BACKPACK_CLOSE_ID or id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 and .bopen then
call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
if id == BACKPACK_CLOSE_ID then
call addItem.create(manipul, 5, this)
elseif id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 then
call addItem.create(manipul, 4, this)
endif
set manipul = null
set dropped = null
return false
endif
endif
if (id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2) and idd == BACKPACK_CLOSE_ID and .bopen then
call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
call addItem.create(manipul, 4, this)
call addItem.create(dropped, 5, this)
set manipul = null
set dropped = null
return false
elseif id == BACKPACK_CLOSE_ID and (idd == BACKPACK_PAGE_1 or idd == BACKPACK_PAGE_2) and .bopen then
call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
call addItem.create(manipul, 5, this)
call addItem.create(dropped, 4, this)
set manipul = null
set dropped = null
return false
endif
set manipul = null
set dropped = null
return true
endmethod
//will be runned whenever an item is picked up
private static method pickupItem takes nothing returns boolean
local thistype this = .table[GetTriggerUnit()]
local item i = GetManipulatedItem()
local Item it = Item.getItemById(GetItemTypeId(i))
if AUTO_EQUIP and it.equippable and .isSlotEmpty(it.slot) and .checkHero(it, false) and .allowauto then
call thistype.equipItem(GetTriggerUnit(), GetManipulatedItem(), it)
set i = null
return true
endif
return false
endmethod
//Will be runned whenever an item is dropped
private static method dropItem takes nothing returns boolean
local thistype this = .table[GetTriggerUnit()]
local item ite = GetManipulatedItem()
local integer id = GetItemTypeId(ite)
if this == 0 or ite == null or not .dropped then
return false
elseif this != 0 and ite != null and .dropped then
if id == BACKPACK_OPEN_ID and not .bopen and not .open then
call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
call addItem.create(ite, BACKPACK_SLOT, this)
set ite = null
return true
elseif id == BACKPACK_CLOSE_ID or id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 and (.bopen or .open) then
if id == BACKPACK_CLOSE_ID then
call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
call addItem.create(ite, 5, this)
set ite = null
return true
elseif id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 then
call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
call addItem.create(ite, 4, this)
set ite = null
return true
endif
endif
endif
return false
endmethod
//initialization of the Inventory struct
private static method onInit takes nothing returns nothing
call TriggerAddCondition(.Use, Condition(function thistype.useItem))
call TriggerAddCondition(.Pickup, Condition(function thistype.pickupItem))
call TriggerAddCondition(.Drag, Condition(function thistype.dragItem))
call TriggerAddCondition(.Drop, Condition(function thistype.dropItem))
set .table = HandleTable.create()
call SETUP_DUMMY_ITEMS()
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library ItemList
globals
//If true, item abilitys will be preloaded on map init, when adding one to the systen (longer laod time, but no laggs if first time used/equipped)
private constant boolean PRELOAD_ABILITYS = false
//The unit for preloading item abilitys
private constant integer PRELOAD_DUMMY_ID = 'hpea'
endglobals
//The struct for each item, you have registred
struct Item
integer Life = 0
integer Mana = 0
integer Str = 0
integer Agi = 0
integer Int = 0
integer Dmg = 0
integer Armor = 0
integer Level = 1
integer HpReg = 0
integer MpReg = 0
integer As = 0
integer Abil = 0
real Ms = 0.
string Effect = ""
string EffectAttach = ""
string ItemClass
string HeroClasses
private integer ItemId = 0
private integer Slot
private boolean AllowStacks = false
private boolean Equipment = true
private integer id = 0
private integer MaxStacks = 0
private static Table table
private static boolean allowAdd = true
private static trigger Disabler = CreateTrigger()
private static unit dummy = null
//Use this method to register an Item, which IS equippable to the system
//Example: call Item.addEquipment('I000', 2, "Bloogmages", "Cloth Armors")
//This would register the item as a weapon (see above), which ItemTypeId is 'I000' to the system
//has the ItemClass "Cloth Armors" and is only equippable by "Bloodmages"
static method addEquipment takes integer ItemId, integer Slot, string availableHeroClasses, string itemClass returns thistype
local thistype this = 0
if .allowAdd then
set this = .allocate()
set .ItemId = ItemId
set .Slot = Slot
set .HeroClasses = availableHeroClasses
set .ItemClass = itemClass
set .id = .id + 1
set .table[.ItemId] = this
return this
debug else
call BJDebugMsg("Can only register Items in Map Initialization")
endif
return 0
endmethod
//Use this method to register an Item, which IS NOT equippable to the system
//Example: call Item.addNormalItem('I001', true, 6)
//This would register the item, which ItemTypeId is 'I001' to the system, enables Stacks for it and sets its MaxStacks to 6
static method addNormalItem takes integer ItemId, boolean AllowStacks, integer MaxStacks returns thistype
local thistype this = 0
if .allowAdd then
set this = .allocate()
set .ItemId = ItemId
set .Equipment = false
set .MaxStacks = MaxStacks
set .id = .id + 1
set .table[.ItemId] = this
return this
debug else
call BJDebugMsg("Can only register Items in Map Initialization")
endif
return 0
endmethod
//call this method after adding an ability to an item. If you set the boolean "inSpellbook" to true,
//the system disables the spellbook for every player (not the ability in it!)
method HasAbility takes boolean inSpellbook returns nothing
local integer i = 0
if PRELOAD_ABILITYS then
call UnitAddAbility(.dummy, .Abil)
call UnitRemoveAbility(.dummy, .Abil)
endif
if inSpellbook then
loop
call SetPlayerAbilityAvailable(Player(i), .Abil, false)
set i = i + 1
exitwhen i >= bj_MAX_PLAYER_SLOTS
endloop
endif
endmethod
//use this to get the slot of the item. Returns -1 if the item isn't equipable
method operator slot takes nothing returns integer
if .Equipment then
return .Slot
else
return -1
endif
return -1
endmethod
//returns true, if item is equippable
method operator equippable takes nothing returns boolean //INLINE FRIENDLY
return .Equipment
endmethod
//Returns the item Id of the used Item
//Can be used for Save & Load Systems
method operator itemId takes nothing returns integer //INLINE FRIENDLY
return .ItemId
endmethod
//Returns the MaxCharges of an item
method operator maxCharges takes nothing returns integer //INLINE FRIENDLY
return .MaxStacks
endmethod
//Returns the Item struct by using its index
static method getItemByIndex takes integer Id returns Item //INLINE FRIENDLY
return Item(Id)
endmethod
//Returns the Item Struct by the item Type Id
static method getItemById takes integer ItemId returns Item //INLINE FRIENDLY
return Item(.table[ItemId])
endmethod
//Disables the registring after map Initialization
private static method disableAdd takes nothing returns boolean
set .allowAdd = false
call DestroyTrigger(.Disabler)
if PRELOAD_ABILITYS then
call KillUnit(.dummy)
endif
return .allowAdd
endmethod
//self-explanatory
private static method onInit takes nothing returns nothing
if PRELOAD_ABILITYS then
set .dummy = CreateUnit(Player(15), PRELOAD_DUMMY_ID, 0., 0., 0.)
endif
call TriggerRegisterTimerEvent(.Disabler, 0., false)
call TriggerAddCondition(.Disabler, Condition(function Item.disableAdd))
set .table = Table.create()
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
// 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 paramiter is the display value of the ability. This is so that they all line up
// neatly in the object editor.
//
// The third paramiter 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.
// BonusMod - Armor
//============================================================================================
//! textmacro ArmorAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AId1 $RAWCODE$ Idef 1 $VALUE$ anam "BonusMod - Armor ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNHumanArmorUpOne.blp
//! endtextmacro
//! runtextmacro ArmorAbility("ZxA0", "+0001", "1")
//! runtextmacro ArmorAbility("ZxA1", "+0002", "2")
//! runtextmacro ArmorAbility("ZxA2", "+0004", "4")
//! runtextmacro ArmorAbility("ZxA3", "+0008", "8")
//! runtextmacro ArmorAbility("ZxA4", "+0016", "16")
//! runtextmacro ArmorAbility("ZxA5", "+0032", "32")
//! runtextmacro ArmorAbility("ZxA6", "+0064", "64")
//! runtextmacro ArmorAbility("ZxA7", "+0128", "128")
//! runtextmacro ArmorAbility("ZxA8", "+0256", "256")
//! runtextmacro ArmorAbility("ZxA9", "+0512", "512")
//! runtextmacro ArmorAbility("ZxAa", "+1024", "1024")
//! runtextmacro ArmorAbility("ZxAb", "+2048", "2048")
//! runtextmacro ArmorAbility("ZxAc", "-4096", "-4096")
// BonusMod - Damage
//============================================================================================
//! textmacro DamageAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AItg $RAWCODE$ Iatt 1 $VALUE$ anam "BonusMod - Damage ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNSteelMelee.blp
//! endtextmacro
//! runtextmacro DamageAbility("ZxB0", "+0001", "1")
//! runtextmacro DamageAbility("ZxB1", "+0002", "2")
//! runtextmacro DamageAbility("ZxB2", "+0004", "4")
//! runtextmacro DamageAbility("ZxB3", "+0008", "8")
//! runtextmacro DamageAbility("ZxB4", "+0016", "16")
//! runtextmacro DamageAbility("ZxB5", "+0032", "32")
//! runtextmacro DamageAbility("ZxB6", "+0064", "64")
//! runtextmacro DamageAbility("ZxB7", "+0128", "128")
//! runtextmacro DamageAbility("ZxB8", "+0256", "256")
//! runtextmacro DamageAbility("ZxB9", "+0512", "512")
//! runtextmacro DamageAbility("ZxBa", "+1024", "1024")
//! runtextmacro DamageAbility("ZxBb", "+2048", "2048")
//! runtextmacro DamageAbility("ZxBc", "-4096", "-4096")
// BonusMod - Attack Speed
//============================================================================================
//! textmacro AttackSpeedAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIs2 $RAWCODE$ Iatt 1 $VALUE$ anam "BonusMod - Attack Speed ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNGlove.blp
//! endtextmacro
//! runtextmacro AttackSpeedAbility("ZxC0", "+0001", "1")
//! runtextmacro AttackSpeedAbility("ZxC1", "+0002", "2")
//! runtextmacro AttackSpeedAbility("ZxC2", "+0004", "4")
//! runtextmacro AttackSpeedAbility("ZxC3", "+0008", "8")
//! runtextmacro AttackSpeedAbility("ZxC4", "+0016", "16")
//! runtextmacro AttackSpeedAbility("ZxC5", "+0032", "32")
//! runtextmacro AttackSpeedAbility("ZxC6", "+0064", "64")
//! runtextmacro AttackSpeedAbility("ZxC7", "+0128", "128")
//! runtextmacro AttackSpeedAbility("ZxC8", "+0256", "256")
//! runtextmacro AttackSpeedAbility("ZxC9", "+0512", "512")
//! runtextmacro AttackSpeedAbility("ZxCa", "+1024", "1024")
//! runtextmacro AttackSpeedAbility("ZxCb", "+2048", "2048")
//! runtextmacro AttackSpeedAbility("ZxCc", "-4096", "-4096")
// BonusMod - Mana Regeneration
//============================================================================================
//! textmacro ManaRegenAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIrm $RAWCODE$ Imrp 1 $VALUE$ anam "BonusMod - Mana Regen ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNSobiMask.blp
//! endtextmacro
//! runtextmacro ManaRegenAbility("ZxD0", "+0001", "0.01")
//! runtextmacro ManaRegenAbility("ZxD1", "+0002", "0.02")
//! runtextmacro ManaRegenAbility("ZxD2", "+0004", "0.04")
//! runtextmacro ManaRegenAbility("ZxD3", "+0008", "0.08")
//! runtextmacro ManaRegenAbility("ZxD4", "+0016", "0.16")
//! runtextmacro ManaRegenAbility("ZxD5", "+0032", "0.32")
//! runtextmacro ManaRegenAbility("ZxD6", "+0064", "0.64")
//! runtextmacro ManaRegenAbility("ZxD7", "+0128", "1.28")
//! runtextmacro ManaRegenAbility("ZxD8", "+0256", "2.56")
//! runtextmacro ManaRegenAbility("ZxD9", "+0512", "5.12")
//! runtextmacro ManaRegenAbility("ZxDa", "+1024", "10.24")
//! runtextmacro ManaRegenAbility("ZxDb", "+2048", "20.48")
//! runtextmacro ManaRegenAbility("ZxDc", "-4096", "-40.96")
// BonusMod - Life Regenration
//============================================================================================
//! textmacro LifeRegenAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a Arel $RAWCODE$ Ihpr 1 $VALUE$ anam "BonusMod - Life Regen ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNRingSkull.blp
//! endtextmacro
//! runtextmacro LifeRegenAbility("ZxE0", "+0001", "1")
//! runtextmacro LifeRegenAbility("ZxE1", "+0002", "2")
//! runtextmacro LifeRegenAbility("ZxE2", "+0004", "4")
//! runtextmacro LifeRegenAbility("ZxE3", "+0008", "8")
//! runtextmacro LifeRegenAbility("ZxE4", "+0016", "16")
//! runtextmacro LifeRegenAbility("ZxE5", "+0032", "32")
//! runtextmacro LifeRegenAbility("ZxE6", "+0064", "64")
//! runtextmacro LifeRegenAbility("ZxE7", "+0128", "128")
//! runtextmacro LifeRegenAbility("ZxE8", "+0256", "256")
//! runtextmacro LifeRegenAbility("ZxE9", "+0512", "512")
//! runtextmacro LifeRegenAbility("ZxEa", "+1024", "1024")
//! runtextmacro LifeRegenAbility("ZxEb", "+2048", "2048")
//! runtextmacro LifeRegenAbility("ZxEc", "-4096", "-4096")
// BonusMod - Strength
//============================================================================================
//! textmacro HeroStrAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIa1 $RAWCODE$ Iagi 1 0 Iint 1 0 Istr 1 $VALUE$ anam "BonusMod - Hero STR ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNGoldRing.blp
//! endtextmacro
//! runtextmacro HeroStrAbility("ZxF0", "+0001", "1")
//! runtextmacro HeroStrAbility("ZxF1", "+0002", "2")
//! runtextmacro HeroStrAbility("ZxF2", "+0004", "4")
//! runtextmacro HeroStrAbility("ZxF3", "+0008", "8")
//! runtextmacro HeroStrAbility("ZxF4", "+0016", "16")
//! runtextmacro HeroStrAbility("ZxF5", "+0032", "32")
//! runtextmacro HeroStrAbility("ZxF6", "+0064", "64")
//! runtextmacro HeroStrAbility("ZxF7", "+0128", "128")
//! runtextmacro HeroStrAbility("ZxF8", "+0256", "256")
//! runtextmacro HeroStrAbility("ZxF9", "+0512", "512")
//! runtextmacro HeroStrAbility("ZxFa", "+1024", "1024")
//! runtextmacro HeroStrAbility("ZxFb", "+2048", "2048")
//! runtextmacro HeroStrAbility("ZxFc", "-4096", "-4096")
// BonusMod - Agility
//============================================================================================
//! textmacro HeroAgiAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIa1 $RAWCODE$ Iagi 1 $VALUE$ Iint 1 0 Istr 1 0 anam "BonusMod - Hero AGI ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNGoldRing.blp
//! endtextmacro
//! runtextmacro HeroAgiAbility("ZxG0", "+0001", "1")
//! runtextmacro HeroAgiAbility("ZxG1", "+0002", "2")
//! runtextmacro HeroAgiAbility("ZxG2", "+0004", "4")
//! runtextmacro HeroAgiAbility("ZxG3", "+0008", "8")
//! runtextmacro HeroAgiAbility("ZxG4", "+0016", "16")
//! runtextmacro HeroAgiAbility("ZxG5", "+0032", "32")
//! runtextmacro HeroAgiAbility("ZxG6", "+0064", "64")
//! runtextmacro HeroAgiAbility("ZxG7", "+0128", "128")
//! runtextmacro HeroAgiAbility("ZxG8", "+0256", "256")
//! runtextmacro HeroAgiAbility("ZxG9", "+0512", "512")
//! runtextmacro HeroAgiAbility("ZxGa", "+1024", "1024")
//! runtextmacro HeroAgiAbility("ZxGb", "+2048", "2048")
//! runtextmacro HeroAgiAbility("ZxGc", "-4096", "-4096")
// BonusMod - Intelligence
//============================================================================================
//! textmacro HeroIntAbility takes RAWCODE, DISPLAYVALUE, VALUE
//! external ObjectMerger w3a AIa1 $RAWCODE$ Iagi 1 0 Iint 1 $VALUE$ Istr 1 0 anam "BonusMod - Hero INT ($DISPLAYVALUE$)" aite 0 ansf "" aart ReplaceableTextures\CommandButtons\BTNGoldRing.blp
//! endtextmacro
//! runtextmacro HeroIntAbility("ZxH0", "+0001", "1")
//! runtextmacro HeroIntAbility("ZxH1", "+0002", "2")
//! runtextmacro HeroIntAbility("ZxH2", "+0004", "4")
//! runtextmacro HeroIntAbility("ZxH3", "+0008", "8")
//! runtextmacro HeroIntAbility("ZxH4", "+0016", "16")
//! runtextmacro HeroIntAbility("ZxH5", "+0032", "32")
//! runtextmacro HeroIntAbility("ZxH6", "+0064", "64")
//! runtextmacro HeroIntAbility("ZxH7", "+0128", "128")
//! runtextmacro HeroIntAbility("ZxH8", "+0256", "256")
//! runtextmacro HeroIntAbility("ZxH9", "+0512", "512")
//! runtextmacro HeroIntAbility("ZxHa", "+1024", "1024")
//! runtextmacro HeroIntAbility("ZxHb", "+2048", "2048")
//! runtextmacro HeroIntAbility("ZxHc", "-4096", "-4096")
// Don't let a //! external command be the last line in a trigger!
//TESH.scrollpos=0
//TESH.alwaysfold=0
// The Mana ability:
//! external ObjectMerger w3a AImz Zx00 alev 19 aite 0 Iman 1 0 Iman 2 1 Iman 3 2 Iman 4 4 Iman 5 8 Iman 6 16 Iman 7 32 Iman 8 64 Iman 9 128 Iman 10 256 Iman 11 -1 Iman 12 -2 Iman 13 -4 Iman 14 -8 Iman 15 -16 Iman 16 -32 Iman 17 -64 Iman 18 -128 Iman 19 -256 anam "SetUnitMaxState - Mana" ansf "" aart ReplaceableTextures\CommandButtons\BTNManaStone.blp
// The Life ability:
//! external ObjectMerger w3a AIlf Zx01 alev 19 aite 0 Ilif 1 0 Ilif 2 1 Ilif 3 2 Ilif 4 4 Ilif 5 8 Ilif 6 16 Ilif 7 32 Ilif 8 64 Ilif 9 128 Ilif 10 256 Ilif 11 -1 Ilif 12 -2 Ilif 13 -4 Ilif 14 -8 Ilif 15 -16 Ilif 16 -32 Ilif 17 -64 Ilif 18 -128 Ilif 19 -256 anam "SetUnitMaxState - Life" ansf "" aart ReplaceableTextures\CommandButtons\BTNHealthStone.blp
// Don't let a //! external command be the last line in a trigger!
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Heroes initializer init
private function init takes nothing returns nothing
call Inventory.create(gg_unit_Harf_0000, "Paladins", "Heavy Armors, Leather Armors, Cloth Armors, Shields")
call Inventory.create(gg_unit_Eevi_0008, "Demon Hunters", "Leather Armors, Cloth Armors")
call Inventory.create(gg_unit_Hkal_0018, "Bloodmages", "Cloth Armors")
endfunction
endscope
//TESH.scrollpos=46
//TESH.alwaysfold=0
scope TestEquipment initializer init
private function Setup takes nothing returns nothing
local Item it = 0
//Iron Helmet
set it = Item.addEquipment('I00C', 0, "", "Heavy Armors")
set it.Armor = 3
set it.Life = 70
set it.HpReg = 1 //in Percent
//Mage's Cape
set it = Item.addEquipment('I00D', 0, "", "Cloth Armors")
set it.Armor = 1
set it.Int = 4
set it.Mana = 65
//Iron Chainmail
set it = Item.addEquipment('I00F', 1, "", "Heavy Armors")
set it.Level = 3
set it.Life = 100
set it.Str = 5
set it.Armor = 5
//Mage's Robe
set it = Item.addEquipment('I00E', 1, "Bloodmages", "Cloth Armors")
set it.Level = 2
set it.Mana = 85
set it.Int = 5
set it.Armor = 2
set it.MpReg = 2
//Searing Blade
set it = Item.addEquipment('I00G', 2, "Demon Hunters and Paladins", "")
set it.Level = 5
set it.Life = 225
set it.Str = 4
set it.Agi = 7
set it.Effect = "Environment\\SmallBuildingFire\\SmallBuildingFire2.mdl"
set it.EffectAttach = "weapon"
//Aqua Staff
set it = Item.addEquipment('I00H', 2, "Bloodmages", "")
set it.Mana = 100
set it.Int = 6
set it.Dmg = 7
set it.Abil = 'A002'
call it.HasAbility(true)
//Golden Ring
set it = Item.addEquipment('I00I', 7, "", "")
set it.Mana = 40
set it.Life = 40
set it.Str = 2
set it.Agi = 2
set it.Int = 2
//Holy Book
set it = Item.addEquipment('I00J', 6, "Paladins", "")
set it.Level = 4
set it.Life = 125
set it.Str = 4
set it.Int = 4
//Power Boots
set it = Item.addEquipment('I00K', 5, "Demon Hunters", "Leather Armors")
set it.Agi = 4
set it.Abil = 'A003'
set it.Ms = 75.
//Bloody Claws
set it = Item.addEquipment('I00L', 4, "Demon Hunters", "")
set it.Level = 2
set it.Dmg = 3
set it.As = 15
set it.Agi = 2
//Toxic Vapor
set it = Item.addEquipment('I00M', 6, "Demon Hunters", "")
set it.Dmg = 12
set it.Agi = 4
set it.Effect = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
set it.EffectAttach = "hand, left"
//Kil'jaeden' Amulet
set it = Item.addEquipment('I00N', 6, "", "")
set it.Level = 5
set it.Mana = 200
set it.Life = 200
set it.HpReg = 2
set it.MpReg = 2
//Shiny Stone
set it = Item.addEquipment('I00O', 7, "Bloodmages", "")
set it.Mana = 75
set it.Int = 6
set it.MpReg = 3
//Iron Shield
set it = Item.addEquipment('I00X', 3, "", "Shield")
set it.Armor = 1
set it.Life = 25
//Iron Sword
set it = Item.addEquipment('I00W', 2, "", "")
set it.Dmg = 2
set it.Str = 1
//Leather Gloves
set it = Item.addEquipment('I00V', 4, "", "Leather Armors")
set it.As = 5
set it.Agi = 1
//Magic Wand
set it = Item.addEquipment('I00Y', 2, "", "")
set it.Dmg = 7
set it.Mana = 100
set it.Effect = "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"
set it.EffectAttach = "hand"
endfunction
private function init takes nothing returns nothing
call Setup()
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope TestPotions initializer init
private function Setup takes nothing returns nothing
local Item it = 0
//Potion of Healing
set it = Item.addNormalItem('I00P', true, 6)
//Potion of Mana
set it = Item.addNormalItem('I00Q', true, 4)
endfunction
private function init takes nothing returns nothing
call Setup()
endfunction
endscope