library HeroImage /* v2.0.0.0
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* HeroImage it's a simple library (very useful for AoS maps) which can
* be used to show the stats (life and mana) of our allies heroes.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* struct UnitIndex
*
* static method create takes unit which returns thistype
* - Creates the copy for "which"
*
* method destroy takes nothing returns nothing
* - Destroys the copy
*
* static method isOriginal takes unit which returns boolean
* - If "which" is an "original" unit, returns true
*
* static method isCopy takes unit which returns boolean
* - If "which" is a copy from a unit, returns true
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Thanks to
*
* - Jesus4Lyf from thehelper.net
* - muZk from who knows where <.<
* - Magtheridon96 from hiveworkshop.com
* - rulerofiron99 from hiveworkshop.com
* - -Kobas- from hiveworkshop.com
* - ck5524209 from hiveworkshop.com
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
globals
// Lower value = higher quality but more lag
private constant real TIMEOUT = 1.
endglobals
globals
private real WORLD_BOUNDS_MAX_X = 0.
private real WORLD_BOUNDS_MAX_Y = 0.
private constant hashtable HASHTABLE = InitHashtable()
endglobals
struct HeroImage
private thistype prev
private thistype next
readonly unit original
readonly unit array copies[12]
static method isOriginal takes unit which returns boolean
return HaveSavedInteger(HASHTABLE, GetHandleId(which), 0)
endmethod
static method isCopy takes unit which returns boolean
return HaveSavedInteger(HASHTABLE, GetHandleId(which), 1)
endmethod
method destroy takes nothing returns nothing
local integer i = 0
call RemoveSavedHandle(HASHTABLE, GetHandleId(this.original), 0)
set this.original = null
loop
set i = i + 1
exitwhen this.copies[i] == null
call RemoveSavedHandle(HASHTABLE, GetHandleId(this.copies[i]), 1)
call RemoveUnit(this.copies[i])
set this.copies[i] = null
endloop
set this.prev.next = this.next
set this.next.prev = this.prev
call this.deallocate()
endmethod
private static method getInstanceFromOriginal takes unit original returns thistype
return LoadInteger(HASHTABLE, GetHandleId(original), 0)
endmethod
private static method getInstanceFromCopy takes unit copy returns thistype
return LoadInteger(HASHTABLE, GetHandleId(copy), 1)
endmethod
private static method periodic takes nothing returns nothing
local thistype this = thistype(0).next
local real originalHp
local real originalMp
local integer originalXp
local unit copy
local integer n = 0
loop
exitwhen this == 0
if (this.original == null) then
call this.destroy()
else
set originalHp = GetWidgetLife(this.original)
set originalMp = GetUnitState(this.original, UNIT_STATE_MANA)
set originalXp = GetHeroXP(this.original)
set n = 0
loop
set n = n + 1
exitwhen this.copies[n] == null
set copy = this.copies[n]
// HP
if (originalHp <= 0.405) then
call SetWidgetLife(copy, 1)
else
call SetWidgetLife(copy, originalHp)
endif
// MP
call SetUnitState(copy, UNIT_STATE_MANA, originalMp)
// Level
call SetHeroXP(copy, originalXp, false)
endloop
endif
set this = this.next
endloop
set copy = null
endmethod
private static method onOrder takes nothing returns boolean
local thistype this = thistype.getInstanceFromCopy(GetOrderTargetUnit())
if ( this == 0 ) then
return false
endif
call IssueTargetOrderById(GetTriggerUnit(), GetIssuedOrderId(), this.original)
return false
endmethod
private static method onSelection takes nothing returns boolean
local thistype this = thistype.getInstanceFromCopy(GetTriggerUnit())
if ( this == 0 ) then
return false
endif
if ( GetLocalPlayer() == GetTriggerPlayer() ) then
call ClearSelection()
call SelectUnit(this.original, true)
call SetCameraPosition(GetUnitX(this.original), GetUnitY(this.original))
endif
return false
endmethod
private static method onLearnSpell takes nothing returns boolean
local thistype this = thistype.getInstanceFromOriginal(GetLearningUnit())
local integer spellId = 0
local integer spellLevel = 0
local unit copy = null
local integer n = 0
if ( this == 0 ) then
return false
endif
set spellId = GetLearnedSkill()
set spellLevel = GetLearnedSkillLevel()
loop
set n = n + 1
exitwhen this.copies[n] == null
set copy = this.copies[n]
if (GetUnitAbilityLevel(copy, spellId) != 0) then
call SetUnitAbilityLevel(copy, spellId, spellLevel)
else
call UnitAddAbility(copy, spellId)
endif
call UnitModifySkillPoints(copy, -1)
endloop
set copy = null
return false
endmethod
private static method onDie takes nothing returns boolean
if ( thistype.isCopy(GetTriggerUnit()) == false ) then
return false
endif
call ReviveHero(GetTriggerUnit(), WORLD_BOUNDS_MAX_X, WORLD_BOUNDS_MAX_Y, false)
return false
endmethod
private static method onAcquiresItem takes nothing returns boolean
local thistype this = thistype.getInstanceFromOriginal(GetTriggerUnit())
local item manipulatedItem = null
local integer manipulatedItemTypeId = 0
local integer manipulatedItemCharges = 0
local integer i = 0
if ( this == 0 ) then
return false
endif
set manipulatedItem = GetManipulatedItem()
set manipulatedItemTypeId = GetItemTypeId(manipulatedItem)
set manipulatedItemCharges = GetItemCharges(manipulatedItem)
loop
set i = i + 1
exitwhen this.copies[i] == null
call SetItemCharges(UnitAddItemById(this.copies[i], manipulatedItemTypeId), manipulatedItemCharges)
endloop
set manipulatedItem = null
return false
endmethod
private static method onLosesItem takes nothing returns boolean
local thistype this = thistype.getInstanceFromOriginal(GetTriggerUnit())
local item manipulatedItem = null
local integer manipulatedItemTypeId = 0
local integer manipulatedItemCharges = 0
local item tempItem = null
local integer i = 0
local integer n = 0
if ( this == 0 ) then
return false
endif
set manipulatedItem = GetManipulatedItem()
set manipulatedItemTypeId = GetItemTypeId(manipulatedItem)
set manipulatedItemCharges = GetItemCharges(manipulatedItem)
loop
set i = i + 1
exitwhen this.copies[i] == null
set n = 0
loop
set tempItem = UnitItemInSlot(this.copies[i], n)
if ( GetItemTypeId(tempItem) == manipulatedItemTypeId and GetItemCharges(tempItem) == manipulatedItemCharges ) then
call RemoveItem(tempItem)
exitwhen true
endif
set n = n + 1
exitwhen n >= bj_MAX_INVENTORY
endloop
endloop
set manipulatedItem = null
set tempItem = null
return false
endmethod
static method create takes unit which returns thistype
local thistype this = 0
local integer whichId = 0
local player playerOwner = null
local player enumPlayer = null
local unit copy = null
local integer unitTypeId = 0
local integer index = 0
local integer n = 0
if ( IsUnitType(which, UNIT_TYPE_HERO) == false ) then
debug call BJDebugMsg("HeroImage_HeroImage.create() -> Only heroes unit can be copied")
return 0
endif
if ( thistype.isOriginal(which) ) then
debug call BJDebugMsg("HeroImage_HeroImage.create() -> " + GetUnitName(which) + " has already a copy")
return 0
endif
if ( thistype.isCopy(which) ) then
debug call BJDebugMsg("HeroImage_HeroImage.create() -> Copy units can't have copies")
return 0
endif
set this = thistype.allocate()
set whichId = GetHandleId(which)
// thanks Jesus4Lyf =3
set thistype(0).next.prev = this
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
set playerOwner = GetOwningPlayer(which)
set unitTypeId = GetUnitTypeId(which)
set this.original = which
call SaveInteger(HASHTABLE, whichId, 0, this)
loop
set enumPlayer = Player(index)
if ( IsPlayerAlly(enumPlayer, playerOwner) and enumPlayer != playerOwner ) then
set copy = CreateUnit(enumPlayer, unitTypeId, WORLD_BOUNDS_MAX_X, WORLD_BOUNDS_MAX_Y, 0)
call SaveInteger(HASHTABLE, GetHandleId(copy), 1, this)
set n = n + 1
set this.copies[n] = copy
endif
set index = index + 1
exitwhen index == bj_MAX_PLAYERS
endloop
set enumPlayer = null
set playerOwner = null
set copy = null
return this
endmethod
private static method onInit takes nothing returns nothing
local trigger orderTrigger = CreateTrigger()
local trigger selectionTrigger = CreateTrigger()
local trigger learnSpellTrigger = CreateTrigger()
local trigger dieTrigger = CreateTrigger()
local trigger acquiresItemTrigger = CreateTrigger()
local trigger losesItemTrigger = CreateTrigger()
local boolexpr onOrderCondition = Condition(function thistype.onOrder)
local boolexpr onSelectionCondition = Condition(function thistype.onSelection)
local boolexpr onLearnSpellCondition = Condition(function thistype.onLearnSpell)
local boolexpr onDieCondition = Condition(function thistype.onDie)
local boolexpr onAcquiresItemCondition = Condition(function thistype.onAcquiresItem)
local boolexpr onLosesItemCondition = Condition(function thistype.onLosesItem)
local rect worldBounds = GetWorldBounds()
local player enumPlayer = null
local integer index = 0
set WORLD_BOUNDS_MAX_X = GetRectMaxX(worldBounds)
set WORLD_BOUNDS_MAX_Y = GetRectMaxY(worldBounds)
call RemoveRect(worldBounds)
set worldBounds = null
loop
set enumPlayer = Player(index)
call TriggerRegisterPlayerUnitEvent(orderTrigger, enumPlayer, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
call TriggerAddCondition(orderTrigger, onOrderCondition)
call TriggerRegisterPlayerUnitEvent(selectionTrigger, enumPlayer, EVENT_PLAYER_UNIT_SELECTED, null)
call TriggerAddCondition(selectionTrigger, onSelectionCondition)
call TriggerRegisterPlayerUnitEvent(learnSpellTrigger, enumPlayer, EVENT_PLAYER_HERO_SKILL, null)
call TriggerAddCondition(learnSpellTrigger, onLearnSpellCondition)
call TriggerRegisterPlayerUnitEvent(dieTrigger, enumPlayer, EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddCondition(dieTrigger, onDieCondition)
call TriggerRegisterPlayerUnitEvent(acquiresItemTrigger, enumPlayer, EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
call TriggerAddCondition(acquiresItemTrigger, onAcquiresItemCondition)
call TriggerRegisterPlayerUnitEvent(losesItemTrigger, enumPlayer, EVENT_PLAYER_UNIT_DROP_ITEM, null)
call TriggerAddCondition(losesItemTrigger, onLosesItemCondition)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TimerStart(CreateTimer(), TIMEOUT, true, function thistype.periodic)
set orderTrigger = null
set selectionTrigger = null
set learnSpellTrigger = null
set dieTrigger = null
set acquiresItemTrigger = null
set losesItemTrigger = null
set onOrderCondition = null
set onSelectionCondition = null
set onLearnSpellCondition = null
set onDieCondition = null
set onAcquiresItemCondition = null
set onLosesItemCondition = null
set enumPlayer = null
endmethod
endstruct
endlibrary