- Joined
- Jan 30, 2013
- Messages
- 12,758
Interesting. How about spam the section w/ unit merging everyone? 
//Unit Fusion System V8a
//by Tasyen
//======================================
//API
//======================================
// function UnitDefusion takes unit u, boolean killed, integer indexFusion returns nothing
// tries to defuse an unit u, killed, or Defusionen Index
// indexFusion is faster, but most times you won't know the DefusionIndex
// If you do not know the defusion index call it with -1
// function UnitFusionStartFadeIn takes unit u, real dur, real hiddenStateAfter, string sfx, boolean immunDuringFade returns nothing
// pauses an unit and makes it transparent both will be lost over time.
// the pausing will be reapplied every timeout of "UnitFusionTimerSpeed"
// - u the unit
// - dur how long the process will take in seconds.
// - hiddenStateAfter this much % will the unit stay transparent after finishing the process (expects a number from 0 to 100)
// - sfx the modell which will displayed during the fadein
// - immunDuringFade if true the unit becomes invulnurable during fadein.
// - This will throw an FadeInFinish-Event with Fusion_Event_SpellData = -1
// - To Manipulate this used Fusion_Object use udg_Fusion_Current_CreatedObject right after calling it.
// function UnitFusionTimerStart takes nothing returns nothing
// Activaded automatacly normally.
// will start the System-timer, withthat the fusion behaviour overall.
// use it if you stopped the timer manually.
// "udg_Fusion_System_TimerDisabled = true" will prevent starting the timer that way.
//======================================
// Fusion_Data_HeroStatsMod:
// 0 uses Results default
// 1 uses Average of fusion members
// 2 uses sum of fusion members
// Fusion_Data_DefuseAfterDurHP is a % value between 0 and 1 or -1 to use Fusions %
// Fusion_Event
//
// 1 = NonHero Fusion
// 2 = Hero Fusion
// 3 = FadeInFinish
// -1 = Defusion
// Fusion_Event_Fusion = the Fusion
// Fusion_Event_Source = the Source casted fusion spell.
// Fusion_Event_Group = the merged/demerged Units; is does not contain substitutes.
// Fusion_Event_SpellData = the data index of the used Spell for fusing.
// Fusion_Event_SpellLevel = the level with which the fusion was casted.
// Fusion_Event_SpellObject = the FusionObjectIndex with this you an manipulate data inside an event, most time unneeded.
// Arrays here generally start with 1
//======================================
//Constants
//======================================
//Will the Fusion will be automatacly added to the selection of the owning Player?
constant function UnitFusionAutoSelect takes nothing returns boolean
return true
endfunction
constant function UnitFusionErrorMsg takes nothing returns string
return "Misses:"
endfunction
//ErrorMessage for each Missing Wildcard Unit.
//Looks like this:
//Misses:
// - Peon
// - Warlock
// - WildCard-Unit
// - WildCard-Unit
//
constant function UnitFusionWildCard takes nothing returns string
return " - WildCard-Unit"
endfunction
//How much is an unit transparent while flying 255 = 0%, 0 = 100%
constant function UnitFusionFade takes nothing returns integer
return 128
endfunction
//This is used to get units beeing at the edge of the AoE Indikator of a spell, beeing inside wither their hitbox.
constant function UnitMaxColison takes nothing returns real
return 200.0
endfunction
//Intervale used for fadingIn/Pulling
constant function UnitFusionTimerSpeed takes nothing returns real
return 0.05
endfunction
//How long one does see what is missing to fuse in seconds
constant function UnitFusionErrorDur takes nothing returns real
return 11.0
endfunction
constant function UnitFusionEventNonHero takes nothing returns real
return 1.0
endfunction
constant function UnitFusionEventHero takes nothing returns real
return 2.0
endfunction
constant function UnitFusionEventFadeInFinish takes nothing returns real
return 3.0
endfunction
constant function UnitFusionEventDefusion takes nothing returns real
return -1.0
endfunction
//The Fusion_Current_ItemStack usage for Defusions starts at Offset.
constant function UnitDefusionItemOffset takes nothing returns integer
return 200
endfunction
//Used by Fusion_Object_Type
constant function UnitFusionTypePull takes nothing returns string
return "UnitFusionPulled"
endfunction
constant function UnitFusionTypeDefusion takes nothing returns string
return "UnitDefusionMonitor"
endfunction
constant function UnitFusionTypeFadeIn takes nothing returns string
return "UnitFusionFadeIn"
endfunction
function StringIsEmpty takes string s returns boolean
return s == null or s == ""
endfunction
//======================================
//Code - Starts
//======================================
//This will return the Entering Index of the new Object
//And creates an pointer pointing at it.
//The LastUsed ObjectIndex is saved in udg_Fusion_Current_CreatedObject.
function UnitFusionInserObject takes nothing returns integer
local integer returnValue
if udg_Fusion_System_ReuseSize > 0 then
set returnValue = udg_Fusion_System_Reuse[udg_Fusion_System_ReuseSize]
set udg_Fusion_System_ReuseSize = udg_Fusion_System_ReuseSize - 1
else
set udg_Fusion_System_ObjectSize = udg_Fusion_System_ObjectSize + 1
set returnValue = udg_Fusion_System_ObjectSize
endif
set udg_Fusion_Current_CreatedObject = returnValue
//Create Pointer with used Object.
set udg_Fusion_System_Pointer_Last = udg_Fusion_System_Pointer_Last + 1
set udg_Fusion_System_Pointer[udg_Fusion_System_Pointer_Last] = returnValue
set udg_Fusion_Object_Pointer[returnValue] = udg_Fusion_System_Pointer_Last
set udg_Fusion_System_Pointer_Finished[udg_Fusion_System_Pointer_Last] = false
return returnValue
endfunction
//Will give you the index of an free spot in the Defusion Items.
function UnitDefusionItemGetFreeSpot takes nothing returns integer
local integer returnValue
if udg_Fusion_Item_DefReuseSize > 0 then
set returnValue = udg_Fusion_Item_DefReuse[udg_Fusion_Item_DefReuseSize]
set udg_Fusion_Item_DefReuseSize = udg_Fusion_Item_DefReuseSize - 1
else
set udg_Fusion_Item_DefSize = udg_Fusion_Item_DefSize + 1
set returnValue = udg_Fusion_Item_DefSize
endif
return returnValue
endfunction
// Will Create a new Fusion Object
//Cloning Fusion, Source,LEvel,Owner,Data, add all Units to the a group
function UnitFusionCloneObject takes integer sourceObject returns integer
local integer indexObject = UnitFusionInserObject()
if udg_Fusion_Object_Loc[indexObject] == null then
set udg_Fusion_Object_Loc[indexObject] = Location(GetLocationX(udg_Fusion_Object_Loc[sourceObject]),GetLocationY(udg_Fusion_Object_Loc[sourceObject]))
else
call MoveLocation(udg_Fusion_Object_Loc[indexObject],GetLocationX(udg_Fusion_Object_Loc[sourceObject]),GetLocationY(udg_Fusion_Object_Loc[sourceObject]))
endif
if udg_Fusion_Object_Group[indexObject] == null then
set udg_Fusion_Object_Group[indexObject] = CreateGroup()
else
call GroupClear(udg_Fusion_Object_Group[indexObject])
endif
set udg_Fusion_Object_Fusion[indexObject] = udg_Fusion_Object_Fusion[sourceObject]
set udg_Fusion_Object_Source[indexObject] = udg_Fusion_Object_Source[sourceObject]
set udg_Fusion_Object_SpellLevel[indexObject] = udg_Fusion_Object_SpellLevel[sourceObject]
set udg_Fusion_Object_DataIndex[indexObject] = udg_Fusion_Object_DataIndex[sourceObject]
set udg_Fusion_Object_Effect[indexObject] = null
call GroupAddGroup(udg_Fusion_Object_Group[sourceObject],udg_Fusion_Object_Group[indexObject])
// call printCloneGroups(udg_Fusion_Object_Group[sourceObject],udg_Fusion_Object_Group[indexObject])
return indexObject
endfunction
function UnitFusionItemStackRemove takes integer indexChoosen returns nothing
//That makes no sense
if indexChoosen == -1 then
return
endif
if indexChoosen != udg_Fusion_Item_Size then
set udg_Fusion_Item_Item[indexChoosen] = udg_Fusion_Item_Item[udg_Fusion_Item_Size]
set udg_Fusion_Item_Owner[indexChoosen] = udg_Fusion_Item_Owner[udg_Fusion_Item_Size]
endif
set udg_Fusion_Item_Item[udg_Fusion_Item_Size] = null
set udg_Fusion_Item_Owner[udg_Fusion_Item_Size] = null
set udg_Fusion_Item_Size = udg_Fusion_Item_Size - 1
endfunction
//Returns the Item with the highest Level from the stack.
//removeReturned = true will take it from the stack and countdown.
function UnitFusionBestItem takes nothing returns integer
local integer LoopA = 1
local integer indexChoosen = -1
local integer level = 0
//Find one with highestLevel
loop
exitwhen LoopA > udg_Fusion_Item_Size
if level < GetItemLevel(udg_Fusion_Item_Item[LoopA]) then
set indexChoosen = LoopA
set level = GetItemLevel(udg_Fusion_Item_Item[LoopA])
endif
set LoopA = LoopA + 1
endloop
return indexChoosen
endfunction
//Returns the ItemTypeId of the item with the highest Level from the stack.
//removeReturned = true will take it from the stack and countdown.
//might be unneeded
function UnitFusionBestItemType takes boolean removeReturned returns integer
local integer LoopA = 1
local integer indexChoosen = -1
local integer itemId = 0
local integer level = 0
//Find one with highestLevel
loop
exitwhen LoopA > udg_Fusion_Item_Size
if level < GetItemLevel(udg_Fusion_Item_Item[LoopA]) then
set indexChoosen = LoopA
set itemId = GetItemTypeId(udg_Fusion_Item_Item[indexChoosen])
set level = GetItemLevel(udg_Fusion_Item_Item[LoopA])
endif
set LoopA = LoopA + 1
endloop
//Reindex?
if removeReturned and indexChoosen != -1 then
if indexChoosen != udg_Fusion_Item_Size then
set udg_Fusion_Item_Item[indexChoosen] = udg_Fusion_Item_Item[udg_Fusion_Item_Size]
set udg_Fusion_Item_Owner[udg_Fusion_Item_Size] = udg_Fusion_Item_Owner[udg_Fusion_Item_Size]
else
set udg_Fusion_Item_Item[udg_Fusion_Item_Size] = null
set udg_Fusion_Item_Owner[udg_Fusion_Item_Size] = null
endif
set udg_Fusion_Item_Size = udg_Fusion_Item_Size - 1
endif
return itemId
endfunction
//Take items from the ItemStack and move them to the Unit u.
//Will give the hero the best (heighest Level) first
function UnitFusionGiveItems takes unit u returns nothing
local integer creationCount = UnitInventorySize(u)
local integer indexChoosen
local integer indexCurrent
local integer indexLast
loop
exitwhen 0 == udg_Fusion_Item_Size or creationCount == 0
set indexChoosen = UnitFusionBestItem()
if indexChoosen != 0 then
call UnitAddItem (u, udg_Fusion_Item_Item[indexChoosen])
call UnitFusionItemStackRemove(indexChoosen)
set creationCount = creationCount - 1
else
set creationCount = 0
endif
endloop
endfunction
//Take items from the ItemStack and move them to the Unit u.
//Will give the hero the best (heighest Level) first
// This will save items and old owners.
function UnitFusionGiveItemsSave takes unit u, integer indexDefusion returns nothing
local integer creationCount = UnitInventorySize(u)
local integer indexChoosen
local integer indexCurrent
local integer indexLast
//This is the End point of this Defusions items.
set udg_Fusion_Object_Int3[indexDefusion] = UnitDefusionItemGetFreeSpot()
set indexCurrent =udg_Fusion_Object_Int3[indexDefusion]
loop
exitwhen 0 == udg_Fusion_Item_Size or creationCount == 0
set indexChoosen = UnitFusionBestItem()
if indexChoosen != -1 then
set indexLast = indexCurrent
set indexCurrent = UnitDefusionItemGetFreeSpot()
set udg_Fusion_Item_DefNext[indexLast] = indexCurrent
set udg_Fusion_Item_Item[indexCurrent] = udg_Fusion_Item_Item[indexChoosen]
set udg_Fusion_Item_Owner[indexCurrent] = udg_Fusion_Item_Owner[indexChoosen]
//call BJDebugMsg(GetItemName(udg_Fusion_Item_Item[indexCurrent])+ GetHeroProperName(udg_Fusion_Item_Owner[indexCurrent]))
call UnitAddItem (u, udg_Fusion_Item_Item[indexChoosen])
call UnitFusionItemStackRemove(indexChoosen)
set creationCount = creationCount - 1
else
set creationCount = 0
endif
endloop
//finish the list
set udg_Fusion_Item_DefNext[indexCurrent] = -1
endfunction
//This Loads all Items of the unit into the stack.
//Will Count up udg_Fusion_Item_Size
function UnitFusionLoadInventory takes unit u returns nothing
local integer LoopInventory = 0
//Gain Items
if UnitInventorySize(u) != 0 then
loop
exitwhen LoopInventory == UnitInventorySize(u)
if UnitItemInSlot(u, LoopInventory) != null then
set udg_Fusion_Item_Size = udg_Fusion_Item_Size + 1
set udg_Fusion_Item_Item[udg_Fusion_Item_Size] = UnitItemInSlot(u, LoopInventory)
set udg_Fusion_Item_Owner[udg_Fusion_Item_Size] = u
endif
set LoopInventory = LoopInventory + 1
endloop
endif
endfunction
//Overall timer
//Executes sub actions based on Type.
//Main Index for sub functions are
// udg_Fusion_Current_Pointer the pointer
function UnitFusionTimer takes nothing returns nothing
local integer LoopA = 1
//call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1,I2S(udg_Fusion_System_Pointer_Last))
loop
exitwhen LoopA > udg_Fusion_System_Pointer_Last
if not udg_Fusion_System_Pointer_Finished[LoopA] then
set udg_Fusion_Current_Pointer = LoopA
set udg_Fusion_Current_Object = udg_Fusion_System_Pointer[LoopA]
set udg_Fusion_Current_Data = udg_Fusion_Object_DataIndex[udg_Fusion_Current_Object]
call ExecuteFunc(udg_Fusion_Object_Type[udg_Fusion_Current_Object])
else
//Mark DataRow reusable
set udg_Fusion_System_ReuseSize = udg_Fusion_System_ReuseSize + 1
set udg_Fusion_System_Reuse[udg_Fusion_System_ReuseSize] = udg_Fusion_System_Pointer[LoopA]
//Pointer Reindex
set udg_Fusion_Object_Pointer[udg_Fusion_System_Pointer[LoopA]] = udg_Fusion_System_Pointer_Last
set udg_Fusion_System_Pointer_Finished[LoopA] = udg_Fusion_System_Pointer_Finished[udg_Fusion_System_Pointer_Last]
set udg_Fusion_System_Pointer[LoopA] = udg_Fusion_System_Pointer[udg_Fusion_System_Pointer_Last]
set udg_Fusion_System_Pointer_Last = udg_Fusion_System_Pointer_Last - 1
set LoopA = LoopA - 1
endif
set LoopA = LoopA + 1
endloop
if udg_Fusion_System_Pointer_Last == 0 then
call PauseTimer(udg_Fusion_System_Timer)
endif
endfunction
//This is called to (re)start the timer.
function UnitFusionTimerStart takes nothing returns nothing
if not udg_Fusion_System_TimerDisabled then
call TimerStart(udg_Fusion_System_Timer, UnitFusionTimerSpeed(),true, function UnitFusionTimer)
endif
endfunction
function UnitDropInventory takes unit u returns nothing
local integer LoopInventory = UnitInventorySize(u)
if UnitInventorySize(u) != 0 then
loop
set LoopInventory = LoopInventory - 1
exitwhen LoopInventory == -1
call UnitRemoveItemFromSlot(u, LoopInventory)
endloop
endif
endfunction
//This function will defusion an fusion unit.
//call it with index -1, if you don't know the Defusion index.
function UnitDefusion takes unit u, boolean killed, integer indexFusion returns nothing
local integer LoopA = 1
local integer LoopB
local integer itemIndex
local integer indexData
local real x
local real x2
local real y
local real y2
local real angleInc
local real angle
local item i
local integer amountMats
local integer exp
local unit fog
local boolean wasSelected = IsUnitSelected(u, GetOwningPlayer(u))
//Skip calls using unit without anyone in users.
if FirstOfGroup(udg_Fusion_System_DefusionUser) == null and indexFusion == -1 then
return
endif
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, "Defusion")
//When indexFusion unknown find it.
if indexFusion == - 1 then
loop
exitwhen LoopA > udg_Fusion_System_Pointer_Last
//Find Defusion
if u == udg_Fusion_Object_Fusion[udg_Fusion_System_Pointer[LoopA]] then
// call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, "Nr:"+I2S(LoopA))
set indexFusion = udg_Fusion_System_Pointer[LoopA]
set udg_Fusion_System_Pointer_Finished[LoopA] = true
exitwhen true
endif
set LoopA = LoopA + 1
endloop
set x = GetUnitX(u)
set y = GetUnitY(u)
else
set udg_Fusion_System_Pointer_Finished[udg_Fusion_Object_Pointer[indexFusion]] = true
set u = udg_Fusion_Object_Fusion[indexFusion]
set x = GetLocationX(udg_Fusion_Object_Loc[indexFusion])
set y = GetLocationY(udg_Fusion_Object_Loc[indexFusion])
endif
call GroupRemoveUnit(udg_Fusion_System_DefusionUser, u)
//not found?
if indexFusion == -1 then
return
endif
set indexData = udg_Fusion_Object_DataIndex[indexFusion]
set amountMats = CountUnitsInGroup (udg_Fusion_Object_Group[indexFusion])
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, GetObjectName(udg_Fusion_Data_Spell[indexData]))
call DestroyEffect( AddSpecialEffect(udg_Fusion_Data_DefuseSFX[indexData],x,y))
//Drop Items and give them to their owners.
if udg_Fusion_Object_Int3[indexFusion] != -1 then
set itemIndex = udg_Fusion_Object_Int3[indexFusion]
loop
exitwhen itemIndex == -1
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, "Item Nr: "+I2S(itemIndex)+GetItemName(udg_Fusion_Item_Item[itemIndex]))
if UnitHasItem(u, udg_Fusion_Item_Item[itemIndex]) then
// call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, "Give it to: "+I2S(itemIndex)+GetHeroProperName(udg_Fusion_Item_Owner[itemIndex]))
call PauseUnit(udg_Fusion_Item_Owner[itemIndex], false)
call ShowUnit(udg_Fusion_Item_Owner[itemIndex], true)
call UnitAddItem(udg_Fusion_Item_Owner[itemIndex], udg_Fusion_Item_Item[itemIndex])
endif
//mark as free.
set udg_Fusion_Item_DefReuseSize = udg_Fusion_Item_DefReuseSize + 1
set udg_Fusion_Item_DefReuse[udg_Fusion_Item_DefReuseSize] = itemIndex
//next item
set itemIndex = udg_Fusion_Item_DefNext[itemIndex]
endloop
//Drop all items from the fusion.
set LoopA = UnitInventorySize(u) - 1
loop
exitwhen LoopA == -1
call SetItemPosition( UnitItemInSlot (u, LoopA),x,y)
set LoopA = LoopA - 1
endloop
endif
//Prepare Event
set udg_Fusion_Event_Fusion = u
set udg_Fusion_Event_Source = udg_Fusion_Object_Source[indexFusion]
set udg_Fusion_Event_SpellData = udg_Fusion_Object_DataIndex[indexFusion]
set udg_Fusion_Event_SpellLevel = udg_Fusion_Object_SpellLevel[indexFusion]
set udg_Fusion_Event_SpellObject = indexFusion
call GroupClear (udg_Fusion_Event_Group)
//Remove the Fuion?
if udg_Fusion_Data_Remove[indexData] then
call RemoveUnit(u)
else
//Might be a Custom call to defuse
call KillUnit(u)
endif
set angle = 0
set angleInc = 2 * bj_PI / amountMats
//Current Exp - old exp = gained Exp
set exp = R2I((udg_Fusion_Object_Int2[indexFusion] - udg_Fusion_Object_Int1[indexFusion]) * udg_Fusion_Data_DefusionEXPMulti[indexData] / amountMats)
//Restore fusion Parts.
loop
set fog = FirstOfGroup (udg_Fusion_Object_Group[indexFusion])
exitwhen fog == null
call GroupRemoveUnit(udg_Fusion_Object_Group[indexFusion],fog)
set x2 = x + udg_Fusion_Data_DefuseDistance[indexData]*Cos(angle)
set y2 = y + udg_Fusion_Data_DefuseDistance[indexData]*Sin(angle)
set angle = angle + angleInc
// call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, "ReGain "+GetUnitName(fog) )
//Make Mats useable
call SetUnitPosition(fog, x2,y2)
call ShowUnit(fog,true)
call PauseUnit(fog,false)
call SetUnitInvulnerable(fog, false )
call SetUnitPathing (fog, true)
call SetUnitVertexColor(fog,255,255,255,255)
call UnitRemoveAbility(fog ,'Arav')
call AddHeroXP(fog, exp, true)
if udg_Fusion_Data_DefuseDispellMat[indexData] then
call UnitRemoveBuffs(fog, true, true)
endif
call SetUnitFacing(fog,bj_RADTODEG * Atan2(y - y2, x - x2))
//Load defused material into fusionGroup
call GroupAddUnit(udg_Fusion_Event_Group, fog)
//What shall happen with the mat?
if (killed and not udg_Fusion_Data_DefuseOnKilled[indexData]) or ( not killed and not udg_Fusion_Data_DefuseAfterDur[indexData] )then
//units are lost.
call UnitDropInventory(fog)
call RemoveUnit(fog)
else
call SetUnitUseFood( fog, true )
if wasSelected then
call SelectUnitAddForPlayer( fog, GetOwningPlayer(fog))
endif
if killed then
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, "Fusion killed/Removed - Set Restored Unit's Life to ="+GetUnitName(u)+" "+ R2S(( GetUnitState(u, UNIT_STATE_MAX_LIFE))* udg_Fusion_Data_DefuseOnKilledHP[indexData]))
call SetUnitState(fog, UNIT_STATE_LIFE, GetUnitState(fog, UNIT_STATE_MAX_LIFE) * udg_Fusion_Data_DefuseOnKilledHP[indexData])
call SetUnitState(fog, UNIT_STATE_MANA, GetUnitState(fog, UNIT_STATE_MAX_MANA) * udg_Fusion_Data_DefuseOnKilledMP[indexData])
else
if udg_Fusion_Data_DefuseAfterDurHP[indexData] == -1 then
call SetUnitState(fog, UNIT_STATE_LIFE, GetUnitState(fog, UNIT_STATE_MAX_LIFE) * udg_Fusion_Object_Real1[indexFusion])
else
call SetUnitState(fog, UNIT_STATE_LIFE, GetUnitState(fog, UNIT_STATE_MAX_LIFE) * udg_Fusion_Data_DefuseAfterDurHP[indexData])
endif
if udg_Fusion_Data_DefuseAfterDurMP[indexData] == -1 then
call SetUnitState(fog, UNIT_STATE_MANA, GetUnitState(fog, UNIT_STATE_MAX_MANA) * udg_Fusion_Object_Real2[indexFusion])
else
call SetUnitState(fog, UNIT_STATE_MANA, GetUnitState(fog, UNIT_STATE_MAX_MANA) * udg_Fusion_Data_DefuseAfterDurMP[indexData])
endif
endif
endif
endloop
//Throw Event
set udg_Fusion_Event = UnitFusionEventDefusion()
set udg_Fusion_Event = 0
endfunction
//Will get one the Life and Mana from the Defusion. To use on defusion.
// Int1 = Old EP
// Int2 = current ep
// Real1 = current Life
// Real2 = current Mana.
function UnitDefusionMonitor takes nothing returns nothing
local integer indexObject = udg_Fusion_System_Pointer[udg_Fusion_Current_Pointer]
//was Removed?
if GetUnitState(udg_Fusion_Object_Fusion[indexObject], UNIT_STATE_MAX_LIFE) != 0 then
set udg_Fusion_Object_Int2[indexObject] = GetHeroXP (udg_Fusion_Object_Fusion[indexObject])
call MoveLocation(udg_Fusion_Object_Loc[indexObject],GetUnitX(udg_Fusion_Object_Fusion[indexObject]),GetUnitY(udg_Fusion_Object_Fusion[indexObject]))
//Percent
set udg_Fusion_Object_Real1[indexObject] = GetUnitState( udg_Fusion_Object_Fusion[indexObject], UNIT_STATE_LIFE)/ GetUnitState( udg_Fusion_Object_Fusion[indexObject], UNIT_STATE_MAX_LIFE)
if GetUnitState(udg_Fusion_Object_Fusion[indexObject], UNIT_STATE_MAX_MANA) != 0 then
set udg_Fusion_Object_Real2[indexObject] = GetUnitState( udg_Fusion_Object_Fusion[indexObject], UNIT_STATE_MANA)/GetUnitState( udg_Fusion_Object_Fusion[indexObject], UNIT_STATE_MAX_MANA)
endif
else
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 5, "Force Defusion: ")
call UnitDefusion(null, true, indexObject)
endif
endfunction
//Triggers if an Unit dies.
function UnitDefusionDeath takes nothing returns nothing
if IsUnitInGroup (GetTriggerUnit(), udg_Fusion_System_DefusionUser) then
call UnitDefusion(GetTriggerUnit(), (GetKillingUnit() != null), -1 )
endif
endfunction
//This will use the given Fusion_Object and use it for defusion
//If you need an new one call it with InserObject or with cloneObject
function UnitDefusionTransformObject takes integer indexObject returns nothing
set udg_Fusion_Object_Int1[indexObject] = GetHeroXP (udg_Fusion_Object_Fusion[indexObject])
set udg_Fusion_Object_Int2[indexObject] = udg_Fusion_Object_Int1[indexObject]
//Next Line saves defusions if they do not take over items
set udg_Fusion_Object_Int3[indexObject] = -1
set udg_Fusion_Object_Type[indexObject] = UnitFusionTypeDefusion()
call DestroyEffect(udg_Fusion_Object_Effect[indexObject])
set udg_Fusion_Object_Effect[indexObject] = null
call GroupAddUnit(udg_Fusion_System_DefusionUser, udg_Fusion_Object_Fusion[indexObject])
call UnitFusionTimerStart()
endfunction
//perfoms actions an Material for Defusion should do.
function UnitDefusionSaveMatObject takes unit u, integer indexObject returns nothing
call GroupAddUnit(udg_Fusion_Object_Group[indexObject], u)
call SetUnitInvulnerable(u, true )
call PauseUnit(u, true )
call ShowUnit(u, false)
call SetUnitUseFood( u, false )
call SetUnitPathing (u, false)
call SetUnitPositionLoc(u, udg_Fusion_System_SaveLoc)
endfunction
//Action
// Real1 = remaningDur in seconds.
// Real2 = CurrentTransparenz
// Real3 = Transparenz change a intervale
function UnitFusionFadeIn takes nothing returns nothing
local integer indexObject = udg_Fusion_System_Pointer[udg_Fusion_Current_Pointer]
local integer indexData = udg_Fusion_Object_DataIndex[indexObject]
//Stop instantly when Fusion Unit was removed/dead.
if GetWidgetLife(udg_Fusion_Object_Fusion[indexObject]) < 0.405 then
set udg_Fusion_System_Pointer_Finished[udg_Fusion_Current_Pointer] = true
call DestroyEffect(udg_Fusion_Object_Effect[indexObject])
set udg_Fusion_Object_Effect[indexObject] = null
return
endif
//Calc new Transperence
set udg_Fusion_Object_Real2[indexObject] = udg_Fusion_Object_Real2[indexObject] + udg_Fusion_Object_Real3[indexObject]
call SetUnitVertexColor(udg_Fusion_Object_Fusion[indexObject], 255, 255, 255, R2I(udg_Fusion_Object_Real2[indexObject]))
set udg_Fusion_Object_Real1[indexObject] = udg_Fusion_Object_Real1[indexObject] - UnitFusionTimerSpeed()
//FadeIn Finish?
if udg_Fusion_Object_Real1[indexObject] <= 0.0 then
set udg_Fusion_System_Pointer_Finished[udg_Fusion_Current_Pointer] = true
//Finish destroy
if not udg_Fusion_Object_Bool[indexObject] then
call SetUnitInvulnerable(udg_Fusion_Object_Fusion[indexObject], false )
endif
call PauseUnit(udg_Fusion_Object_Fusion[indexObject], false)
if UnitFusionAutoSelect() then
call SelectUnitAddForPlayer(udg_Fusion_Object_Fusion[indexObject], GetOwningPlayer(udg_Fusion_Object_Fusion[indexObject]))
endif
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, UnitFusionErrorDur(), udg_Fusion_Data_SFXResult[indexData] +" "+ udg_Fusion_Data_SFXResultAttacht[indexData] )
call DestroyEffect(AddSpecialEffectTarget( udg_Fusion_Data_SFXResult[indexData] , udg_Fusion_Object_Fusion[indexObject],udg_Fusion_Data_SFXResultAttacht[indexData] ))
call DestroyEffect(udg_Fusion_Object_Effect[indexObject])
set udg_Fusion_Object_Effect[indexObject] = null
//Throw Event
call GroupClear (udg_Fusion_Event_Group)
call GroupAddGroup(udg_Fusion_Object_Group[indexObject], udg_Fusion_Event_Group)
set udg_Fusion_Event_Fusion = udg_Fusion_Object_Fusion[indexObject]
set udg_Fusion_Event_Source = udg_Fusion_Object_Source[indexObject]
set udg_Fusion_Event_SpellData = indexData
set udg_Fusion_Event_SpellLevel = udg_Fusion_Object_SpellLevel[indexObject]
set udg_Fusion_Event_SpellObject = indexObject
set udg_Fusion_Event = UnitFusionEventFadeInFinish()
set udg_Fusion_Event = 0
//this will clean the objct on next timer intervale
else
call PauseUnit(udg_Fusion_Object_Fusion[indexObject], true)
endif
endfunction
//Takeover an FusionObject for fading in
//To start an new call it with cloneObject(orginalObject)
// Real1 = remaningDur in seconds.
// Real2 = CurrentTransparenz
// Real3 = Transparenz change a intervale
function UnitFusionStartFadeInTakeOver takes integer indexObject returns nothing
local integer indexData = udg_Fusion_Object_DataIndex[indexObject]
if not udg_Fusion_Data_FadeVulnerable[indexData] then
call SetUnitInvulnerable( udg_Fusion_Object_Fusion[indexObject], true )
endif
set udg_Fusion_Object_Bool[indexObject] = udg_Fusion_Data_FadeVulnerable[indexData]
call PauseUnit(udg_Fusion_Object_Fusion[indexObject], true)
call SetUnitVertexColor(udg_Fusion_Object_Fusion[indexObject], 255, 255, 255, 0)
if udg_Fusion_Object_Effect[indexObject] == null then
set udg_Fusion_Object_Effect[indexObject] = AddSpecialEffect( udg_Fusion_Data_SFX[indexData] , GetUnitX(udg_Fusion_Object_Fusion[indexObject]),GetUnitY(udg_Fusion_Object_Fusion[indexObject]))
endif
set udg_Fusion_Object_Type[indexObject] = UnitFusionTypeFadeIn()
set udg_Fusion_Object_Real1[indexObject] = udg_Fusion_Data_FadeIn[indexData]
set udg_Fusion_Object_Real2[indexObject] = 0
set udg_Fusion_Object_Real3[indexObject]= PercentToInt(100 - udg_Fusion_Data_FadeInHidden[indexData], 255) / udg_Fusion_Data_FadeIn[indexData] * UnitFusionTimerSpeed()
//Duration above 0?
if udg_Fusion_Data_ResultDur[indexData] + udg_Fusion_Data_ResultDurPerLevel[indexData] * udg_Fusion_Object_SpellLevel[indexObject] > 0 then
call UnitApplyTimedLife( udg_Fusion_Object_Fusion[indexObject], 'BTLF', udg_Fusion_Data_ResultDur[indexData] + udg_Fusion_Data_ResultDurPerLevel[indexData] * udg_Fusion_Object_SpellLevel[indexObject] )
endif
call UnitFusionTimerStart()
endfunction
//Start FadingIn for u
// Creates a new Fusion Object.
//This for peouple who want to use the fadeinEffect.
function UnitFusionStartFadeIn takes unit u, real dur, real hiddenStateAfter, string sfx, boolean immunDuringFade returns nothing
local integer indexObject
set indexObject = UnitFusionInserObject()
if immunDuringFade then
call SetUnitInvulnerable( u, true )
endif
set udg_Fusion_Object_Bool[indexObject] = immunDuringFade
call PauseUnit(u, true)
call SetUnitVertexColor(u, 255, 255, 255, 0)
//Call it without unit.
set udg_Fusion_Object_Fusion[indexObject] = u
set udg_Fusion_Object_Type[indexObject] = UnitFusionTypeFadeIn()
set udg_Fusion_Object_Real1[indexObject] = dur
set udg_Fusion_Object_DataIndex[indexObject] = -1
//Create new effect?
set udg_Fusion_Object_Effect[indexObject] = AddSpecialEffect( sfx, GetUnitX(u), GetUnitY(u) )
set udg_Fusion_Object_Real2[indexObject] = 0
set udg_Fusion_Object_Real3[indexObject]= PercentToInt(100 - hiddenStateAfter, 255) / dur * UnitFusionTimerSpeed()
call UnitFusionTimerStart()
endfunction
function UnitFusionPulledGetItems takes nothing returns nothing
call UnitFusionLoadInventory(GetEnumUnit())
endfunction
//Subfunction - UnitFusionPulled
//Removes the material
function UnitFusionCleanMats takes nothing returns nothing
local unit u = GetEnumUnit()
call ShowUnit(u, false)
call ShowUnit(u, true)
if udg_Fusion_Data_Remove[udg_Fusion_Current_Data] then
call UnitDropInventory(u)
call RemoveUnit(u)
else
call KillUnit(u)
endif
set u = null
endfunction
//Subfunction - UnitFusionPulled
//Removes substitutes missles
function UnitFusionPulledClean takes nothing returns nothing
local unit u = GetEnumUnit()
if GetUnitTypeId(u) == udg_Fusion_Data_Replace[udg_Fusion_Current_Data] then
call GroupRemoveUnit(udg_Fusion_Object_Group[udg_Fusion_Current_Object] , u)
call RemoveUnit(u)
endif
set u = null
endfunction
//Loads real Units into the FusionEventGroup
//Old - Unneeded
function UnitFusionLoadParts takes nothing returns nothing
if GetUnitTypeId(GetEnumUnit()) != udg_Fusion_Data_Replace[udg_Fusion_Current_Data] then
call GroupAddUnit (udg_Fusion_Event_Group, GetEnumUnit())
endif
endfunction
//Subfunction - UnitFusionPulled
//Group Enumeration of Current FusionGroup
//Real1 = Speed
//Real2 = ZSpeed
function UnitFusionPulledPull takes nothing returns nothing
local integer indexObject = udg_Fusion_System_Pointer[udg_Fusion_Current_Pointer]
local integer indexData = udg_Fusion_Object_DataIndex[indexObject]
local unit u = GetEnumUnit()
local real x
local real y
local real angle
//call BJDebugMsg("Pull")
//do not move real units if there is an replace.
if udg_Fusion_Data_Replace[indexData] != 0 and GetUnitTypeId(u) != udg_Fusion_Data_Replace[indexData] then
return
endif
//Flying enabled?
if udg_Fusion_Object_Real2[indexObject] > 0 then
call SetUnitFlyHeight( u, ( GetUnitFlyHeight(u) + udg_Fusion_Object_Real2[indexObject] ), 0.00 )
endif
//Avoid Moving units over the Location; hidden defusion using an replace do not matter.
if IsUnitInRangeLoc(u, udg_Fusion_Object_Loc[indexObject], udg_Fusion_Object_Real1[indexObject]) or ((udg_Fusion_Data_DefuseAfterDur[indexData] or udg_Fusion_Data_DefuseOnKilled[indexData]) and udg_Fusion_Data_Replace[indexData] == 0 and GetUnitTypeId(u) != udg_Fusion_Data_Replace[indexData]) then
call SetUnitPositionLoc( u, udg_Fusion_Object_Loc[indexObject] )
else
set udg_Fusion_Object_Bool[indexObject] = false
set x = GetUnitX(u)
set y = GetUnitY(u)
set angle = Atan2(GetLocationY(udg_Fusion_Object_Loc[indexObject]) - y, GetLocationX(udg_Fusion_Object_Loc[indexObject]) - x)
set x = x + udg_Fusion_Object_Real1[indexObject] * Cos(angle)
set y = y + udg_Fusion_Object_Real1[indexObject] * Sin(angle)
call SetUnitPosition( u, x,y )
endif
endfunction
//Group Action to take defusion Material out of play.
function UnitFusionSaveMat takes nothing returns nothing
call UnitDefusionSaveMatObject(GetEnumUnit(),udg_Fusion_Current_Object)
endfunction
//Spawns the Fusion
//Based on the Fusion Object
//Will fill udg_Fusion_Object_Fusion[indexObject] with the fusion.
function UnitFusionSpawn takes integer indexObject, real x, real y returns nothing
local integer indexData = udg_Fusion_Object_DataIndex[indexObject]
local unit u = CreateUnit (GetOwningPlayer(udg_Fusion_Object_Source[indexObject]), udg_Fusion_Data_Result[indexData], x, y, 270 )
local boolean hasInventory = (UnitInventorySize(u) != 0)
local boolean defusion = udg_Fusion_Data_DefuseAfterDur[indexData] or udg_Fusion_Data_DefuseOnKilled[indexData]
call UnitAddAbility(u, udg_Fusion_Data_SkillGained[indexData])
set udg_Fusion_Object_Fusion[indexObject] = u
call SetHeroLevel (u, udg_Fusion_Object_Int1[indexObject], false)
//Which Statmod, statsmod 0 is default?
if udg_Fusion_Data_HeroStatsMod[indexData] != 0 then
call SetHeroAgi (u, udg_Fusion_Object_Int2[indexObject], true)
call SetHeroStr (u, udg_Fusion_Object_Int3[indexObject], true)
call SetHeroInt (u, udg_Fusion_Object_Int4[indexObject], true)
endif
//Load Items.
if hasInventory then
set udg_Fusion_Item_Size = 0
call ForGroup(udg_Fusion_Object_Group[indexObject], function UnitFusionPulledGetItems)
endif
//Defusion?
if defusion then
call UnitDefusionTransformObject(indexObject)
set udg_Fusion_Current_Object = indexObject
call ForGroup(udg_Fusion_Object_Group[indexObject], function UnitFusionSaveMat)
set udg_Fusion_System_Pointer_Finished[udg_Fusion_Current_Pointer] = false
if hasInventory then
call UnitFusionGiveItemsSave(u, indexObject)
endif
else
set udg_Fusion_System_Pointer_Finished[udg_Fusion_Current_Pointer] = true
if hasInventory then
call UnitFusionGiveItems(u)
endif
endif
//apply Averrage Life?
if udg_Fusion_Data_ResultHPAverage[indexData] then
call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE) * udg_Fusion_Object_Real3[indexObject] )
endif
//apply Averrage Mana?
if udg_Fusion_Data_ResultMPAverage[indexData] then
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA) * udg_Fusion_Object_Real4[indexObject] )
endif
//Throw Event
call GroupClear(udg_Fusion_Event_Group)
//call ForGroup(udg_Fusion_Object_Group[indexObject], function UnitFusionLoadParts)
call GroupAddGroup(udg_Fusion_Object_Group[indexObject], udg_Fusion_Event_Group)
set udg_Fusion_Event_Fusion = u
set udg_Fusion_Event_Source = udg_Fusion_Object_Source[indexObject]
set udg_Fusion_Event_SpellData = indexData
set udg_Fusion_Event_SpellLevel = udg_Fusion_Object_SpellLevel[indexObject]
set udg_Fusion_Event_SpellObject = indexObject
if IsUnitType (u, UNIT_TYPE_HERO) then
set udg_Fusion_Event = UnitFusionEventHero()
else
set udg_Fusion_Event = UnitFusionEventNonHero()
endif
set udg_Fusion_Event = 0
//Start FadeIn after pulling?
if udg_Fusion_Data_FadeIn[indexData] > 0 then
//Start a new Fusion Object or takeover?
if udg_Fusion_System_Pointer_Finished[udg_Fusion_Current_Pointer] then
call UnitFusionStartFadeInTakeOver(indexObject)
set udg_Fusion_System_Pointer_Finished[udg_Fusion_Current_Pointer] = false
else
call UnitFusionStartFadeInTakeOver(UnitFusionCloneObject(indexObject))
endif
else
// Timed Life > 0
// Constant + Level * Levelboni
if udg_Fusion_Data_ResultDur[indexData] + ( udg_Fusion_Data_ResultDurPerLevel[indexData]* udg_Fusion_Object_SpellLevel[indexObject]) > 0 then
call UnitApplyTimedLife( u, 'BTLF', udg_Fusion_Data_ResultDur[indexData] + ( udg_Fusion_Data_ResultDurPerLevel[indexData]* udg_Fusion_Object_SpellLevel[indexObject]) )
endif
call DestroyEffect(udg_Fusion_Object_Effect[indexObject])
set udg_Fusion_Object_Effect[indexObject] = null
if UnitFusionAutoSelect() then
call SelectUnitAddForPlayer(u, GetOwningPlayer(udg_Fusion_Object_Source[indexObject]))
endif
call DestroyEffect(AddSpecialEffectTarget( udg_Fusion_Data_SFXResult[indexData] , u,udg_Fusion_Data_SFXResultAttacht[indexData] ))
endif
//Clean mats if no defusion
if not defusion then
call ForGroup(udg_Fusion_Object_Group[indexObject], function UnitFusionCleanMats)
endif
set u = null
endfunction
//Timer Sub Action Pull Fusion
// Real = Speed
// Real2 = ZSpeed
// Real3 = life On Fusion
// Real4 = Mana on fusion
// Int1 = heroLevel
// Int2 = heroAgi
// Int3 = heroStr
// Int4 = heroInt
function UnitFusionPulled takes nothing returns nothing
local integer indexObject = udg_Fusion_System_Pointer[udg_Fusion_Current_Pointer]
set udg_Fusion_Object_Bool[indexObject] = true
//Loop All running fusion
//Used in the Subfunction
call ForGroup(udg_Fusion_Object_Group[indexObject], function UnitFusionPulledPull)
//All parts are near Enough?
if udg_Fusion_Object_Bool[indexObject] then
call ForGroup(udg_Fusion_Object_Group[indexObject], function UnitFusionPulledClean)
call UnitFusionSpawn(indexObject, GetLocationX(udg_Fusion_Object_Loc[indexObject]),GetLocationY(udg_Fusion_Object_Loc[indexObject]))
endif
endfunction
function UnitFusionIsPart takes unit u, integer indexData returns boolean
local integer indexEnd = udg_Fusion_System_UnitTypesEnd[indexData]
local integer indexCurrent = udg_Fusion_System_UnitTypesStart[indexData]
set udg_Fusion_Current_FilterUnit = u
//Can Unit be part of Fusion?
loop
if udg_Fusion_Data_UnitTypes[indexCurrent] == 0 and udg_Fusion_System_Units[indexCurrent] == null then
if TriggerEvaluate(udg_Fusion_Data_FilterWild[indexData]) then
set udg_Fusion_System_Units[indexCurrent] = u
return true
endif
endif
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
return false
endfunction
function UnitFusionIsSpecificPart takes unit u, integer indexData returns boolean
local integer indexEnd = udg_Fusion_System_UnitTypesEnd[indexData]
local integer indexCurrent = udg_Fusion_System_UnitTypesStart[indexData]
local integer uTyp = GetUnitTypeId(u)
//Can Unit be part of Fusion?
loop
if uTyp == udg_Fusion_Data_UnitTypes[indexCurrent] and udg_Fusion_System_Units[indexCurrent] == null then
set udg_Fusion_System_Units[indexCurrent] = u
return true
endif
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
return false
endfunction
function UnitFusionPickAny takes nothing returns nothing
call UnitFusionIsPart(GetEnumUnit(), udg_Fusion_Current_Data)
call GroupRemoveUnit(udg_Fusion_Object_Group[0], GetEnumUnit())
endfunction
function UnitFusionPickSpecific takes nothing returns nothing
if UnitFusionIsSpecificPart(GetEnumUnit(), udg_Fusion_Current_Data) then
call GroupRemoveUnit(udg_Fusion_Object_Group[0], GetEnumUnit())
endif
endfunction
function UnitFusionPickSelected takes nothing returns nothing
if IsUnitSelected(GetEnumUnit(), GetTriggerPlayer()) then
call UnitFusionPickSpecific()
endif
endfunction
function UnitFusionFilter takes unit u, integer indexData returns boolean
local integer indexEnd = udg_Fusion_System_UnitTypesEnd[indexData]
local integer indexCurrent = udg_Fusion_System_UnitTypesStart[indexData]
local real life = GetWidgetLife(u)
set udg_Fusion_Current_FilterUnit = u
//Allowed?
//Ordercheck;
//Filter Units if OrderCheck is set and Unit has not the expectedOrder.
if not (udg_Fusion_Data_OrderCheck[indexData] == "" or udg_Fusion_Data_OrderCheck[indexData] == null ) and OrderId(udg_Fusion_Data_OrderCheck[indexData]) != GetUnitCurrentOrder(u) then
return false
endif
if not TriggerEvaluate(udg_Fusion_Data_FilterPre[indexData]) and udg_Fusion_Data_FilterPre[indexData] != null then
return false
endif
if not TriggerEvaluate(udg_Fusion_Data_FilterMain[indexData]) and udg_Fusion_Data_FilterMain[indexData] != null then
return false
endif
//Needed UnitTypes pass
loop
if GetUnitTypeId(u) == udg_Fusion_Data_UnitTypes[indexCurrent] or udg_Fusion_Data_UnitTypes[indexCurrent] == 0 then
return true
endif
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
//if something goes terrible wrong.
return false
endfunction
function UnitFusionFilterEnum takes nothing returns boolean
if IsUnitPaused(GetFilterUnit()) or IsUnitIllusion(GetFilterUnit()) or not IsUnitInRangeLoc(GetFilterUnit(), udg_Fusion_Object_Loc[0], udg_Fusion_Object_Real1[0]) then
return false
endif
return UnitFusionFilter(GetFilterUnit(),udg_Fusion_Current_Data)
endfunction
function UnitFusionFilterMessage takes integer indexData, integer indexCurrent, string s returns string
local string seperator = "\n"
set s = s +seperator
//Specific UnitType?
if udg_Fusion_Data_UnitTypes[indexCurrent] != null then
set s = s + " - " + GetObjectName(udg_Fusion_Data_UnitTypes[indexCurrent])
else
set s = s + UnitFusionWildCard()
endif
set seperator = null
return s
endfunction
//Generate ErrorWarrinng
function UnitFusionErrorMessage takes integer indexData, string s returns string
local string seperator = "\n"
set s = "|cffffcc00"+ GetObjectName(udg_Fusion_Data_Spell[indexData])+"|r"
if udg_Fusion_Data_FilterPre[indexData]!= null and udg_Fusion_Data_ErrorMsgPre[indexData] != null and udg_Fusion_Data_ErrorMsgPre[indexData] !="" then
set s = s + seperator
set s = s + udg_Fusion_Data_ErrorMsgPre[indexData]
endif
if udg_Fusion_Data_FilterMain[indexData]!= null and udg_Fusion_Data_ErrorMsgMain[indexData] != null and udg_Fusion_Data_ErrorMsgMain[indexData] !="" then
set s = s + seperator
set s = s + udg_Fusion_Data_ErrorMsgMain[indexData]
endif
if udg_Fusion_Data_FilterWild[indexData]!= null and udg_Fusion_Data_ErrorMsgWild[indexData] != null and udg_Fusion_Data_ErrorMsgWild[indexData] !="" then
set s = s + seperator
set s = s + udg_Fusion_Data_ErrorMsgWild[indexData]
endif
set s = s + seperator + UnitFusionErrorMsg()
set seperator = null
return s
endfunction
function UnitFusionLoadGroup takes integer indexCurrent, integer indexEnd, integer indexObject returns nothing
loop
call GroupAddUnit(udg_Fusion_Object_Group[indexObject], udg_Fusion_System_Units[indexCurrent])
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
endfunction
function UnitFusionFuse takes integer indexData, location loc returns nothing
local integer indexEnd = udg_Fusion_System_UnitTypesEnd[indexData]
local integer indexCurrent = udg_Fusion_System_UnitTypesStart[indexData]
local integer amount = ( udg_Fusion_System_UnitTypesEnd[indexData] - udg_Fusion_System_UnitTypesStart[indexData] ) + 1
local real x = 0
local real y = 0
local real x2 = 0
local real y2 = 0
local boolean isValidFusion = true
local unit u
local integer level = GetUnitAbilityLevel(GetTriggerUnit(), udg_Fusion_Data_Spell[indexData])
local real life = 0
local real mana = 0
local string s
local boolean defusion = udg_Fusion_Data_DefuseAfterDur[indexData] or udg_Fusion_Data_DefuseOnKilled[indexData]
local integer heroLevel = 0
local integer heroAgi = 0
local integer heroStr = 0
local integer heroInt = 0
local integer indexEnter
local boolean isResultHero = IsUnitIdType(udg_Fusion_Data_Result[indexData], UNIT_TYPE_HERO)
set udg_Fusion_Current_Data = indexData
//clear old data
call GroupClear(udg_Fusion_Object_Group[0])
loop
set udg_Fusion_System_Units[indexCurrent] = null
exitwhen indexCurrent == indexEnd
set indexCurrent = indexCurrent + 1
endloop
//Index 0 is never used, so one can use it here.
set udg_Fusion_Object_Real1[0] = udg_Fusion_Data_AoE[indexData] + ( level * udg_Fusion_Data_AoEPerLevel[indexData])
if udg_Fusion_Object_Real1[0] > 0 then
set udg_Fusion_Object_Loc[0] = loc
call GroupEnumUnitsInRangeOfLoc(udg_Fusion_Object_Group[0], loc, udg_Fusion_Object_Real1[0] + UnitMaxColison() , udg_Fusion_System_Filter)
set udg_Fusion_Object_Loc[0] = null
endif
//AutoAddCaster?
if udg_Fusion_Data_AutoAddCaster[indexData] and UnitFusionFilter(GetTriggerUnit(),indexData ) then
if UnitFusionIsSpecificPart(GetTriggerUnit(), udg_Fusion_Current_Data) then
call GroupRemoveUnit(udg_Fusion_Object_Group[0], GetTriggerUnit())
endif
endif
//AutoAddTarget?
if udg_Fusion_Data_AutoAddTarget[indexData] and UnitFusionFilter(GetSpellTargetUnit(),indexData ) then
if UnitFusionIsSpecificPart(GetSpellTargetUnit(), udg_Fusion_Current_Data) then
call GroupRemoveUnit(udg_Fusion_Object_Group[0], GetSpellTargetUnit())
endif
endif
//First check selected
call ForGroup(udg_Fusion_Object_Group[0], function UnitFusionPickSelected)
//then check for defined unittypes
call ForGroup(udg_Fusion_Object_Group[0], function UnitFusionPickSpecific)
//then use wildcard unittypes
set indexCurrent = udg_Fusion_System_UnitTypesStart[indexData]
//spell has wildcards?
loop
if udg_Fusion_Data_UnitTypes[indexCurrent] == 0 then
call ForGroup(udg_Fusion_Object_Group[0], function UnitFusionPickAny)
exitwhen true
endif
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
//All MergingParts found?
set indexCurrent = udg_Fusion_System_UnitTypesStart[indexData]
set s = UnitFusionErrorMessage(indexData,"")
loop
if udg_Fusion_System_Units[indexCurrent] == null then
set isValidFusion = false
set s = UnitFusionFilterMessage(indexData,indexCurrent,s)
else
set x = x + GetUnitX(udg_Fusion_System_Units[indexCurrent])
set y = y + GetUnitY(udg_Fusion_System_Units[indexCurrent])
set life = life + GetUnitStatePercent(udg_Fusion_System_Units[indexCurrent] , UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE)
set mana = mana + GetUnitStatePercent(udg_Fusion_System_Units[indexCurrent] , UNIT_STATE_MANA, UNIT_STATE_MAX_MANA)
//HeroStuf
if IsUnitType(udg_Fusion_System_Units[indexCurrent] ,UNIT_TYPE_HERO) and isResultHero then
set heroLevel = heroLevel + GetHeroLevel (udg_Fusion_System_Units[indexCurrent])
set heroAgi = heroAgi + GetHeroAgi(udg_Fusion_System_Units[indexCurrent], udg_Fusion_Data_HeroAllowBoniStats[indexData])
set heroStr = heroStr + GetHeroStr(udg_Fusion_System_Units[indexCurrent], udg_Fusion_Data_HeroAllowBoniStats[indexData])
set heroInt = heroInt + GetHeroInt(udg_Fusion_System_Units[indexCurrent], udg_Fusion_Data_HeroAllowBoniStats[indexData])
endif
endif
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
if isValidFusion then
set x= x/amount
set y = y/amount
set life = (life/amount)*0.01
set mana = (mana/amount) *0.01
set indexCurrent = udg_Fusion_System_UnitTypesStart[indexData]
if udg_Fusion_Data_SpawnAtTargetPoint[indexData] then
set x = GetLocationX(loc)
set y = GetLocationY(loc)
endif
//Gives an free spot in the Object Arrays.
set indexEnter = UnitFusionInserObject()
set udg_Fusion_Current_Pointer = udg_Fusion_System_Pointer_Last
set udg_Fusion_Current_Object = indexEnter
set udg_Fusion_Object_DataIndex[indexEnter] = indexData
set udg_Fusion_Object_Source[indexEnter] = GetTriggerUnit()
set udg_Fusion_Object_Fusion[indexEnter] = null
set udg_Fusion_Object_SpellLevel[indexEnter] = level
set udg_Fusion_Object_Real3[indexEnter] = life
set udg_Fusion_Object_Real4[indexEnter] = mana
if isResultHero then
if not udg_Fusion_Data_HeroSumLevel[indexData] then
set heroLevel = heroLevel / amount
endif
if udg_Fusion_Data_HeroStatsMod[indexData] == 1 then
set heroAgi = heroAgi / amount
set heroStr = heroStr / amount
set heroInt = heroInt / amount
endif
set udg_Fusion_Object_Int1[indexEnter] = heroLevel
set udg_Fusion_Object_Int2[indexEnter] = heroAgi
set udg_Fusion_Object_Int3[indexEnter] = heroStr
set udg_Fusion_Object_Int4[indexEnter] = heroInt
endif
if udg_Fusion_Object_Group[indexEnter] == null then
set udg_Fusion_Object_Group[indexEnter] = CreateGroup()
else
call GroupClear (udg_Fusion_Object_Group[indexEnter])
endif
call UnitFusionLoadGroup(indexCurrent,indexEnd,indexEnter)
if udg_Fusion_Object_Loc[indexEnter] == null then
set udg_Fusion_Object_Loc[indexEnter] = Location(x,y)
else
call MoveLocation(udg_Fusion_Object_Loc[indexEnter],x,y)
endif
//Mark the Object as finished?
//Pulled Fusions / Defusions / Fadeins will take over this object.
//set udg_Fusion_System_Pointer_Finished[udg_Fusion_System_Pointer_Last] = not (udg_Fusion_Data_Speed[indexData] > 0 or udg_Fusion_Data_FadeIn[indexData] > 0 or defusion)
// Pull together:
if udg_Fusion_Data_Speed[indexData] > 0 then
set udg_Fusion_Object_Effect[indexEnter] = AddSpecialEffect( udg_Fusion_Data_SFX[indexData],x,y )
set udg_Fusion_Object_Type[indexEnter] = UnitFusionTypePull()
//For Pull Real 1 is Speed.
set udg_Fusion_Object_Real1[indexEnter] = udg_Fusion_Data_Speed[indexData] * UnitFusionTimerSpeed()
//For Pull Real2 is ZSpeed
set udg_Fusion_Object_Real2[indexEnter] = udg_Fusion_Data_SpeedZ[indexData] * UnitFusionTimerSpeed()
//Pull orginal units?
if udg_Fusion_Data_Replace[indexData] == 0 then
loop
call SetUnitFacing(udg_Fusion_System_Units[indexCurrent],bj_RADTODEG * Atan2(y - GetUnitY(udg_Fusion_System_Units[indexCurrent]), x - GetUnitX(udg_Fusion_System_Units[indexCurrent])))
call SetUnitVertexColor(udg_Fusion_System_Units[indexCurrent], 255, 255, 255, UnitFusionFade())
call DestroyEffect(AddSpecialEffectTarget( udg_Fusion_Data_SFXUnit[indexData] , udg_Fusion_System_Units[indexCurrent], udg_Fusion_Data_SFXUnitAttacht[indexData] ))
call UnitAddAbility(udg_Fusion_System_Units[indexCurrent], 'Arav' )
if not defusion then
call UnitAddAbility(udg_Fusion_System_Units[indexCurrent] , 'Aloc')
else
call SetUnitInvulnerable(udg_Fusion_System_Units[indexCurrent], true )
call SetUnitPathing (udg_Fusion_System_Units[indexCurrent], false)
endif
call PauseUnit(udg_Fusion_System_Units[indexCurrent], true )
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
else
//Pull substitutes
loop
set x2 =GetUnitX(udg_Fusion_System_Units[indexCurrent])
set y2 =GetUnitY(udg_Fusion_System_Units[indexCurrent])
call DestroyEffect(AddSpecialEffect( udg_Fusion_Data_SFXUnit[indexData],x2,y2 ))
if not defusion then
if udg_Fusion_Data_Remove[indexData] then
//Hide and Pause until pull is finished.
call ShowUnit(udg_Fusion_System_Units[indexCurrent], false)
call PauseUnit(udg_Fusion_System_Units[indexCurrent], true)
else
call KillUnit(udg_Fusion_System_Units[indexCurrent])
endif
else
call SetUnitInvulnerable(udg_Fusion_System_Units[indexCurrent], true )
call PauseUnit(udg_Fusion_System_Units[indexCurrent], true )
call SetUnitPathing (udg_Fusion_System_Units[indexCurrent], false)
call ShowUnit (udg_Fusion_System_Units[indexCurrent], false)
endif
//Substitudes should flying
set u = CreateUnit(GetTriggerPlayer(), udg_Fusion_Data_Replace[indexData], x2, y2, bj_RADTODEG * Atan2(y - y2, x - x2) )
call GroupAddUnit( udg_Fusion_Object_Group[indexEnter], u )
call PauseUnit(u, true )
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
set u = null
endif
call UnitFusionTimerStart()
else
//Instant Fusion
//Spawn Grafic Supstitudes
loop
set x2 =GetUnitX(udg_Fusion_System_Units[indexCurrent])
set y2 =GetUnitY(udg_Fusion_System_Units[indexCurrent])
call DestroyEffect(AddSpecialEffect( udg_Fusion_Data_SFXUnit[indexData],x2,y2 ))
//Spawn extra Units, if wanted.
//that is actually a hidden feature:
//if one does not set speed but uses replaces it will summon units, where the old units were standing.
//This summons have the same duration as the fusion.
if udg_Fusion_Data_Replace[indexData] != 0 then
set u = CreateUnit(GetTriggerPlayer(), udg_Fusion_Data_Replace[indexData], x2, y2, bj_RADTODEG * Atan2(y - y2, x - x2) )
// Timed Life > 0
// Constant + Level * Levelboni
if udg_Fusion_Data_ResultDur[indexData] + ( udg_Fusion_Data_ResultDurPerLevel[indexData]*level) > 0 then
call UnitApplyTimedLife(u, 'BTLF', udg_Fusion_Data_ResultDur[indexData] + ( udg_Fusion_Data_ResultDurPerLevel[indexData]*level))
endif
endif
set indexCurrent = indexCurrent + 1
exitwhen indexCurrent > indexEnd
endloop
call UnitFusionSpawn(indexEnter,x,y)
set u = null
endif
else
call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, UnitFusionErrorDur(), s)
call DisplayTimedTextToPlayer(GetTriggerPlayer(), 0, 0, UnitFusionErrorDur(), ( "---------------" ))
endif
set s = null
set u = null
endfunction
function UnitFusionCasting takes nothing returns nothing
local integer indexData = 0
local integer Id = GetSpellAbilityId()
local location loc
if IsUnitHidden(GetTriggerUnit()) then
return
endif
//Find Casted Skill
loop
exitwhen indexData == udg_Fusion_CreationIndex
if Id == udg_Fusion_Data_Spell[indexData] then
//Has TargetUnit
if GetSpellTargetUnit() != null then
set loc = GetUnitLoc(GetSpellTargetUnit())
else
//Has TargetLoc? not 100% correct, but its pretty unlikly to cast something exactly at 0/0.
if GetSpellTargetX() == 0.0 and GetSpellTargetY() == 0.0 then
set loc = GetUnitLoc(GetTriggerUnit())
else
set loc = GetSpellTargetLoc()
endif
endif
call UnitFusionFuse(indexData, loc)
call RemoveLocation(loc)
set loc = null
return
endif
set indexData = indexData + 1
endloop
endfunction
//On First Execution of this System
//Preload Skills
//Enable Fusion
//Enable Defusion death detecion
//Preload Specialeffects
//Autogenerate missing Atttachmentpoints
//Printout Warnings for using wildcard units but having no FilterWild
function UnitFusionPreload takes nothing returns nothing
local unit u
local integer LoopA = 0
local integer LoopB
local real x = GetRectMaxX (bj_mapInitialPlayableArea)
local real y = GetRectMaxY (bj_mapInitialPlayableArea)
call TriggerClearActions(gg_trg_UnitFusion)
call TriggerAddAction( gg_trg_UnitFusion, function UnitFusionCasting )
call TriggerRegisterAnyUnitEventBJ( gg_trg_UnitFusion, EVENT_PLAYER_UNIT_SPELL_EFFECT )
set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'hfoo', 0,0, 270 )
call UnitAddAbility(u, 'Arav')
call UnitAddAbility(u, 'Aloc')
call RemoveUnit( u )
set udg_Fusion_System_DefusionTrigger = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( udg_Fusion_System_DefusionTrigger, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction(udg_Fusion_System_DefusionTrigger, function UnitDefusionDeath)
set u = null
set udg_Fusion_Item_DefSize = UnitDefusionItemOffset()
//Define Filter for finding Mats.
set udg_Fusion_System_Filter = Condition(function UnitFusionFilterEnum)
//Preload specialeffects
//Autofills Attachmentpoints, if needed
loop
exitwhen LoopA == udg_Fusion_CreationIndex
call DestroyEffect(AddSpecialEffect( udg_Fusion_Data_SFXUnit[LoopA],x,y ))
call DestroyEffect(AddSpecialEffect( udg_Fusion_Data_SFX[LoopA],x,y ))
call DestroyEffect(AddSpecialEffect( udg_Fusion_Data_SFXResult[LoopA],x,y ))
//Use default attachment point?
if udg_Fusion_Data_SFXUnit[LoopA] != "" and StringIsEmpty(udg_Fusion_Data_SFXUnitAttacht[LoopA]) then
set udg_Fusion_Data_SFXUnitAttacht[LoopA] = "chest"
endif
//Use default attachment point?
if udg_Fusion_Data_SFXResult[LoopA] != "" and StringIsEmpty(udg_Fusion_Data_SFXResultAttacht[LoopA]) then
set udg_Fusion_Data_SFXResultAttacht[LoopA] = "origin"
endif
set LoopA = LoopA + 1
endloop
//Printout Warnings for using Wildcards but not using Wildcard Filters.
set LoopA = 0
loop
exitwhen LoopA == udg_Fusion_CreationIndex
set LoopB = udg_Fusion_System_UnitTypesStart[LoopA]
loop
exitwhen LoopB > udg_Fusion_System_UnitTypesEnd[LoopA]
if udg_Fusion_Data_UnitTypes[LoopB] == 0 then
if udg_Fusion_Data_FilterWild[LoopA] == null then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,30,"|cffff0000Warning|r: "+ GetObjectName(udg_Fusion_Data_Spell[LoopA])+" uses Wildcards but has no Wildcard Filter.")
exitwhen true
endif
endif
set LoopB = LoopB + 1
endloop
set LoopA = LoopA + 1
endloop
endfunction
//===============
function InitTrig_UnitFusion takes nothing returns nothing
set gg_trg_UnitFusion = CreateTrigger( )
call TriggerAddAction( gg_trg_UnitFusion, function UnitFusionPreload )
endfunction
Variable | Info |
Fusion_CreationIndex | this is the index on which your Data is saved on. [Fusion_CreationIndex] |
Fusion_Data_AmountOfMergers | tells the System how many Units will fuse. |
Fusion_Data_Spell | is the spell which will use this fusion, they have to be unique inside the system. |
Fusion_Data_Result | is the UnitType one Gains |
Fusion_Data_UnitTypes | starting with [creationindex + 1] are specific Fusion Member Types, if you have not set the same number of specific members as Fusion_Data_AmountOfMergers, your spell will take wildcards. This is the only variable you create this way [Fusion_CreationIndex + 1/2/3/4] |
Fusion_Data_ResultHPAverage | if set the fusion will have only the average % HP/MP of the units having mergered |
Fusion_Data_ResultDur | the fusion will only hold for this amount of seconds. |
Fusion_Data_SFX | this will be player while the Fusion is still building up |
Fusion_Data_SFXResult | this will be displayed on the fusion when finished. using the death animation tag |
Fusion_Data_SFXUnit | this will be displayed at the units having mergered. using the death animation tag |
Fusion_Data_Speed | if set the Merging members will be pulled to the fusion point using this speed |
Fusion_Data_Replace | if you set speed the merging members will not be pulled the spawn each a replace which will be pulled. You can only set 1 Replacetype on each spell |
Fusion_Data_AoE | in which area around the Target Units will be considered for the fusion. |
Fusion_Data_AutoAddCaster | ignoring the AoE and TargetLocation the Caster will be considered for Fusing if he passes the filters. |
Fusion_Data_SpawnAtTargetPoint | if set the fusion will take place at the target, else it will be the average of cordinates of merging units |
Fusion_Data_Remove | the merging Units will removed if set, default they die. |
Fusion_Data_ErrorMsgMain | The Error Message for the MainFilter |
Fusion_Data_FilterMain | The Main Filter units have to pass to be used for a fusion. |
Fusion_Data_SkillGained | This Ability will be added to the Fusion |
Variable | Info |
Fusion_Data_FadeIn | How long it takes to fadeIn, and beeing able to act, in seconds. |
Fusion_Data_FadeInHidden | this variable allows you to keep the FadedIn Unit hidden by that %. |
Fusion_Data_FadeVulnerable | When true the unit can be hit while the process. |
function UnitFusionStartFadeIn
takes unit u, real dur, real hiddenStateAfter, string sfx, boolean immunDuringFade
returns nothing
Variable | Info |
Fusion_Data_DefuseDispellMat | on Defuse take away all buffs from the restored Units |
Fusion_Data_DefuseDistance | how far away the units will be restored from the Defusion, they spawn in an circle form |
Fusion_Data_DefuseSFX | played when defusion triggers, uses death animation tag. |
Fusion_Data_DefusionEXPMulti | how much of gained exp will be transfered to the Merged Units. It shares it equaly between all Units no matter if they are hero or not. 1 = 50% for each in a 2 unit fusion. |
Fusion_Data_DefuseAfterDur | Will defusie, if dies/Removed without killer. |
Fusion_Data_DefuseAfterDurHP | how much % the merged units will have. If you set -1 the take over the fusions one. 1 = 100%; 0 = 0% 0.2 = 20% |
Fusion_Data_DefuseOnKilled | Will defuse, if killed with an killer |
Fusion_Data_DefuseOnKilledHP | how much % the merged units will have. -1 is not working here. 1 = 100%; 0 = 0% |
FusionSaveLoc | is the Location which the waiting Merged Units will be sent to, is set inside UnitFusion Init. |
function UnitDefusion takes unit u, boolean killed, integer indexFusion returns nothing
//This function will defusion an fusion unit.
//call it with index -1, if you don't know the Defusion index.
//call it with null unit if you know the index.
//killed do this Fusion's OnKilled = true / AfterDur = false
Variable | Info |
Fusion_Data_HeroSumLevel | on default the fusionresult beeing an hero will have the average Level of merged heroes, if you set this the Levels will be summed up. |
Fusion_Data_HeroStatsMod | is an integer expecting 3 aviable mods: 0/1/2. 0 default Stats, 1 average Stats of merged Units, 2 sum of Merged Heroes. |
Fusion_Data_HeroAllowBoniStats | ^^influences mod 1 and 2, if true green numbers will be taken in account |
Fusion_Data_DefusionEXPMulti | how much of gained exp will be transfered to the Merged Units. It shares it equaly between all Units no matter if they are hero or not. 1 = 50% for each in a 2 unit fusion. |
Variable | Info |
Fusion_Event | Tells you what happened |
Fusion_Event_Fusion | The Unit beeing Fused/Fadedin/Defused |
Fusion_Event_Group | The merged units. |
Fusion_Event_Source | The Spellcaster who started the Fusion. |
Fusion_Event_SpellData | Which Fusion Data is used. |
Fusion_Event_SpellLevel | The Spell Level this fusion was called. |
Fusion_Event_SpellObject | The Fusion Object Handeling the Fusion/Defusion/Fadein |
Event | Info |
Fusion_Event == 1 | A non-Hero Fusion was summoned |
Fusion_Event == 2 | A Hero Fusion was summoned |
Fusion_Event == 3 | A Fusion Ended Fadein. |
Fusion_Event == -1 | A Fusion defuses. |
Credits