Name | Type | is_array | initial_value |
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
library GroupUtils initializer Init requires optional xebasic
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This library is a combination of several features relevant to groups. First
//* and foremost, it contains a group stack that you can access dynamic groups
//* from. It also provides means to refresh groups and clear any shadow
//* references within them. The included boolexprs are there for backwards
//* compatibility with maps that happen to use them. Since the 1.24c patch,
//* null boolexprs used in GroupEnumUnits* calls no longer leak, so there is no
//* performance gain to using the BOOLEXPR_TRUE constant.
//*
//* Instead of creating/destroying groups, we have moved on to recycling them.
//* NewGroup pulls a group from the stack and ReleaseGroup adds it back. Always
//* remember to call ReleaseGroup on a group when you are done using it. If you
//* fail to do so enough times, the stack will overflow and no longer work.
//*
//* GroupRefresh cleans a group of any shadow references which may be clogging
//* its hashtable. If you remove a unit from the game who is a member of a unit
//* group, it will 'effectively' remove the unit from the group, but leave a
//* shadow in its place. Calling GroupRefresh on a group will clean up any
//* shadow references that may exist within it. It is only worth doing this on
//* groups that you plan to have around for awhile.
//*
//* Constants that can be used from the library:
//* [group] ENUM_GROUP As you might expect, this group is good for
//* when you need a group just for enumeration.
//* [boolexpr] BOOLEXPR_TRUE This is a true boolexpr, which is important
//* because a 'null' boolexpr in enumeration
//* calls results in a leak. Use this instead.
//* [boolexpr] BOOLEXPR_FALSE This exists mostly for completeness.
//*
//* This library also includes a simple implementation of a group enumeration
//* call that factors collision of units in a given area of effect. This is
//* particularly useful because GroupEnumUnitsInRange doesn't factor collision.
//*
//* In your map, you can just replace all instances of GroupEnumUnitsInRange
//* with GroupEnumUnitsInArea with identical arguments and your spells will
//* consider all units colliding with the area of effect. After calling this
//* function as you would normally call GroupEnumUnitsInRange, you are free to
//* do anything with the group that you would normally do.
//*
//* If you don't use xebasic in your map, you may edit the MAX_COLLISION_SIZE
//* variable below and the library will use that as the added radius to check.
//* If you use xebasic, however, the script will automatically use xe's
//* collision size variable.
//*
//* You are also able to use GroupUnitsInArea. This function returns all units
//* within the area, no matter what they are, which can be convenient for those
//* instances where you actually want that.
//*
//* Example usage:
//* local group MyGroup = NewGroup()
//* call GroupRefresh(MyGroup)
//* call ReleaseGroup(MyGroup)
//* call GroupEnumUnitsInArea(ENUM_GROUP, x, y, 350., BOOLEXPR_TRUE)
//* call GroupUnitsInArea(ENUM_GROUP, x, y, 350.)
//*
globals
//If you don't have xebasic in your map, this value will be used instead.
//This value corresponds to the max collision size of a unit in your map.
private constant real MAX_COLLISION_SIZE = 197.
//If you are insane and don't care about any of the protection involved in
//this library, but want this script to be really fast, set this to true.
private constant boolean LESS_SAFETY = false
endglobals
globals
//* Constants that are available to the user
group ENUM_GROUP = CreateGroup()
boolexpr BOOLEXPR_TRUE = null
boolexpr BOOLEXPR_FALSE = null
endglobals
globals
//* Hashtable for debug purposes
private hashtable ht = InitHashtable()
//* Temporary references for GroupRefresh
private boolean Flag = false
private group Refr = null
//* Arrays and counter for the group stack
private group array Groups
private integer Count = 0
//* Variables for use with the GroupUnitsInArea function
private real X = 0.
private real Y = 0.
private real R = 0.
private hashtable H = InitHashtable()
endglobals
private function HookDestroyGroup takes group g returns nothing
if g == ENUM_GROUP then
call BJDebugMsg(SCOPE_PREFIX+"Warning: ENUM_GROUP destroyed")
endif
endfunction
debug hook DestroyGroup HookDestroyGroup
private function AddEx takes nothing returns nothing
if Flag then
call GroupClear(Refr)
set Flag = false
endif
call GroupAddUnit(Refr, GetEnumUnit())
endfunction
function GroupRefresh takes group g returns nothing
set Flag = true
set Refr = g
call ForGroup(Refr, function AddEx)
if Flag then
call GroupClear(g)
endif
endfunction
function NewGroup takes nothing returns group
if Count == 0 then
set Groups[0] = CreateGroup()
else
set Count = Count - 1
endif
static if not LESS_SAFETY then
call SaveInteger(ht, 0, GetHandleId(Groups[Count]), 1)
endif
return Groups[Count]
endfunction
function ReleaseGroup takes group g returns boolean
local integer id = GetHandleId(g)
static if LESS_SAFETY then
if g == null then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Null groups cannot be released")
return false
elseif Count == 8191 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max groups achieved, destroying group")
call DestroyGroup(g)
return false
endif
else
if g == null then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Null groups cannot be released")
return false
elseif not HaveSavedInteger(ht, 0, id) then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Group not part of stack")
return false
elseif LoadInteger(ht, 0, id) == 2 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Groups cannot be multiply released")
return false
elseif Count == 8191 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max groups achieved, destroying group")
call DestroyGroup(g)
return false
endif
call SaveInteger(ht, 0, id, 2)
endif
call GroupClear(g)
set Groups[Count] = g
set Count = Count + 1
return true
endfunction
private function Filter takes nothing returns boolean
return IsUnitInRangeXY(GetFilterUnit(), X, Y, R)
endfunction
private function HookDestroyBoolExpr takes boolexpr b returns nothing
local integer bid = GetHandleId(b)
if HaveSavedHandle(H, 0, bid) then
//Clear the saved boolexpr
call DestroyBoolExpr(LoadBooleanExprHandle(H, 0, bid))
call RemoveSavedHandle(H, 0, bid)
endif
endfunction
hook DestroyBoolExpr HookDestroyBoolExpr
private constant function GetRadius takes real radius returns real
static if LIBRARY_xebasic then
return radius+XE_MAX_COLLISION_SIZE
else
return radius+MAX_COLLISION_SIZE
endif
endfunction
function GroupEnumUnitsInArea takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
local real prevX = X
local real prevY = Y
local real prevR = R
local integer bid = 0
//Set variables to new values
set X = x
set Y = y
set R = radius
if filter == null then
//Adjusts for null boolexprs passed to the function
set filter = Condition(function Filter)
else
//Check for a saved boolexpr
set bid = GetHandleId(filter)
if HaveSavedHandle(H, 0, bid) then
//Set the filter to use to the saved one
set filter = LoadBooleanExprHandle(H, 0, bid)
else
//Create a new And() boolexpr for this filter
set filter = And(Condition(function Filter), filter)
call SaveBooleanExprHandle(H, 0, bid, filter)
endif
endif
//Enumerate, if they want to use the boolexpr, this lets them
call GroupEnumUnitsInRange(whichGroup, x, y, GetRadius(radius), filter)
//Give back original settings so nested enumerations work
set X = prevX
set Y = prevY
set R = prevR
endfunction
function GroupUnitsInArea takes group whichGroup, real x, real y, real radius returns nothing
local real prevX = X
local real prevY = Y
local real prevR = R
//Set variables to new values
set X = x
set Y = y
set R = radius
//Enumerate
call GroupEnumUnitsInRange(whichGroup, x, y, GetRadius(radius), Condition(function Filter))
//Give back original settings so nested enumerations work
set X = prevX
set Y = prevY
set R = prevR
endfunction
private function True takes nothing returns boolean
return true
endfunction
private function False takes nothing returns boolean
return false
endfunction
private function Init takes nothing returns nothing
set BOOLEXPR_TRUE = Condition(function True)
set BOOLEXPR_FALSE = Condition(function False)
endfunction
endlibrary
library CustomDummy
globals
constant integer CD_UNIT_ID = 'cdun'
endglobals
function CreateDummy takes player p, real x, real y returns unit
return CreateUnit(p, CD_UNIT_ID, x, y, 0.)
endfunction
endlibrary
/**************************************************************
*
* RegisterPlayerUnitEvent
* v5.1.0.1
* By Magtheridon96
*
* I would like to give a special thanks to Bribe, azlier
* and BBQ for improving this library. For modularity, it only
* supports player unit events.
*
* Functions passed to RegisterPlayerUnitEvent must either
* return a boolean (false) or nothing. (Which is a Pro)
*
* Warning:
* --------
*
* - Don't use TriggerSleepAction inside registered code.
* - Don't destroy a trigger unless you really know what you're doing.
*
* API:
* ----
*
* - function RegisterPlayerUnitEvent takes playerunitevent whichEvent, code whichFunction returns nothing
* - Registers code that will execute when an event fires.
* - function RegisterPlayerUnitEventForPlayer takes playerunitevent whichEvent, code whichFunction, player whichPlayer returns nothing
* - Registers code that will execute when an event fires for a certain player.
* - function GetPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
* - Returns the trigger corresponding to ALL functions of a playerunitevent.
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
globals
private trigger array t
endglobals
function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
local integer i = GetHandleId(p)
local integer k = 15
if t[i] == null then
set t[i] = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
exitwhen k == 0
set k = k - 1
endloop
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
local integer i = 16 * GetHandleId(p) + GetPlayerId(pl)
if t[i] == null then
set t[i] = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t[i], pl, p, null)
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function GetPlayerUnitEventTrigger takes playerunitevent p returns trigger
return t[GetHandleId(p)]
endfunction
endlibrary
library NewBonus requires optional DamageInterface, optional Evasion, optional CriticalStrike, optional SpellPower, optional LifeSteal, optional SpellVamp, optional CooldownReduction, optional Tenacity
/* ---------------------------------------- NewBonus v2.4 --------------------------------------- */
// Since ObjectMerger is broken and we still have no means to edit
// bonus values (green values) i decided to create a light weight
// Bonus library that works in the same way that the original Bonus Mod
// by Earth Fury did. NewBonus requires patch 1.30+.
// Credits to Earth Fury for the original Bonus idea
// How to Import?
// Importing bonus mod is really simple. Just copy the 9 abilities with the
// prefix "NewBonus" from the Object Editor into your map and match their new raw
// code to the bonus types in the global block below. Then create a trigger called
// NewBonus, convert it to custom text and paste this code there. You done!
/* ---------------------------------------- By Chopinski ---------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* Configuration */
/* ---------------------------------------------------------------------------------------------- */
globals
// If true will use the extended version of the system.
// Make sure you have the DamageInterface and Cooldown Reduction libraries
public constant boolean EXTENDED = true
// This is the maximum recursion limit allowed by the system.
// It's value must be greater than or equal to 0. When equal to 0
// no recursion is allowed. Values too big can cause screen freezes.
private constant integer RECURSION_LIMIT = 8
//The bonus types
constant integer BONUS_DAMAGE = 1
constant integer BONUS_ARMOR = 2
constant integer BONUS_AGILITY = 3
constant integer BONUS_STRENGTH = 4
constant integer BONUS_INTELLIGENCE = 5
constant integer BONUS_HEALTH = 6
constant integer BONUS_MANA = 7
constant integer BONUS_MOVEMENT_SPEED = 8
constant integer BONUS_SIGHT_RANGE = 9
constant integer BONUS_HEALTH_REGEN = 10
constant integer BONUS_MANA_REGEN = 11
constant integer BONUS_ATTACK_SPEED = 12
constant integer BONUS_MAGIC_RESISTANCE = 13
constant integer BONUS_EVASION_CHANCE = 14
constant integer BONUS_CRITICAL_DAMAGE = 15
constant integer BONUS_CRITICAL_CHANCE = 16
constant integer BONUS_LIFE_STEAL = 17
constant integer BONUS_MISS_CHANCE = 18
constant integer BONUS_SPELL_POWER_FLAT = 19
constant integer BONUS_SPELL_POWER_PERCENT = 20
constant integer BONUS_SPELL_VAMP = 21
constant integer BONUS_COOLDOWN_REDUCTION = 22
constant integer BONUS_COOLDOWN_REDUCTION_FLAT = 23
constant integer BONUS_COOLDOWN_OFFSET = 24
constant integer BONUS_TENACITY = 25
constant integer BONUS_TENACITY_FLAT = 26
constant integer BONUS_TENACITY_OFFSET = 27
//The abilities codes for each bonus
//When pasting the abilities over to your map
//their raw code should match the bonus here
private constant integer DAMAGE_ABILITY = 'A004'
private constant integer ARMOR_ABILITY = 'A001'
private constant integer STATS_ABILITY = 'A000'
private constant integer HEALTH_ABILITY = 'A006'
private constant integer MANA_ABILITY = 'A00A'
private constant integer HEALTHREGEN_ABILITY = 'A00D'
private constant integer MANAREGEN_ABILITY = 'A00E'
private constant integer ATTACKSPEED_ABILITY = 'A002'
private constant integer MOVEMENTSPEED_ABILITY = 'A00B'
private constant integer SIGHT_RANGE_ABILITY = 'A00C'
private constant integer MAGIC_RESISTANCE_ABILITY = 'A009'
private constant integer CRITICAL_STRIKE_ABILITY = 'A003'
private constant integer EVASION_ABILITY = 'A005'
private constant integer LIFE_STEAL_ABILITY = 'A008'
//The abilities fields that are modified. For the sake of readability
private constant abilityintegerlevelfield DAMAGE_FIELD = ABILITY_ILF_ATTACK_BONUS
private constant abilityintegerlevelfield ARMOR_FIELD = ABILITY_ILF_DEFENSE_BONUS_IDEF
private constant abilityintegerlevelfield AGILITY_FIELD = ABILITY_ILF_AGILITY_BONUS
private constant abilityintegerlevelfield STRENGTH_FIELD = ABILITY_ILF_STRENGTH_BONUS_ISTR
private constant abilityintegerlevelfield INTELLIGENCE_FIELD = ABILITY_ILF_INTELLIGENCE_BONUS
private constant abilityintegerlevelfield HEALTH_FIELD = ABILITY_ILF_MAX_LIFE_GAINED
private constant abilityintegerlevelfield MANA_FIELD = ABILITY_ILF_MAX_MANA_GAINED
private constant abilityintegerlevelfield MOVEMENTSPEED_FIELD = ABILITY_ILF_MOVEMENT_SPEED_BONUS
private constant abilityintegerlevelfield SIGHT_RANGE_FIELD = ABILITY_ILF_SIGHT_RANGE_BONUS
private constant abilityreallevelfield HEALTHREGEN_FIELD = ABILITY_RLF_AMOUNT_OF_HIT_POINTS_REGENERATED
private constant abilityreallevelfield MANAREGEN_FIELD = ABILITY_RLF_AMOUNT_REGENERATED
private constant abilityreallevelfield ATTACKSPEED_FIELD = ABILITY_RLF_ATTACK_SPEED_INCREASE_ISX1
private constant abilityreallevelfield MAGIC_RESISTANCE_FIELD = ABILITY_RLF_DAMAGE_REDUCTION_ISR2
private constant abilityreallevelfield CRITICAL_CHANCE_FIELD = ABILITY_RLF_CHANCE_TO_CRITICAL_STRIKE
private constant abilityreallevelfield CRITICAL_DAMAGE_FIELD = ABILITY_RLF_DAMAGE_MULTIPLIER_OCR2
private constant abilityreallevelfield EVASION_FIELD = ABILITY_RLF_CHANCE_TO_EVADE_EEV1
private constant abilityreallevelfield LIFE_STEAL_FIELD = ABILITY_RLF_LIFE_STOLEN_PER_ATTACK
endglobals
/* ---------------------------------------------------------------------------------------------- */
/* JASS API */
/* ---------------------------------------------------------------------------------------------- */
function GetUnitBonus takes unit source, integer bonus returns real
return NewBonus.get(source, bonus)
endfunction
function SetUnitBonus takes unit source, integer bonus, real amount returns real
return NewBonus.Set(source, bonus, amount, false)
endfunction
function RemoveUnitBonus takes unit source, integer bonus returns nothing
if bonus == BONUS_CRITICAL_DAMAGE then
call NewBonus.Set(source, bonus, 1, false)
else
call NewBonus.Set(source, bonus, 0, false)
endif
if bonus == BONUS_LIFE_STEAL then
call UnitRemoveAbility(source, LIFE_STEAL_ABILITY)
endif
endfunction
function AddUnitBonus takes unit source, integer bonus, real amount returns real
return NewBonus.add(source, bonus, amount)
endfunction
function RegisterBonusEvent takes code c returns nothing
call NewBonus.register(c, 0)
endfunction
function RegisterBonusTypeEvent takes integer bonus, code c returns nothing
call NewBonus.register(c, bonus)
endfunction
function GetBonusUnit takes nothing returns unit
return NewBonus.unit[NewBonus.key]
endfunction
function GetBonusType takes nothing returns integer
return NewBonus.type[NewBonus.key]
endfunction
function SetBonusType takes integer bonus returns nothing
if bonus >= BONUS_DAMAGE and bonus <= NewBonus.last then
set NewBonus.type[NewBonus.key] = bonus
endif
endfunction
function GetBonusAmount takes nothing returns real
return NewBonus.amount[NewBonus.key]
endfunction
function SetBonusAmount takes real amount returns nothing
set NewBonus.amount[NewBonus.key] = amount
endfunction
/* ---------------------------------------------------------------------------------------------- */
/* System */
/* ---------------------------------------------------------------------------------------------- */
struct NewBonus
private static trigger trigger = CreateTrigger()
readonly static integer key = -1
private static trigger array event
private static integer count = 0
readonly static unit array unit
readonly static integer last
readonly static integer linkType
static integer array type
static real array amount
private static method checkOverflow takes real current, real value returns real
if value > 0 and current > 2147483647 - value then
return 2147483647 - current
elseif value < 0 and current < -2147483648 - value then
return -2147483648 - current
else
return value
endif
endmethod
private static method onEvent takes integer key returns nothing
local integer i = 0
local integer next = -1
local integer prev = -2
set count = count + 1
if amount[key] != 0 and (count - last < RECURSION_LIMIT) then
loop
exitwhen type[key] == next or (i - last > RECURSION_LIMIT)
set next = type[key]
if event[next] != null then
call TriggerEvaluate(event[next])
endif
if type[key] != next then
set i = i + 1
else
if next != prev then
call TriggerEvaluate(trigger)
if type[key] != next then
set i = i + 1
set prev = next
endif
endif
endif
endloop
endif
set count = count - 1
set .key = key
endmethod
private static method setAbilityI takes unit source, integer id, abilityintegerlevelfield field, real value, boolean adding returns real
if GetUnitAbilityLevel(source, id) == 0 then
call UnitAddAbility(source, id)
call UnitMakeAbilityPermanent(source, true, id)
endif
if adding then
if BlzSetAbilityIntegerLevelField(BlzGetUnitAbility(source, id), field, 0, BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, id), field, 0) + R2I(value)) then
call IncUnitAbilityLevel(source, id)
call DecUnitAbilityLevel(source, id)
endif
else
if BlzSetAbilityIntegerLevelField(BlzGetUnitAbility(source, id), field, 0, R2I(value)) then
call IncUnitAbilityLevel(source, id)
call DecUnitAbilityLevel(source, id)
endif
endif
set linkType = type[key]
if key > -1 then
set key = key - 1
endif
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, id), field, 0))
endmethod
private static method setAbilityR takes unit source, integer id, abilityreallevelfield field, real value returns real
if GetUnitAbilityLevel(source, id) == 0 then
call UnitAddAbility(source, id)
call UnitMakeAbilityPermanent(source, true, id)
endif
if BlzSetAbilityRealLevelField(BlzGetUnitAbility(source, id), field, 0, value) then
call IncUnitAbilityLevel(source, id)
call DecUnitAbilityLevel(source, id)
endif
set linkType = type[key]
if key > -1 then
set key = key - 1
endif
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, id), field, 0)
endmethod
static method get takes unit source, integer bonus returns real
if bonus == BONUS_DAMAGE then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, DAMAGE_ABILITY), DAMAGE_FIELD, 0))
elseif bonus == BONUS_ARMOR then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, ARMOR_ABILITY), ARMOR_FIELD, 0))
elseif bonus == BONUS_HEALTH then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, HEALTH_ABILITY), HEALTH_FIELD, 0))
elseif bonus == BONUS_MANA then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, MANA_ABILITY), MANA_FIELD, 0))
elseif bonus == BONUS_AGILITY then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, STATS_ABILITY), AGILITY_FIELD, 0))
elseif bonus == BONUS_STRENGTH then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, STATS_ABILITY), STRENGTH_FIELD, 0))
elseif bonus == BONUS_INTELLIGENCE then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, STATS_ABILITY), INTELLIGENCE_FIELD, 0))
elseif bonus == BONUS_MOVEMENT_SPEED then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, MOVEMENTSPEED_ABILITY), MOVEMENTSPEED_FIELD, 0))
elseif bonus == BONUS_SIGHT_RANGE then
return I2R(BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(source, SIGHT_RANGE_ABILITY), SIGHT_RANGE_FIELD, 0))
elseif bonus == BONUS_HEALTH_REGEN then
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, HEALTHREGEN_ABILITY), HEALTHREGEN_FIELD, 0)
elseif bonus == BONUS_MANA_REGEN then
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, MANAREGEN_ABILITY), MANAREGEN_FIELD, 0)
elseif bonus == BONUS_ATTACK_SPEED then
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, ATTACKSPEED_ABILITY), ATTACKSPEED_FIELD, 0)
elseif bonus == BONUS_MAGIC_RESISTANCE then
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, MAGIC_RESISTANCE_ABILITY), MAGIC_RESISTANCE_FIELD, 0)
elseif bonus >= BONUS_EVASION_CHANCE and bonus <= last then
static if EXTENDED and LIBRARY_DamageInterface and LIBRARY_Evasion and LIBRARY_CriticalStrike and LIBRARY_SpellPower and LIBRARY_LifeSteal and LIBRARY_SpellVamp and LIBRARY_Tenacity then
if bonus == BONUS_EVASION_CHANCE then
return GetUnitEvasionChance(source)
elseif bonus == BONUS_MISS_CHANCE then
return GetUnitMissChance(source)
elseif bonus == BONUS_CRITICAL_CHANCE then
return GetUnitCriticalChance(source)
elseif bonus == BONUS_CRITICAL_DAMAGE then
return GetUnitCriticalMultiplier(source)
elseif bonus == BONUS_SPELL_POWER_FLAT then
return GetUnitSpellPowerFlat(source)
elseif bonus == BONUS_SPELL_POWER_PERCENT then
return GetUnitSpellPowerPercent(source)
elseif bonus == BONUS_LIFE_STEAL then
return GetUnitLifeSteal(source)
elseif bonus == BONUS_SPELL_VAMP then
return GetUnitSpellVamp(source)
elseif bonus == BONUS_COOLDOWN_REDUCTION then
return GetUnitCooldownReduction(source)
elseif bonus == BONUS_COOLDOWN_REDUCTION_FLAT then
return GetUnitCooldownReductionFlat(source)
elseif bonus == BONUS_COOLDOWN_OFFSET then
return GetUnitCooldownOffset(source)
elseif bonus == BONUS_TENACITY then
return GetUnitTenacity(source)
elseif bonus == BONUS_TENACITY_FLAT then
return GetUnitTenacityFlat(source)
elseif bonus == BONUS_TENACITY_OFFSET then
return GetUnitTenacityOffset(source)
endif
else
if bonus == BONUS_CRITICAL_CHANCE then
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, CRITICAL_STRIKE_ABILITY), CRITICAL_CHANCE_FIELD, 0)
elseif bonus == BONUS_CRITICAL_DAMAGE then
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, CRITICAL_STRIKE_ABILITY), CRITICAL_DAMAGE_FIELD, 0)
elseif bonus == BONUS_EVASION_CHANCE then
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, EVASION_ABILITY), EVASION_FIELD, 0)
elseif bonus == BONUS_LIFE_STEAL then
return BlzGetAbilityRealLevelField(BlzGetUnitAbility(source, LIFE_STEAL_ABILITY), LIFE_STEAL_FIELD, 0)
endif
endif
else
call DisplayTimedTextToPlayer(Player(0), 0, 0, 10, "Invalid Bonus Type")
endif
return -1.
endmethod
static method Set takes unit source, integer bonus, real value, boolean adding returns real
local real p
if not adding then
set key = key + 1
set unit[key] = source
set type[key] = bonus
set amount[key] = value
call onEvent(key)
if amount[key] != value then
set value = amount[key]
endif
if type[key] != bonus then
return Set(unit[key], type[key], amount[key], not adding)
endif
else
set unit[key] = source
set type[key] = bonus
set amount[key] = value
endif
if bonus == BONUS_DAMAGE then
return setAbilityI(source, DAMAGE_ABILITY, DAMAGE_FIELD, value, adding)
elseif bonus == BONUS_ARMOR then
return setAbilityI(source, ARMOR_ABILITY, ARMOR_FIELD, value, adding)
elseif bonus == BONUS_HEALTH then
set p = GetUnitLifePercent(source)
if value == 0 and not adding then
call BlzSetUnitMaxHP(source, R2I(BlzGetUnitMaxHP(source) - get(source, bonus)))
else
call BlzSetUnitMaxHP(source, R2I(BlzGetUnitMaxHP(source) + value))
endif
call setAbilityI(source, HEALTH_ABILITY, HEALTH_FIELD, value, adding)
call SetUnitLifePercentBJ(source, p)
return value
elseif bonus == BONUS_MANA then
set p = GetUnitManaPercent(source)
if value == 0 and not adding then
call BlzSetUnitMaxMana(source, R2I(BlzGetUnitMaxMana(source) - get(source, bonus)))
else
call BlzSetUnitMaxMana(source, R2I(BlzGetUnitMaxMana(source) + value))
endif
call setAbilityI(source, MANA_ABILITY, MANA_FIELD, value, adding)
call SetUnitManaPercentBJ(source, p)
return value
elseif bonus == BONUS_AGILITY then
return setAbilityI(source, STATS_ABILITY, AGILITY_FIELD, value, adding)
elseif bonus == BONUS_STRENGTH then
return setAbilityI(source, STATS_ABILITY, STRENGTH_FIELD, value, adding)
elseif bonus == BONUS_INTELLIGENCE then
return setAbilityI(source, STATS_ABILITY, INTELLIGENCE_FIELD, value, adding)
elseif bonus == BONUS_MOVEMENT_SPEED then
return setAbilityI(source, MOVEMENTSPEED_ABILITY, MOVEMENTSPEED_FIELD, value, adding)
elseif bonus == BONUS_SIGHT_RANGE then
if value == 0 and not adding then
call BlzSetUnitRealField(source, UNIT_RF_SIGHT_RADIUS, (BlzGetUnitRealField(source, UNIT_RF_SIGHT_RADIUS) - get(source, bonus)))
else
call BlzSetUnitRealField(source, UNIT_RF_SIGHT_RADIUS, (BlzGetUnitRealField(source, UNIT_RF_SIGHT_RADIUS) + value))
endif
call setAbilityI(source, SIGHT_RANGE_ABILITY, SIGHT_RANGE_FIELD, value, adding)
return value
elseif bonus == BONUS_HEALTH_REGEN then
return setAbilityR(source, HEALTHREGEN_ABILITY, HEALTHREGEN_FIELD, value)
elseif bonus == BONUS_MANA_REGEN then
return setAbilityR(source, MANAREGEN_ABILITY, MANAREGEN_FIELD, value)
elseif bonus == BONUS_ATTACK_SPEED then
return setAbilityR(source, ATTACKSPEED_ABILITY, ATTACKSPEED_FIELD, value)
elseif bonus == BONUS_MAGIC_RESISTANCE then
return setAbilityR(source, MAGIC_RESISTANCE_ABILITY, MAGIC_RESISTANCE_FIELD, value)
elseif bonus >= BONUS_EVASION_CHANCE and bonus <= last then
static if EXTENDED and LIBRARY_DamageInterface and LIBRARY_Evasion and LIBRARY_CriticalStrike and LIBRARY_SpellPower and LIBRARY_LifeSteal and LIBRARY_SpellVamp and LIBRARY_Tenacity then
if bonus == BONUS_EVASION_CHANCE then
call SetUnitEvasionChance(source, value)
elseif bonus == BONUS_MISS_CHANCE then
call SetUnitMissChance(source, value)
elseif bonus == BONUS_CRITICAL_CHANCE then
call SetUnitCriticalChance(source, value)
elseif bonus == BONUS_CRITICAL_DAMAGE then
call SetUnitCriticalMultiplier(source, value)
elseif bonus == BONUS_SPELL_POWER_FLAT then
call SetUnitSpellPowerFlat(source, value)
elseif bonus == BONUS_SPELL_POWER_PERCENT then
call SetUnitSpellPowerPercent(source, value)
elseif bonus == BONUS_LIFE_STEAL then
call SetUnitLifeSteal(source, value)
elseif bonus == BONUS_SPELL_VAMP then
call SetUnitSpellVamp(source, value)
elseif bonus == BONUS_COOLDOWN_REDUCTION then
if adding then
call UnitAddCooldownReduction(source, value)
else
call SetUnitCooldownReduction(source, value)
endif
elseif bonus == BONUS_COOLDOWN_REDUCTION_FLAT then
call SetUnitCooldownReductionFlat(source, value)
elseif bonus == BONUS_COOLDOWN_OFFSET then
call SetUnitCooldownOffset(source, value)
elseif bonus == BONUS_TENACITY then
if adding then
call UnitAddTenacity(source, value)
else
call SetUnitTenacity(source, value)
endif
elseif bonus == BONUS_TENACITY_FLAT then
call SetUnitTenacityFlat(source, value)
elseif bonus == BONUS_TENACITY_OFFSET then
call SetUnitTenacityOffset(source, value)
endif
set linkType = bonus
if key > -1 then
set key = key - 1
endif
return value
else
if bonus == BONUS_CRITICAL_CHANCE then
return setAbilityR(source, CRITICAL_STRIKE_ABILITY, CRITICAL_CHANCE_FIELD, value)
elseif bonus == BONUS_CRITICAL_DAMAGE then
return setAbilityR(source, CRITICAL_STRIKE_ABILITY, CRITICAL_DAMAGE_FIELD, value)
elseif bonus == BONUS_EVASION_CHANCE then
return setAbilityR(source, EVASION_ABILITY, EVASION_FIELD, value)
elseif bonus == BONUS_LIFE_STEAL then
return setAbilityR(source, LIFE_STEAL_ABILITY, LIFE_STEAL_FIELD, value)
endif
endif
else
call DisplayTimedTextToPlayer(Player(0), 0, 0, 10, "Invalid Bonus Type")
endif
return -1.
endmethod
static method add takes unit source, integer bonus, real value returns real
if value != 0 then
set key = key + 1
set unit[key] = source
set type[key] = bonus
set amount[key] = value
if bonus <= BONUS_SIGHT_RANGE then
set amount[key] = checkOverflow(get(source, bonus), R2I(value))
endif
call onEvent(key)
set value = amount[key]
if type[key] <= BONUS_SIGHT_RANGE then
call Set(unit[key], type[key], checkOverflow(get(unit[key], type[key]), R2I(amount[key])), true)
else
static if EXTENDED and LIBRARY_DamageInterface and LIBRARY_Evasion and LIBRARY_CriticalStrike and LIBRARY_SpellPower and LIBRARY_LifeSteal and LIBRARY_SpellVamp and LIBRARY_Tenacity then
if type[key] == BONUS_COOLDOWN_REDUCTION or type[key] == BONUS_TENACITY then
call Set(unit[key], type[key], amount[key], true)
else
call Set(unit[key], type[key], get(unit[key], type[key]) + amount[key], true)
endif
else
call Set(unit[key], type[key], get(unit[key], type[key]) + amount[key], true)
endif
endif
return value
endif
return 0.
endmethod
static method register takes code c, integer bonus returns nothing
if bonus >= BONUS_DAMAGE and bonus <= last then
if event[bonus] == null then
set event[bonus] = CreateTrigger()
endif
call TriggerAddCondition(event[bonus], Filter(c))
else
call TriggerAddCondition(trigger, Filter(c))
endif
endmethod
private static method onInit takes nothing returns nothing
static if EXTENDED and LIBRARY_DamageInterface and LIBRARY_Evasion and LIBRARY_CriticalStrike and LIBRARY_SpellPower and LIBRARY_LifeSteal and LIBRARY_SpellVamp and LIBRARY_Tenacity then
set last = BONUS_TENACITY_OFFSET
else
set last = BONUS_LIFE_STEAL
endif
endmethod
endstruct
endlibrary
library NewBonusUtils requires NewBonus, RegisterPlayerUnitEvent
/* ------------------------------------- NewBonusUtils v2.4 ------------------------------------- */
// Required Library: RegisterPlayerUnitEvent -> www.hiveworkshop.com/threads/snippet-registerplayerunitevent.203338/
// API:
// function AddUnitBonusTimed takes unit u, integer bonus_type, real amount, real duration returns nothing
// -> Add the specified amount for the specified bonus type for unit for a duration
// -> Example: call AddUnitBonusTimed(GetTriggerUnit(), BONUS_ARMOR, 13, 10.5)
// function LinkBonusToBuff takes unit u, integer bonus_type, real amount, integer buffId returns nothing
// -> Links the bonus amount specified to a buff or ability. As long as the unit has the buff or
// -> the ability represented by the parameter buffId the bonus is not removed.
// -> Example: call LinkBonusToBuff(GetTriggerUnit(), BONUS_ARMOR, 10, 'B000')
// function LinkBonusToItem takes unit u, integer bonus_type, real amount, item i returns nothing
// -> Links the bonus amount specified to an item. As long as the unit has that item the bonus is not removed.
// -> Note that it will work for items with the same id, because it takes as parameter the item object.
// -> Example: call LinkBonusToItem(GetManipulatingUnit(), BONUS_ARMOR, 10, GetManipulatedItem())
// function UnitCopyBonuses takes unit source, unit target returns nothing
// -> Copy the source unit bonuses using the Add functionality to the target unit
// -> Example: call UnitCopyBonuses(GetTriggerUnit(), GetSummonedUnit())
// function UnitMirrorBonuses takes unit source, unit target returns nothing
// -> Copy the source unit bonuses using the Set functionality to the target unit
// -> Example: call UnitMirrorBonuses(GetTriggerUnit(), GetSummonedUnit())
/* ---------------------------------------- By Chopinski ---------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* JASS API */
/* ---------------------------------------------------------------------------------------------- */
function AddUnitBonusTimed takes unit source, integer bonus, real amount, real duration returns nothing
call NewBonusUtils.linkTimed(source, bonus, amount, duration, true)
endfunction
function LinkBonusToBuff takes unit source, integer bonus, real amount, integer id returns nothing
call NewBonusUtils.linkBuff(source, bonus, amount, id, false)
endfunction
function LinkBonusToItem takes unit source, integer bonus, real amount, item i returns nothing
call NewBonusUtils.linkItem(source, bonus, amount, i)
endfunction
function UnitCopyBonuses takes unit source, unit target returns nothing
call NewBonusUtils.copy(source, target)
endfunction
function UnitMirrorBonuses takes unit source, unit target returns nothing
call NewBonusUtils.mirror(source, target)
endfunction
/* ---------------------------------------------------------------------------------------------- */
/* System */
/* ---------------------------------------------------------------------------------------------- */
struct NewBonusUtils extends NewBonus
static constant real period = 0.03125000
static timer timer = CreateTimer()
static integer index = -1
static thistype array array
static integer k = -1
static thistype array items
unit source
item item
real duration
integer bonus_t
integer buff
real value
boolean link
method remove takes integer i, boolean isItem returns integer
static if NewBonus_EXTENDED and LIBRARY_DamageInterface and LIBRARY_Evasion and LIBRARY_CriticalStrike and LIBRARY_SpellPower and LIBRARY_LifeSteal and LIBRARY_SpellVamp and LIBRARY_Tenacity then
if bonus_t == BONUS_COOLDOWN_REDUCTION then
call UnitRemoveCooldownReduction(source, value)
elseif bonus_t == BONUS_TENACITY then
call UnitRemoveTenacity(source, value)
else
call AddUnitBonus(source, bonus_t, -value)
endif
else
call AddUnitBonus(source, bonus_t, -value)
endif
if isItem then
set items[i] = items[k]
set k = k - 1
else
set array[i] = array[index]
set index = index - 1
if index == -1 then
call PauseTimer(timer)
endif
endif
set source = null
set item = null
call deallocate()
return i - 1
endmethod
static method onDrop takes nothing returns nothing
local item itm = GetManipulatedItem()
local integer i = 0
local thistype this
loop
exitwhen i > k
set this = items[i]
if item == itm then
set i = remove(i, true)
endif
set i = i + 1
endloop
endmethod
static method onPeriod takes nothing returns nothing
local integer i = 0
local thistype this
loop
exitwhen i > index
set this = array[i]
if link then
if duration <= 0 then
set i = remove(i, false)
endif
set duration = duration - period
else
if GetUnitAbilityLevel(source, buff) == 0 then
set i = remove(i, false)
endif
endif
set i = i + 1
endloop
endmethod
static method linkTimed takes unit source, integer bonus, real amount, real duration, boolean link returns nothing
local thistype this = thistype.allocate()
set this.source = source
set this.duration = duration
set this.link = link
set this.value = AddUnitBonus(source, bonus, amount)
set this.bonus_t = linkType
set index = index + 1
set array[index] = this
if index == 0 then
call TimerStart(timer, period, true, function thistype.onPeriod)
endif
endmethod
static method linkBuff takes unit source, integer bonus, real amount, integer id, boolean link returns nothing
local thistype this = thistype.allocate()
set this.source = source
set this.buff = id
set this.link = link
set this.value = AddUnitBonus(source, bonus, amount)
set this.bonus_t = linkType
set index = index + 1
set array[index] = this
if index == 0 then
call TimerStart(timer, period, true, function thistype.onPeriod)
endif
endmethod
static method linkItem takes unit source, integer bonus, real amount, item i returns nothing
local thistype this = thistype.allocate()
set this.source = source
set this.item = i
set this.value = AddUnitBonus(source, bonus, amount)
set this.bonus_t = linkType
set k = k + 1
set items[k] = this
endmethod
static method copy takes unit source, unit target returns nothing
local integer i = 1
loop
exitwhen i > last
if GetUnitBonus(source, i) != 0 then
call AddUnitBonus(target, i, GetUnitBonus(source, i))
endif
set i = i + 1
endloop
endmethod
static method mirror takes unit source, unit target returns nothing
local integer i = 1
loop
exitwhen i > last
call SetUnitBonus(target, i, GetUnitBonus(source, i))
set i = i + 1
endloop
endmethod
static method onInit takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DROP_ITEM, function thistype.onDrop)
endmethod
endstruct
endlibrary
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
//: CustomAura
//: by Anachron
//:
//: This system is thought to provide a basic aura system that can be used
//: to create auras with buffs and unit stat modifiers.
//:
//: What this is:
//: This is a very fast and flexible way to create an AOE aura.
//:
//: Functionality:
//: - Use buffs
//: - Use bonuses
//: - Highly customizeable ([Don't] use whatever you want)
//: - Highly flexible (You are allowed to change values at any time)
//: - Fast
//: - Easy understandable (Examples to bring the system closer to you)
//: - Well written (Code is non-redundant, cathegorized)
//:
//: Credits:
//: Rising_Dusk for GroupUtils [http://www.wc3c.net/showthread.php?t=104464]
//:
//: Thanks to:
//: Axarion for the idea.
//:
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
library CustomAura requires GroupUtils, Table
globals
private constant real PERIOD = 0.0375
endglobals
private interface eventHandler
method onLoop takes nothing returns nothing defaults nothing
method onRegister takes unit theUnit returns nothing defaults nothing
method onUnregister takes unit theUnit returns nothing defaults nothing
method onStart takes nothing returns nothing defaults nothing
method onEnd takes nothing returns nothing defaults nothing
method getRadius takes nothing returns real defaults 0.
method onCheck takes unit theUnit returns nothing defaults nothing
method unitFilter takes unit theUnit returns boolean defaults true
method onLevelup takes integer theLevel returns nothing defaults nothing
method activeCond takes nothing returns boolean defaults true
method addBuff takes unit theUnit returns nothing defaults nothing
method removeBuff takes unit theUnit returns nothing defaults nothing
method checkBuff takes unit theUnit returns nothing defaults nothing
method addBonus takes unit theUnit returns nothing defaults nothing
method removeBonus takes unit theUnit returns nothing defaults nothing
endinterface
struct CustomAura extends eventHandler
public unit theUnit = null
private group affect = null
private group last = null
public boolean isAlive = true
public boolean isPaused = false
private boolean hasStarted = false
public integer spellId = 0
//: == ---------------------------- ----------------------------
//: # Indexing & Structstuff
//: == ---------------------------- ----------------------------
private integer index = 0
private static thistype curInstance = 0
private static timer t = CreateTimer()
private static integer a = 0
private static thistype array i
implement CAIndex
public static method create takes unit theUnit returns thistype
local thistype this = thistype.allocate()
set .affect = NewGroup()
set .last = NewGroup()
set .theUnit = theUnit
set .index = thistype.a
set thistype.i[.index] = this
set thistype.a = thistype.a +1
if thistype.a == 1 then
call TimerStart(thistype.t, PERIOD, true, function thistype.run)
endif
return this
endmethod
public stub method aliveCond takes nothing returns boolean
return GetUnitAbilityLevel(.theUnit, .spellId) > 0
endmethod
public method isUnitAffected takes unit theUnit returns boolean
return IsUnitInGroup(theUnit, .affect)
endmethod
public method affectUnit takes unit theUnit returns nothing
call GroupAddUnit(.affect, theUnit)
if not IsUnitInGroup(theUnit, .last) then
call .addBuff(theUnit)
call .addBonus(theUnit)
call .onRegister(theUnit)
else
call .checkBuff(theUnit)
endif
endmethod
public method unaffectUnit takes unit theUnit returns nothing
if not IsUnitInGroup(theUnit, .affect) then
call GroupRemoveUnit(.last, theUnit)
call .removeBuff(theUnit)
call .removeBonus(theUnit)
call .onUnregister(theUnit)
endif
endmethod
private static method unaffectAllEnum takes nothing returns nothing
call thistype.curInstance.unaffectUnit(GetEnumUnit())
endmethod
public method unaffectAll takes nothing returns nothing
set thistype.curInstance = this
call GroupClear(.affect)
call ForGroup(.last, function thistype.unaffectAllEnum)
endmethod
private static method tryRegister takes nothing returns boolean
local thistype this = thistype.curInstance
local unit u = GetFilterUnit()
if .unitFilter(u) then
call .affectUnit(u)
endif
set u = null
return false
endmethod
private static method tryUnregister takes nothing returns nothing
call thistype.curInstance.unaffectUnit(GetEnumUnit())
endmethod
private method move takes nothing returns nothing
call .onLoop()
set .isAlive = .activeCond()
if .isPaused or not .isAlive then
return
endif
if not .hasStarted then
set .hasStarted = true
call .onStart()
endif
//: Replaces call GroupAddGroup(.affect, .last)
set bj_groupAddGroupDest = .last
call ForGroup(.affect, function GroupAddGroupEnum)
call GroupClear(.affect)
call GroupEnumUnitsInRange(.affect, GetUnitX(.theUnit), GetUnitY(.theUnit), .getRadius(), Condition(function thistype.tryRegister))
call ForGroup(.last, function thistype.tryUnregister)
endmethod
public static method run takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= thistype.a
if thistype.i[i].isAlive and thistype.i[i] != 0 then
set thistype.curInstance = thistype.i[i]
call thistype.i[i].move()
else
if thistype.i[i] != 0 then
call thistype.i[i].destroy()
endif
set thistype.a = thistype.a -1
set thistype.i[i] = thistype.i[thistype.a]
set thistype.i[i].index = i
set i = i -1
endif
set i = i +1
endloop
if thistype.a == 0 then
call PauseTimer(thistype.t)
endif
endmethod
private method onDestroy takes nothing returns nothing
call .unaffectAll()
call ReleaseGroup(.affect)
call ReleaseGroup(.last)
call .clear()
call .onEnd()
endmethod
endstruct
endlibrary
library AuraTemplate requires CustomAura
struct AuraTemplate extends CustomAura
implement CABonus
implement CABuff
endstruct
endlibrary
//! textmacro AuraTemplateMethods
private static method new takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer i = GetHandleId(u)
local integer s = GetLearnedSkill()
local integer l = GetUnitAbilityLevel(u, s)
local thistype this = thistype.load(i)
//: Check whether the aura spell ID is valid
if s != SPELL_ID then
set u = null
return false
endif
if this == 0 then
set this = thistype.create(u)
set this.spellId = SPELL_ID
set .ID = i
call .save()
else
//: If we can load the data unaffect all so they get the
//: new bonuses
call .unaffectAll()
endif
//: Update the buff and bonus data
//: PLEASE DO NOT PUT THIS BEFORE .unaffectAll() !
if BUFF_SPELL != 0 and BUFF_ID != 0 and BUFF_ORDER != null then
call .setBuff(BUFF_SPELL, l, BUFF_ID, BUFF_ORDER, true)
endif
call .onLevelup(l)
set u = null
return false
endmethod
private static method onInit takes nothing returns nothing
local integer i = 0
local trigger t = null
//call BJDebugMsg(GetObjectName(SPELL_ID))
if SPELL_ID == 0 then
return
endif
set t = CreateTrigger()
call TriggerAddCondition(t, Condition(function thistype.new))
loop
exitwhen i >= bj_MAX_PLAYER_SLOTS
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_HERO_SKILL, null)
set i = i +1
endloop
endmethod
//! endtextmacro
library CABuff initializer init requires CustomDummy
globals
private unit CASTER = null
endglobals
private function init takes nothing returns nothing
set CASTER = CreateDummy(Player(PLAYER_NEUTRAL_PASSIVE), 0., 0.)
call UnitAddAbility(CASTER, 'Aloc')
endfunction
module CABuff
private integer theSpell = 0
private integer theLevel = 0
private integer theBuff = 0
private string theOrder = null
private boolean buffBased = true
public method setBuff takes integer theSpell, integer theLevel, integer theBuff, string theOrder, boolean buffBased returns nothing
set .theSpell = theSpell
set .theLevel = theLevel
set .theBuff = theBuff
set .theOrder = theOrder
set .buffBased = buffBased
endmethod
public method hasUnitBuff takes unit theUnit returns boolean
return GetUnitAbilityLevel(theUnit, .theBuff) != 0
endmethod
method addBuff takes unit theUnit returns nothing
call SetUnitX(CASTER, GetUnitX(theUnit))
call SetUnitY(CASTER, GetUnitY(theUnit))
call SetUnitOwner(CASTER, GetOwningPlayer(.theUnit), false)
call UnitAddAbility(CASTER, .theSpell)
call SetUnitAbilityLevel(CASTER, .theSpell, .theLevel)
call IssueTargetOrder(CASTER, .theOrder, theUnit)
call UnitRemoveAbility(CASTER, .theSpell)
endmethod
method removeBuff takes unit theUnit returns nothing
call UnitRemoveAbility(theUnit, .theBuff)
endmethod
method checkBuff takes unit theUnit returns nothing
if not .hasUnitBuff(theUnit) then
call .addBuff(theUnit)
endif
endmethod
endmodule
endlibrary
library CABonus
module CABonus
public integer hp = 0
public integer mp = 0
public integer amr = 0
public integer dmg = 0
public integer as = 0
public integer mr = 0
public integer lf = 0
public integer str = 0
public integer agi = 0
public integer int = 0
public integer sr = 0
method addBonus takes unit theUnit returns nothing
if .hp != 0 then
call AddUnitBonus(theUnit, BONUS_HEALTH, .hp)
endif
if .mp != 0 then
call AddUnitBonus(theUnit, BONUS_MANA, .mp)
endif
if .amr != 0 then
call AddUnitBonus(theUnit, BONUS_ARMOR, .amr)
endif
if .dmg != 0 then
call AddUnitBonus(theUnit, BONUS_DAMAGE, .dmg)
endif
if .as != 0 then
call AddUnitBonus(theUnit, BONUS_ATTACK_SPEED, .as)
endif
if .mr != 0 then
call AddUnitBonus(theUnit, BONUS_MANA_REGEN, .mr)
endif
if .lf != 0 then
call AddUnitBonus(theUnit, BONUS_HEALTH_REGEN, .lf)
endif
if .str != 0 then
call AddUnitBonus(theUnit, BONUS_STRENGTH, .str)
endif
if .agi != 0 then
call AddUnitBonus(theUnit, BONUS_AGILITY, .agi)
endif
if .int != 0 then
call AddUnitBonus(theUnit, BONUS_INTELLIGENCE, .int)
endif
if .sr!= 0 then
call AddUnitBonus(theUnit, BONUS_SIGHT_RANGE, .sr)
endif
endmethod
method removeBonus takes unit theUnit returns nothing
if .hp != 0 then
call AddUnitBonus(theUnit, BONUS_HEALTH, -.hp)
endif
if .mp != 0 then
call AddUnitBonus(theUnit, BONUS_MANA, -.mp)
endif
if .amr != 0 then
call AddUnitBonus(theUnit, BONUS_ARMOR, -.amr)
endif
if .dmg != 0 then
call AddUnitBonus(theUnit, BONUS_DAMAGE, -.dmg)
endif
if .as != 0 then
call AddUnitBonus(theUnit, BONUS_ATTACK_SPEED, -.as)
endif
if .mr != 0 then
call AddUnitBonus(theUnit, BONUS_MANA_REGEN, -.mr)
endif
if .lf != 0 then
call AddUnitBonus(theUnit, BONUS_HEALTH_REGEN, -.lf)
endif
if .str != 0 then
call AddUnitBonus(theUnit, BONUS_STRENGTH, -.str)
endif
if .agi != 0 then
call AddUnitBonus(theUnit, BONUS_AGILITY, -.agi)
endif
if .int != 0 then
call AddUnitBonus(theUnit, BONUS_INTELLIGENCE, -.int)
endif
if .sr!= 0 then
call AddUnitBonus(theUnit, BONUS_SIGHT_RANGE, -.sr)
endif
endmethod
endmodule
endlibrary
/* ----------------------------------- *//*
Version: 0.1
Author: Anachron
Date: 13th Dec 2009
Release information:
Do not use this library without
copyright information.
Copyright 2009
Requirements:
* Table
What this module does:
Adds the ability to save/load/remove
object instances.
*/
/* ----------------------------------- */
module CAIndex
public static Table INSTANCES = 0
public integer ID = 0
private static method onInit takes nothing returns nothing
set thistype.INSTANCES = Table.create()
endmethod
public method save takes nothing returns nothing
set thistype.INSTANCES[.ID] = integer(this)
endmethod
public method remove takes nothing returns nothing
call thistype.INSTANCES.flush(.ID)
call .destroy()
endmethod
public method clear takes nothing returns nothing
call thistype.INSTANCES.flush(.ID)
endmethod
public static method load takes integer id returns thistype
return thistype(thistype.INSTANCES[id])
endmethod
endmodule
library HolyDevotion requires AuraTemplate
globals
private constant integer BUFF_ID = 'buf1'
private constant integer BUFF_SPELL = 'spl1'
private constant string BUFF_ORDER = "slow"
private constant integer SPELL_ID = 'hldv'
endglobals
private struct HolyDevotionAura extends AuraTemplate
//! runtextmacro AuraTemplateMethods()
method onLevelup takes integer theLevel returns nothing
set .dmg = - theLevel * 2
endmethod
method getRadius takes nothing returns real
return 500.
endmethod
method unitFilter takes unit theUnit returns boolean
//: Do some checks whether the unit is a valid target
return IsUnitEnemy(theUnit, GetOwningPlayer(.theUnit)) and GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.40
endmethod
endstruct
endlibrary
library DevotionAura requires AuraTemplate
globals
private constant integer BUFF_ID = 'BHad'
private constant integer BUFF_SPELL = 'spl2'
private constant string BUFF_ORDER = "slow"
private constant integer SPELL_ID = 'dvar'
endglobals
private struct DevotionAura extends AuraTemplate
//! runtextmacro AuraTemplateMethods()
method onLevelup takes integer newLevel returns nothing
set .amr = - newLevel * 2
endmethod
method getRadius takes nothing returns real
return 500.
endmethod
method unitFilter takes unit theUnit returns boolean
//: Do some checks whether the unit is a valid target
return IsUnitEnemy(theUnit, GetOwningPlayer(.theUnit)) and GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.40
endmethod
endstruct
endlibrary
library MagicImmunityAura initializer init requires CustomAura
globals
private constant integer SPELL_BOOK = 'MIbk'
endglobals
private function init takes nothing returns nothing
local integer i = 0
loop
exitwhen i > bj_MAX_PLAYERS
call SetPlayerAbilityAvailable(Player(i), SPELL_BOOK, false)
set i = i + 1
endloop
endfunction
struct MagicImmunityAura extends CustomAura
method activeCond takes nothing returns boolean
return true
endmethod
method onRegister takes unit theUnit returns nothing
call UnitAddAbility(theUnit, SPELL_BOOK)
endmethod
method onUnregister takes unit theUnit returns nothing
call UnitRemoveAbility(theUnit, SPELL_BOOK)
endmethod
method getRadius takes nothing returns real
return 500.
endmethod
method unitFilter takes unit theUnit returns boolean
//: Only for alive, non-reincarnating units
return GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.40
endmethod
endstruct
endlibrary
scope TestMagicImmunityAura initializer init// requires MagicImmunity
private function init takes nothing returns nothing
local unit testDummy = CreateUnit(Player(0), 'hfoo', -450., -600., 270.)
call MagicImmunityAura.create(testDummy)
call AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\BattleRoar\\RoarTarget.mdl", testDummy, "overhead")
endfunction
endscope
/*
library HolyDevotion requires CustomAura
globals
private constant integer BUFF_ID = 'buf1'
private constant integer BUFF_SPELL = 'spl1'
endglobals
private struct HolyDevotionAura extends CustomAura
implement CABuff
implement CABonus
implement TableMacros
private static method new takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer i = GetHandleId(u)
local integer s = GetLearnedSkill()
local integer l = GetUnitAbilityLevel(u, s)
local thistype this = thistype.load(i)
//: Check whether the aura spell ID is valid
if s != 'hldv' then
set u = null
return false
endif
if this == 0 then
set this = thistype.create(u)
set .ID = i
call .save()
else
//: If we can load the data unaffect all so they get the
//: new bonuses
call .unaffectAll()
endif
//: Update the buff and bonus data
//: PLEASE DO NOT PUT THIS BEFORE .unaffectAll() !
call .setBuff(BUFF_SPELL, l, BUFF_ID, true)
set .dmg = - l * 2
set u = null
return false
endmethod
method getRadius takes nothing returns real
return 500.
endmethod
method unitFilter takes unit theUnit returns boolean
//: Do some checks whether the unit is a valid target
return IsUnitEnemy(theUnit, GetOwningPlayer(.theUnit)) and GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.40
endmethod
private static method onInit takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
call TriggerAddCondition(t, Condition(function thistype.new))
loop
exitwhen i >= bj_MAX_PLAYER_SLOTS
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_HERO_SKILL, null)
set i = i +1
endloop
endmethod
endstruct
endlibrary
*/
/*
library DevotionAura requires CustomAura
globals
private constant integer BUFF_ID = 'BHad'
private constant integer BUFF_SPELL = 'spl2'
endglobals
private struct DevotionAura extends CustomAura
implement CABuff
implement CABonus
implement TableMacros
private static method new takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer i = GetHandleId(u)
local integer s = GetLearnedSkill()
local integer l = GetUnitAbilityLevel(u, s)
local thistype this = thistype.load(i)
//: Check whether the aura spell ID is valid
if s != 'dvar' then
set u = null
return false
endif
if this == 0 then
set this = thistype.create(u)
set .ID = i
call .save()
else
//: If we can load the data unaffect all so they get the
//: new bonuses
call .unaffectAll()
endif
//: Update the buff and bonus data
//: PLEASE DO NOT PUT THIS BEFORE .unaffectAll() !
call .setBuff(BUFF_SPELL, l, BUFF_ID, true)
set .amr = - l * 2
set u = null
return false
endmethod
method getRadius takes nothing returns real
return 500.
endmethod
method unitFilter takes unit theUnit returns boolean
//: Do some checks whether the unit is a valid target
return IsUnitEnemy(theUnit, GetOwningPlayer(.theUnit)) and GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.40
endmethod
private static method onInit takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
call TriggerAddCondition(t, Condition(function thistype.new))
loop
exitwhen i >= bj_MAX_PLAYER_SLOTS
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_HERO_SKILL, null)
set i = i +1
endloop
endmethod
endstruct
endlibrary
*/