Name | Type | is_array | initial_value |
AfterDamageEvent | real | No | |
AOEDamageEvent | real | No | |
ArenaWalls | destructable | Yes | |
ArenaWalls2 | destructable | Yes | |
CenterPoint | location | No | |
ClearDamageEvent | trigger | No | |
Count | integer | No | |
DAMAGE_FACTOR_BRACERS | real | No | |
DAMAGE_FACTOR_ELUNES | real | No | |
DAMAGE_FACTOR_ETHEREAL | real | No | |
DamageBlockingAbility | abilcode | No | |
DamageEvent | real | No | |
DamageEventAmount | real | No | |
DamageEventAOE | integer | No | |
DamageEventAOEGroup | group | No | |
DamageEventCode | integer | No | |
DamageEventLevel | integer | No | |
DamageEventOverride | boolean | No | |
DamageEventPrevAmt | real | No | |
DamageEventSource | unit | No | |
DamageEventsWasted | integer | No | |
DamageEventTarget | unit | No | |
DamageEventTrigger | trigger | No | |
DamageEventType | integer | No | |
DamageModifierEvent | real | No | |
DamageTypeAttack | integer | No | |
DamageTypeBlocked | integer | No | |
DamageTypeCriticalStrike | integer | No | |
DamageTypeExplosive | integer | No | |
DamageTypeHeal | integer | No | |
DamageTypeHealOverTime | integer | No | |
DamageTypeMagic | integer | No | |
DamageTypeMagicAoe | integer | No | |
DamageTypeMagicOverTime | integer | No | |
DamageTypePhysical | integer | No | |
DamageTypePhysicalAoe | integer | No | |
DamageTypePhysicalOverTime | integer | No | |
DamageTypePure | integer | No | |
DamageTypeReduced | integer | No | |
DmgEvBracers | itemcode | No | |
DmgEvRecursionN | integer | No | |
DmgEvRunning | boolean | No | |
DmgEvStarted | boolean | No | |
DmgEvTimer | timer | No | |
DmgEvTrig | trigger | No | |
EnhancedDamageTarget | unit | No | |
HeroSelectorEvent | real | No | |
HeroSelectorEventIsRandom | boolean | No | |
HeroSelectorEventPlayer | player | No | |
HeroSelectorEventUnit | unit | No | |
HeroSelectorEventUnitCode | unitcode | No | |
HideDamageFrom | boolean | Yes | |
IsDamageSpell | boolean | No | |
IsUnitBeingKnockedBack | boolean | Yes | |
K2DAmphibious | boolean | Yes | |
K2DAngle | real | Yes | |
K2DBounce | boolean | Yes | |
K2DCollision | real | Yes | |
K2DCos | real | Yes | |
K2DCosD1 | real | Yes | |
K2DCosD2 | real | Yes | |
K2DCosH | real | Yes | |
K2DDebrisKiller | unit | No | |
K2DDestRadius | real | Yes | |
K2DDistanceLeft | real | Yes | |
K2DFreeze | boolean | Yes | |
K2DFriction | real | Yes | |
K2DFXModel | string | Yes | |
K2DFXRate | real | Yes | |
K2DFXTimeLeft | real | Yes | |
K2DHeight | real | Yes | |
K2DHeightThreshold | real | Yes | |
K2DImpact | trigger | Yes | |
K2DItem | item | No | |
K2DItemOffset | boolean | No | |
K2DItemsFound | boolean | No | |
K2DKillTrees | boolean | Yes | |
K2DLastX | real | Yes | |
K2DLastY | real | Yes | |
K2DMaxDestRadius | real | No | |
K2DMaxX | real | No | |
K2DMaxY | real | No | |
K2DMinX | real | No | |
K2DMinY | real | No | |
K2DNext | integer | Yes | |
K2DOverride | boolean | Yes | |
K2DPause | boolean | Yes | |
K2DPrev | integer | Yes | |
K2DRadius | integer | Yes | |
K2DRegion | rect | No | |
K2DSimple | boolean | Yes | |
K2DSin | real | Yes | |
K2DSinD1 | real | Yes | |
K2DSinD2 | real | Yes | |
K2DSinH | real | Yes | |
K2DSource | unit | Yes | |
K2DTimeLeft | real | Yes | |
K2DTimeout | real | No | |
K2DTimer | timer | No | |
K2DUnbiasedCollision | boolean | Yes | |
K2DVelocity | real | Yes | |
K2DX | real | No | |
K2DY | real | No | |
Knockback2DAmphibious | boolean | No | |
Knockback2DAngle | real | No | |
Knockback2DBounces | boolean | No | |
Knockback2DCollision | real | No | |
Knockback2DDefaultBounce | boolean | No | |
Knockback2DDefaultDestRadius | real | No | |
Knockback2DDefaultFriction | real | No | |
Knockback2DDefaultFX | string | No | |
Knockback2DDefaultFXRate | real | No | |
Knockback2DDefaultGravity | real | No | |
Knockback2DDefaultKillTrees | boolean | No | |
Knockback2DDefaultPause | boolean | No | |
Knockback2DDestRadius | real | No | |
Knockback2DDistance | real | No | |
Knockback2DFriction | real | No | |
Knockback2DFXRate | real | No | |
Knockback2DGravity | real | No | |
Knockback2DHeight | real | No | |
Knockback2DKillTrees | boolean | No | |
Knockback2DLoopFX | string | No | |
Knockback2DOnImpact | trigger | No | |
Knockback2DOverride | boolean | No | |
Knockback2DPause | boolean | No | |
Knockback2DRobustPathing | integer | No | |
Knockback2DSimple | boolean | No | |
Knockback2DSource | unit | No | |
Knockback2DTime | real | No | |
Knockback2DTreeOrDebris | string | No | |
Knockback2DUnbiasedCollision | boolean | No | |
Knockback2DUnit | unit | No | |
LastDamageHP | real | No | |
LastDmgCode | integer | Yes | |
LastDmgPrevAmount | real | Yes | |
LastDmgPrevType | integer | Yes | |
LastDmgSource | unit | Yes | |
LastDmgTarget | unit | Yes | |
LastDmgValue | real | Yes | |
LastDmgWasSpell | boolean | Yes | |
LocalPlayer | player | No | |
LoopInt | integer | No | |
NextDamageCode | integer | No | |
NextDamageOverride | boolean | No | |
NextDamageType | integer | No | |
onPreDamageCustom | real | No | |
Radians_QuarterPi | real | No | |
Radians_QuarterTurn | real | No | |
Radians_Turn | real | No | |
SpellDamageAbility | abilcode | No | |
temp | string | No | |
TempX | real | No | |
TempY | real | No | |
UnitDamageRegistered | boolean | Yes |
library TeamViewer
//TeamViewer 1.3b
//Plugin for HeroSelector by Tasyen
//It shows the selection of Teams in groups
//Default setup could be suited for 2 team games
//API
// TeamViewerDestroy()
// destroys Frames created by TeamViewer
// TeamViewerInit()
// creates Frames of TeamViewer, normaly should be called at the end of HeroSelectors Init
globals
private boolean ShowNonAllies = true //show non allies
private boolean UpdateNonAllies = true //update the image of non allies when the select or pick
//position when ShowNonAllies = false or when a TeamPos is not set
//how big are the Faces
private real ButtonSize = 0.03
private integer ButtonAlphaSelected = 150
private string ButtonDefaultIcon = "UI\\Widgets\\EscMenu\\Human\\quest-unknown.blp"
private real CategoryButtonSize = 0.015 //size of the CategoryButtons below an players name
private real CategoryButtonGap = 0.002 // space between 2 CategoryButtons
//used when ShowNonAllies = true
//warcraft 3 Teams start with 0
private real array TeamPosX
private real array TeamPosY
private real array TeamPosGapY
private boolean array TeamPosLeft2Right
private trigger ButtonTrigger
private boolean array HasPicked
private framehandle array playerParentFrame
private framehandle array playerFaceButton
private framehandle array playerFaceIcon
private framehandle array playerFaceIconPushed
private framehandle array playerFaceIconDisabled
private framehandle array playerFaceTooltip
private framehandle array playerFaceTooltipBox
private framehandle array playerFaceName
private framehandle array playerFaceColor
private framehandle array LastTeamFaceButton
//2D
private framehandle array playerCategoryIcon
private framehandle array playerCategoryButton
private framehandle array playerCategoryTooltip
private framehandle array playerCategoryTooltipBox
endglobals
function TeamViewerSetup takes nothing returns nothing
set TeamPosX[0] = 0.02
set TeamPosY[0] = 0.5
set TeamPosGapY[0] = 0.015
set TeamPosLeft2Right[0] = true
set TeamPosX[1] = 0.75
set TeamPosY[1] = 0.5
set TeamPosGapY[1] = 0.015
set TeamPosLeft2Right[1] = false
endfunction
// (true) allows includes the player in TeamViewer
private function AllowPlayer takes player p returns boolean
return GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING
endfunction
function TeamViewerDestroy takes nothing returns nothing
local player p
local integer playerIndex = 0
local integer buttonIndex
local integer categoryButtonIndex
call DestroyTrigger(ButtonTrigger)
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
call BlzDestroyFrame(playerFaceButton[playerIndex])
call BlzDestroyFrame(playerFaceName[playerIndex])
call BlzDestroyFrame(playerFaceIcon[playerIndex])
call BlzDestroyFrame(playerFaceIconPushed[playerIndex])
call BlzDestroyFrame(playerFaceIconDisabled[playerIndex])
call BlzDestroyFrame(playerFaceColor[playerIndex])
call BlzDestroyFrame(playerFaceTooltip[playerIndex])
call BlzDestroyFrame(playerFaceTooltipBox[playerIndex])
call BlzDestroyFrame(playerParentFrame[playerIndex])
set playerFaceButton[playerIndex] = null
set playerFaceColor[playerIndex] = null
set playerFaceName[playerIndex] = null
set playerFaceIcon[playerIndex] = null
set playerFaceIconPushed[playerIndex] = null
set playerFaceIconDisabled[playerIndex] = null
set playerFaceTooltip[playerIndex] = null
set buttonIndex = 1
loop
exitwhen buttonIndex > HeroSelector_CategoryButtonCount
set categoryButtonIndex = playerIndex*1000 + buttonIndex
call BlzDestroyFrame(playerCategoryButton[categoryButtonIndex])
call BlzDestroyFrame(playerCategoryIcon[categoryButtonIndex])
call BlzDestroyFrame(playerCategoryTooltip[categoryButtonIndex])
call BlzDestroyFrame(playerCategoryTooltipBox[categoryButtonIndex])
set playerCategoryButton[categoryButtonIndex] = null
set playerCategoryIcon[categoryButtonIndex] = null
set playerCategoryTooltip[categoryButtonIndex] = null
set buttonIndex = buttonIndex + 1
endloop
endif
set playerIndex = playerIndex + 1
endloop
endfunction
private function PosFirstFrame takes framehandle movingFrame, framehandle relativFrame, boolean left2Right returns nothing
if left2Right then
call BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPLEFT, relativFrame, FRAMEPOINT_BOTTOMLEFT, 0, 0)
else
call BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPRIGHT, relativFrame, FRAMEPOINT_BOTTOMRIGHT, 0, 0)
endif
endfunction
private function PosFrame takes framehandle movingFrame, framehandle relativFrame, boolean left2Right returns nothing
if left2Right then
call BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPLEFT, relativFrame, FRAMEPOINT_TOPRIGHT, CategoryButtonGap, 0)
else
call BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPRIGHT, relativFrame, FRAMEPOINT_TOPLEFT, -CategoryButtonGap, 0)
endif
endfunction
private function PlayerFaceClicked takes player clickingPlayer, player targetPlayer returns nothing
//call BJDebugMsg(GetPlayerName(clickingPlayer) + " Clicked " + GetPlayerName(targetPlayer))
endfunction
private function PlayerFaceClickTriggerAction takes nothing returns nothing
local framehandle frame = BlzGetTriggerFrame()
local integer playerIndex = 0
call HeroSelectorframeLoseFocus(frame)
loop
exitwhen playerIndex == GetBJMaxPlayers()
if playerFaceButton[playerIndex] == frame then
call PlayerFaceClicked(GetTriggerPlayer(), Player(playerIndex))
endif
set playerIndex = playerIndex + 1
endloop
set frame = null
endfunction
function TeamViewerInit takes nothing returns nothing
local player p
local integer playerIndex = 0
local integer colorIndex = 0
local integer teamNr
local boolean left2Right = false
local integer createContext
local integer buttonIndex
local integer categoryButtonIndex
set ButtonTrigger = CreateTrigger()
call TriggerAddAction(ButtonTrigger, function PlayerFaceClickTriggerAction)
call TeamViewerSetup()
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if AllowPlayer(p) then
set teamNr = GetPlayerTeam(p)
set createContext = 1000 + playerIndex
set playerParentFrame[playerIndex] = BlzCreateFrame("HeroSelectorTextBox", HeroSelectorBox, 0, createContext)
set playerFaceColor[playerIndex] = BlzCreateFrameByType("BACKDROP", "", playerParentFrame[playerIndex], "", createContext)
call BlzFrameSetLevel(playerParentFrame[playerIndex], -1)
//set playerParentFrame[playerIndex] = BlzCreateFrameByType("FRAME", "TeamViewerPlayerFrame", HeroSelectorBox, "", createContext)
set playerFaceButton[playerIndex] = BlzCreateFrame("HeroSelectorButton", playerParentFrame[playerIndex], 0, createContext)
set playerFaceName[playerIndex] = BlzCreateFrame("HeroSelectorText", playerParentFrame[playerIndex], 0, createContext) // do not the buttons child, else it is affected by Alpha change
set playerFaceIcon[playerIndex] = BlzGetFrameByName("HeroSelectorButtonIcon", createContext)
set playerFaceIconPushed[playerIndex] = BlzGetFrameByName("HeroSelectorButtonIconPushed", createContext)
set playerFaceIconDisabled[playerIndex] = BlzGetFrameByName("HeroSelectorButtonIconDisabled", createContext)
set playerFaceTooltipBox[playerIndex] = BlzCreateFrame("HeroSelectorTextBox", playerFaceButton[playerIndex], 0, createContext)
set playerFaceTooltip[playerIndex] = BlzCreateFrame("HeroSelectorText", playerFaceTooltipBox[playerIndex], 0, createContext)
call BlzTriggerRegisterFrameEvent(ButtonTrigger, playerFaceButton[playerIndex], FRAMEEVENT_CONTROL_CLICK)
call BlzFrameSetPoint(playerFaceTooltipBox[playerIndex], FRAMEPOINT_BOTTOMLEFT, playerFaceTooltip[playerIndex], FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
call BlzFrameSetPoint(playerFaceTooltipBox[playerIndex], FRAMEPOINT_TOPRIGHT, playerFaceTooltip[playerIndex], FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
call BlzFrameSetSize(playerParentFrame[playerIndex], 0.11 + ButtonSize, ButtonSize + CategoryButtonSize + 0.001)
call BlzFrameSetPoint(playerFaceColor[playerIndex], FRAMEPOINT_TOPLEFT, playerParentFrame[playerIndex], FRAMEPOINT_TOPLEFT, 0.005, -0.0035)
call BlzFrameSetPoint(playerFaceColor[playerIndex], FRAMEPOINT_TOPRIGHT, playerParentFrame[playerIndex], FRAMEPOINT_TOPRIGHT, -0.005, -0.0035)
call BlzFrameSetSize(playerFaceColor[playerIndex], 0, 0.003)
set colorIndex = GetHandleId(GetPlayerColor(p))
if colorIndex < 10 then
call BlzFrameSetTexture(playerFaceColor[playerIndex], "ReplaceableTextures\\TeamColor\\TeamColor0"+I2S(colorIndex), 0, false)
else
call BlzFrameSetTexture(playerFaceColor[playerIndex], "ReplaceableTextures\\TeamColor\\TeamColor"+I2S(colorIndex), 0, false)
endif
if ShowNonAllies then
set left2Right = TeamPosLeft2Right[teamNr]
else
set left2Right = TeamPosLeft2Right[0]
endif
call BlzFrameSetSize(playerFaceButton[playerIndex], ButtonSize, ButtonSize)
call BlzFrameSetSize(playerFaceName[playerIndex], 0.105 - ButtonSize, 0.013)
if LastTeamFaceButton[teamNr] == null then
if ShowNonAllies then
call BlzFrameSetAbsPoint(playerFaceButton[playerIndex], FRAMEPOINT_BOTTOMLEFT, TeamPosX[teamNr], TeamPosY[teamNr])
else
call BlzFrameSetAbsPoint(playerFaceButton[playerIndex], FRAMEPOINT_BOTTOMLEFT, TeamPosX[0], TeamPosY[0])
endif
else
call BlzFrameSetPoint(playerFaceButton[playerIndex], FRAMEPOINT_TOPLEFT, LastTeamFaceButton[teamNr], FRAMEPOINT_BOTTOMLEFT, 0, -TeamPosGapY[teamNr])
endif
set LastTeamFaceButton[teamNr] = playerFaceButton[playerIndex]
call PosFrame(playerFaceName[playerIndex], playerFaceButton[playerIndex], left2Right)
if left2Right then
call BlzFrameSetPoint(playerFaceTooltip[playerIndex], FRAMEPOINT_BOTTOMLEFT, playerFaceButton[playerIndex], FRAMEPOINT_TOPLEFT, 0, 0)
call BlzFrameSetPoint(playerParentFrame[playerIndex], FRAMEPOINT_TOPLEFT, playerFaceButton[playerIndex], FRAMEPOINT_TOPLEFT, -0.007, 0.007)
else
call BlzFrameSetPoint(playerFaceTooltip[playerIndex], FRAMEPOINT_BOTTOMRIGHT, playerFaceButton[playerIndex], FRAMEPOINT_TOPRIGHT, 0, 0)
call BlzFrameSetPoint(playerParentFrame[playerIndex], FRAMEPOINT_TOPRIGHT, playerFaceButton[playerIndex], FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
call BlzFrameSetTextAlignment(playerFaceName[playerIndex], TEXT_JUSTIFY_TOP, TEXT_JUSTIFY_RIGHT)
endif
call BlzFrameSetText(playerFaceName[playerIndex], GetPlayerName(p))
call BlzFrameSetTooltip(playerFaceButton[playerIndex], playerFaceTooltipBox[playerIndex])
call BlzFrameSetTexture(playerFaceIcon[playerIndex], ButtonDefaultIcon, 0, true)
call BlzFrameSetTexture(playerFaceIconPushed[playerIndex], ButtonDefaultIcon, 0, true)
//print("Pre HeroSelector.Category")
set buttonIndex = 1
loop
exitwhen buttonIndex > HeroSelector_CategoryButtonCount
set categoryButtonIndex = playerIndex*1000 + buttonIndex
//print("playerIndex",key)
set playerCategoryButton[categoryButtonIndex] = BlzCreateFrameByType("BUTTON", "", playerParentFrame[playerIndex], "", 0)
set playerCategoryIcon[categoryButtonIndex] = BlzCreateFrameByType("BACKDROP", "", playerCategoryButton[categoryButtonIndex], "", 0)
set playerCategoryTooltipBox[categoryButtonIndex] = BlzCreateFrame("HeroSelectorTextBox", playerCategoryButton[categoryButtonIndex], 0, categoryButtonIndex)
set playerCategoryTooltip[categoryButtonIndex] = BlzCreateFrame("HeroSelectorText", playerCategoryTooltipBox[categoryButtonIndex], 0, categoryButtonIndex)
call BlzFrameSetText(playerCategoryTooltip[categoryButtonIndex], BlzFrameGetText(HeroSelector_CategoryTooltipFrame[buttonIndex]))
call BlzFrameSetTooltip( playerCategoryButton[categoryButtonIndex], playerCategoryTooltipBox[categoryButtonIndex])
call BlzFrameSetAllPoints(playerCategoryIcon[categoryButtonIndex], playerCategoryButton[categoryButtonIndex])
call BlzFrameSetPoint(playerCategoryTooltip[categoryButtonIndex], FRAMEPOINT_BOTTOM, playerCategoryButton[categoryButtonIndex], FRAMEPOINT_TOP, 0, 0)
call BlzFrameSetSize( playerCategoryButton[categoryButtonIndex], 0.015, 0.015)
call BlzFrameSetTexture(playerCategoryIcon[categoryButtonIndex], HeroSelector_CategoryTexture[buttonIndex], 0, true)
call BlzFrameSetVisible( playerCategoryButton[categoryButtonIndex], false)
call BlzFrameSetPoint(playerCategoryTooltipBox[categoryButtonIndex], FRAMEPOINT_BOTTOMLEFT, playerCategoryTooltip[categoryButtonIndex], FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
call BlzFrameSetPoint(playerCategoryTooltipBox[categoryButtonIndex], FRAMEPOINT_TOPRIGHT, playerCategoryTooltip[categoryButtonIndex], FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
call BlzFrameSetLevel(playerCategoryTooltipBox[categoryButtonIndex], -1)
set buttonIndex = buttonIndex + 1
endloop
//When showning only allies, hide non allies
if not ShowNonAllies and not IsPlayerAlly(p, GetLocalPlayer()) then
call BlzFrameSetVisible(playerParentFrame[playerIndex], false)
endif
endif
set playerIndex = playerIndex + 1
endloop
endfunction
function TeamViewerButtonSelected takes player p, integer unitCode returns nothing
local integer playerIndex = GetPlayerId(p)
local integer teamNr = GetPlayerTeam(p)
local framehandle prevCategoryButton = null
local integer category = 1
local boolean left2Right = false
local integer unitCodeIndex = LoadInteger(HeroSelector_Hash, unitCode, 0)
local integer unitCategory = HeroSelector_HeroCategory[unitCodeIndex]
local integer categoryButtonIndex
local integer buttonIndex = 1
if not HasPicked[playerIndex] then
if UpdateNonAllies or IsPlayerAlly(GetLocalPlayer(), p) then
call BlzFrameSetText(playerFaceTooltip[playerIndex], GetObjectName(unitCode))
call BlzFrameSetTexture(playerFaceIcon[playerIndex], BlzGetAbilityIcon(unitCode), 0, true)
call BlzFrameSetTexture(playerFaceIconPushed[playerIndex], BlzGetAbilityIcon(unitCode), 0, true)
call BlzFrameSetAlpha(playerFaceButton[playerIndex], ButtonAlphaSelected)
if ShowNonAllies then
set left2Right = TeamPosLeft2Right[teamNr]
else
set left2Right = TeamPosLeft2Right[0]
endif
loop
exitwhen buttonIndex > HeroSelector_CategoryButtonCount
set categoryButtonIndex = playerIndex*1000 + buttonIndex
call BlzFrameClearAllPoints(playerCategoryButton[categoryButtonIndex])
if BlzBitAnd(category, unitCategory) > 0 then
call BlzFrameSetVisible(playerCategoryButton[categoryButtonIndex], true)
if prevCategoryButton == null then
call PosFirstFrame(playerCategoryButton[categoryButtonIndex], playerFaceName[playerIndex], left2Right)
else
call PosFrame(playerCategoryButton[categoryButtonIndex], prevCategoryButton, left2Right)
endif
set prevCategoryButton = playerCategoryButton[categoryButtonIndex]
else
call BlzFrameSetVisible(playerCategoryButton[categoryButtonIndex], false)
endif
set category = category + category
set buttonIndex = buttonIndex + 1
endloop
endif
endif
set prevCategoryButton = null
endfunction
function TeamViewerUnitCreated takes player p, unit u, boolean isRandom returns nothing
local integer playerIndex = GetPlayerId(p)
if UpdateNonAllies or IsPlayerAlly(GetLocalPlayer(), p) then
call BlzFrameSetText(playerFaceTooltip[playerIndex], GetUnitName(u))
call BlzFrameSetTexture(playerFaceIcon[playerIndex], BlzGetAbilityIcon(GetUnitTypeId(u)), 0, true)
call BlzFrameSetTexture(playerFaceIconPushed[playerIndex], BlzGetAbilityIcon(GetUnitTypeId(u)), 0, true)
call BlzFrameSetAlpha(playerFaceButton[playerIndex], 255)
endif
set HasPicked[playerIndex] = true
endfunction
function TeamViewerRepick takes unit u, player p returns nothing
local integer playerIndex = GetPlayerId(p)
if UpdateNonAllies or IsPlayerAlly(GetLocalPlayer(), p) then
call BlzFrameSetText(playerFaceTooltip[playerIndex], "")
call BlzFrameSetTexture(playerFaceIcon[playerIndex], ButtonDefaultIcon, 0, true)
call BlzFrameSetTexture(playerFaceIconPushed[playerIndex], ButtonDefaultIcon, 0, true)
call BlzFrameSetAlpha(playerFaceButton[playerIndex], 255)
endif
set HasPicked[playerIndex] = false
endfunction
endlibrary
library TeamViewer
//TeamViewer 1.3a
//Plugin for HeroSelector by Tasyen
//It shows the selection of Players in cols. When a col is full right of it a new is started
//API
// TeamViewerDestroy()
// destroys Frames created by TeamViewer
// TeamViewerInit()
// creates Frames of TeamViewer, normaly should be called at the end of HeroSelectors Init
globals
//how big are the Faces
private real ButtonSize = 0.03
private integer ButtonAlphaSelected = 150
private string ButtonDefaultIcon = "UI\\Widgets\\EscMenu\\Human\\quest-unknown.blp"
private real CategoryButtonSize = 0.015 //size of the CategoryButtons below an players name
private real CategoryButtonGap = 0.002 // space between 2 CategoryButtons
private real TeamPosX = 0.02
private real TeamPosY = 0.5
private real TeamPosGapY = 0.015
private real TeamPosGapX = 0.015
private integer TeamRowCount = 7
private trigger ButtonTrigger
private boolean array HasPicked
private framehandle array playerParentFrame
private framehandle array playerFaceButton
private framehandle array playerFaceIcon
private framehandle array playerFaceIconPushed
private framehandle array playerFaceIconDisabled
private framehandle array playerFaceTooltip
private framehandle array playerFaceTooltipBox
private framehandle array playerFaceName
private framehandle array playerFaceColor
private framehandle array LastTeamFaceButton
//2D
private framehandle array playerCategoryIcon
private framehandle array playerCategoryButton
private framehandle array playerCategoryTooltip
private framehandle array playerCategoryTooltipBox
endglobals
// (true) allows includes the player in TeamViewer
private function AllowPlayer takes player p returns boolean
return GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING
endfunction
function TeamViewerDestroy takes nothing returns nothing
local player p
local integer playerIndex = 0
local integer buttonIndex
local integer categoryButtonIndex
call DestroyTrigger(ButtonTrigger)
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
call BlzDestroyFrame(playerFaceButton[playerIndex])
call BlzDestroyFrame(playerFaceName[playerIndex])
call BlzDestroyFrame(playerFaceIcon[playerIndex])
call BlzDestroyFrame(playerFaceIconPushed[playerIndex])
call BlzDestroyFrame(playerFaceIconDisabled[playerIndex])
call BlzDestroyFrame(playerFaceColor[playerIndex])
call BlzDestroyFrame(playerFaceTooltip[playerIndex])
call BlzDestroyFrame(playerFaceTooltipBox[playerIndex])
call BlzDestroyFrame(playerParentFrame[playerIndex])
set playerFaceButton[playerIndex] = null
set playerFaceColor[playerIndex] = null
set playerFaceName[playerIndex] = null
set playerFaceIcon[playerIndex] = null
set playerFaceIconPushed[playerIndex] = null
set playerFaceIconDisabled[playerIndex] = null
set playerFaceTooltip[playerIndex] = null
set buttonIndex = 1
loop
exitwhen buttonIndex > HeroSelector_CategoryButtonCount
set categoryButtonIndex = playerIndex*1000 + buttonIndex
call BlzDestroyFrame(playerCategoryButton[categoryButtonIndex])
call BlzDestroyFrame(playerCategoryIcon[categoryButtonIndex])
call BlzDestroyFrame(playerCategoryTooltip[categoryButtonIndex])
call BlzDestroyFrame(playerCategoryTooltipBox[categoryButtonIndex])
set playerCategoryButton[categoryButtonIndex] = null
set playerCategoryIcon[categoryButtonIndex] = null
set playerCategoryTooltip[categoryButtonIndex] = null
set buttonIndex = buttonIndex + 1
endloop
endif
set playerIndex = playerIndex + 1
endloop
endfunction
private function PosFrame takes framehandle movingFrame, framehandle relativFrame returns nothing
call BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPLEFT, relativFrame, FRAMEPOINT_TOPRIGHT, CategoryButtonGap, 0)
endfunction
private function PlayerFaceClicked takes player clickingPlayer, player targetPlayer returns nothing
call BJDebugMsg(GetPlayerName(clickingPlayer) + " Clicked " + GetPlayerName(targetPlayer))
endfunction
private function PlayerFaceClickTriggerAction takes nothing returns nothing
local framehandle frame = BlzGetTriggerFrame()
local integer playerIndex = 0
call HeroSelectorframeLoseFocus(frame)
loop
exitwhen playerIndex == GetBJMaxPlayers()
if playerFaceButton[playerIndex] == frame then
call PlayerFaceClicked(GetTriggerPlayer(), Player(playerIndex))
endif
set playerIndex = playerIndex + 1
endloop
set frame = null
endfunction
function TeamViewerInit takes nothing returns nothing
local player p
local integer playerIndex = 0
local integer colorIndex = 0
local integer createContext
local integer buttonIndex
local integer rowCount = TeamRowCount
local integer created = 0
local integer categoryButtonIndex
set ButtonTrigger = CreateTrigger()
call TriggerAddAction(ButtonTrigger, function PlayerFaceClickTriggerAction)
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if AllowPlayer(p) then
set createContext = 1000 + playerIndex
set created = created + 1
set playerParentFrame[playerIndex] = BlzCreateFrame("HeroSelectorTextBox", HeroSelectorBox, 0, createContext)
set playerFaceColor[playerIndex] = BlzCreateFrameByType("BACKDROP", "", playerParentFrame[playerIndex], "", createContext)
//set playerParentFrame[playerIndex] = BlzCreateFrameByType("FRAME", "TeamViewerPlayerFrame", HeroSelectorBox, "", createContext)
set playerFaceButton[playerIndex] = BlzCreateFrame("HeroSelectorButton", playerParentFrame[playerIndex], 0, createContext)
set playerFaceName[playerIndex] = BlzCreateFrame("HeroSelectorText", playerParentFrame[playerIndex], 0, createContext) // do not the buttons child, else it is affected by Alpha change
set playerFaceIcon[playerIndex] = BlzGetFrameByName("HeroSelectorButtonIcon", createContext)
set playerFaceIconPushed[playerIndex] = BlzGetFrameByName("HeroSelectorButtonIconPushed", createContext)
set playerFaceIconDisabled[playerIndex] = BlzGetFrameByName("HeroSelectorButtonIconDisabled", createContext)
set playerFaceTooltipBox[playerIndex] = BlzCreateFrame("HeroSelectorTextBox", playerFaceButton[playerIndex], 0, createContext)
set playerFaceTooltip[playerIndex] = BlzCreateFrame("HeroSelectorText", playerFaceTooltipBox[playerIndex], 0, createContext)
call BlzTriggerRegisterFrameEvent(ButtonTrigger, playerFaceButton[playerIndex], FRAMEEVENT_CONTROL_CLICK)
call BlzFrameSetPoint(playerFaceTooltipBox[playerIndex], FRAMEPOINT_BOTTOMLEFT, playerFaceTooltip[playerIndex], FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
call BlzFrameSetPoint(playerFaceTooltipBox[playerIndex], FRAMEPOINT_TOPRIGHT, playerFaceTooltip[playerIndex], FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
call BlzFrameSetSize(playerParentFrame[playerIndex], 0.11 + ButtonSize, ButtonSize + CategoryButtonSize + 0.001)
call BlzFrameSetPoint(playerFaceColor[playerIndex], FRAMEPOINT_TOPLEFT, playerParentFrame[playerIndex], FRAMEPOINT_TOPLEFT, 0.005, -0.0035)
call BlzFrameSetPoint(playerFaceColor[playerIndex], FRAMEPOINT_TOPRIGHT, playerParentFrame[playerIndex], FRAMEPOINT_TOPRIGHT, -0.005, -0.0035)
call BlzFrameSetSize(playerFaceColor[playerIndex], 0, 0.003)
set colorIndex = GetHandleId(GetPlayerColor(p))
if colorIndex < 10 then
call BlzFrameSetTexture(playerFaceColor[playerIndex], "ReplaceableTextures\\TeamColor\\TeamColor0"+I2S(colorIndex), 0, false)
else
call BlzFrameSetTexture(playerFaceColor[playerIndex], "ReplaceableTextures\\TeamColor\\TeamColor"+I2S(colorIndex), 0, false)
endif
call BlzFrameSetSize(playerFaceButton[playerIndex], ButtonSize, ButtonSize)
call BlzFrameSetSize(playerFaceName[playerIndex], 0.105 - ButtonSize, 0.013)
if created == 1 then
call BlzFrameSetAbsPoint(playerFaceButton[playerIndex], FRAMEPOINT_BOTTOMLEFT, TeamPosX, TeamPosY)
else
if rowCount <= 0 then
call BlzFrameSetPoint(playerFaceButton[playerIndex], FRAMEPOINT_TOPLEFT, LastTeamFaceButton[created - TeamRowCount], FRAMEPOINT_TOPRIGHT, TeamPosGapX + 0.11, 0)
else
call BlzFrameSetPoint(playerFaceButton[playerIndex], FRAMEPOINT_TOPLEFT, LastTeamFaceButton[created - 1], FRAMEPOINT_BOTTOMLEFT, 0, -TeamPosGapY)
endif
endif
set rowCount = rowCount - 1
set LastTeamFaceButton[created] = playerFaceButton[playerIndex]
call PosFrame(playerFaceName[playerIndex], playerFaceButton[playerIndex])
call BlzFrameSetPoint(playerFaceTooltip[playerIndex], FRAMEPOINT_BOTTOMLEFT, playerFaceButton[playerIndex], FRAMEPOINT_TOPLEFT, 0, 0)
call BlzFrameSetPoint(playerParentFrame[playerIndex], FRAMEPOINT_TOPLEFT, playerFaceButton[playerIndex], FRAMEPOINT_TOPLEFT, -0.007, 0.007)
call BlzFrameSetText(playerFaceName[playerIndex], GetPlayerName(p))
call BlzFrameSetTooltip(playerFaceButton[playerIndex], playerFaceTooltipBox[playerIndex])
call BlzFrameSetTexture(playerFaceIcon[playerIndex], ButtonDefaultIcon, 0, true)
call BlzFrameSetTexture(playerFaceIconPushed[playerIndex], ButtonDefaultIcon, 0, true)
set buttonIndex = 1
loop
exitwhen buttonIndex > HeroSelector_CategoryButtonCount
set categoryButtonIndex = playerIndex*1000 + buttonIndex
set playerCategoryButton[categoryButtonIndex] = BlzCreateFrameByType("BUTTON", "", playerParentFrame[playerIndex], "", 0)
set playerCategoryIcon[categoryButtonIndex] = BlzCreateFrameByType("BACKDROP", "", playerCategoryButton[categoryButtonIndex], "", 0)
set playerCategoryTooltipBox[categoryButtonIndex] = BlzCreateFrame("HeroSelectorTextBox", playerCategoryButton[categoryButtonIndex], 0, categoryButtonIndex)
set playerCategoryTooltip[categoryButtonIndex] = BlzCreateFrame("HeroSelectorText", playerCategoryTooltipBox[categoryButtonIndex], 0, categoryButtonIndex)
call BlzFrameSetText(playerCategoryTooltip[categoryButtonIndex], BlzFrameGetText(HeroSelector_CategoryTooltipFrame[buttonIndex]))
call BlzFrameSetTooltip( playerCategoryButton[categoryButtonIndex], playerCategoryTooltipBox[categoryButtonIndex])
call BlzFrameSetAllPoints(playerCategoryIcon[categoryButtonIndex], playerCategoryButton[categoryButtonIndex])
call BlzFrameSetPoint(playerCategoryTooltip[categoryButtonIndex], FRAMEPOINT_BOTTOM, playerCategoryButton[categoryButtonIndex], FRAMEPOINT_TOP, 0, 0)
call BlzFrameSetSize( playerCategoryButton[categoryButtonIndex], 0.015, 0.015)
call BlzFrameSetTexture(playerCategoryIcon[categoryButtonIndex], HeroSelector_CategoryTexture[buttonIndex], 0, true)
call BlzFrameSetVisible( playerCategoryButton[categoryButtonIndex], false)
call BlzFrameSetPoint(playerCategoryTooltipBox[categoryButtonIndex], FRAMEPOINT_BOTTOMLEFT, playerCategoryTooltip[categoryButtonIndex], FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
call BlzFrameSetPoint(playerCategoryTooltipBox[categoryButtonIndex], FRAMEPOINT_TOPRIGHT, playerCategoryTooltip[categoryButtonIndex], FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
set buttonIndex = buttonIndex + 1
endloop
endif
set playerIndex = playerIndex + 1
endloop
endfunction
function TeamViewerButtonSelected takes player p, integer unitCode returns nothing
local integer playerIndex = GetPlayerId(p)
local framehandle prevCategoryButton = null
local integer category = 1
local integer unitCodeIndex = LoadInteger(HeroSelector_Hash, unitCode, 0)
local integer unitCategory = HeroSelector_HeroCategory[unitCodeIndex]
local integer categoryButtonIndex
local integer buttonIndex = 1
if not HasPicked[playerIndex] then
call BlzFrameSetText(playerFaceTooltip[playerIndex], GetObjectName(unitCode))
call BlzFrameSetTexture(playerFaceIcon[playerIndex], BlzGetAbilityIcon(unitCode), 0, true)
call BlzFrameSetTexture(playerFaceIconPushed[playerIndex], BlzGetAbilityIcon(unitCode), 0, true)
call BlzFrameSetAlpha(playerFaceButton[playerIndex], ButtonAlphaSelected)
loop
exitwhen buttonIndex > HeroSelector_CategoryButtonCount
set categoryButtonIndex = playerIndex*1000 + buttonIndex
call BlzFrameClearAllPoints(playerCategoryButton[categoryButtonIndex])
if BlzBitAnd(category, unitCategory) > 0 then
call BlzFrameSetVisible(playerCategoryButton[categoryButtonIndex], true)
if prevCategoryButton == null then
call BlzFrameSetPoint(playerCategoryButton[categoryButtonIndex], FRAMEPOINT_TOPLEFT, playerFaceName[playerIndex], FRAMEPOINT_BOTTOMLEFT, 0, 0)
else
call PosFrame(playerCategoryButton[categoryButtonIndex], prevCategoryButton)
endif
set prevCategoryButton = playerCategoryButton[categoryButtonIndex]
else
call BlzFrameSetVisible(playerCategoryButton[categoryButtonIndex], false)
endif
set category = category + category
set buttonIndex = buttonIndex + 1
endloop
endif
set prevCategoryButton = null
endfunction
function TeamViewerUnitCreated takes player p, unit u, boolean isRandom returns nothing
local integer playerIndex = GetPlayerId(p)
call BlzFrameSetText(playerFaceTooltip[playerIndex], GetUnitName(u))
call BlzFrameSetTexture(playerFaceIcon[playerIndex], BlzGetAbilityIcon(GetUnitTypeId(u)), 0, true)
call BlzFrameSetTexture(playerFaceIconPushed[playerIndex], BlzGetAbilityIcon(GetUnitTypeId(u)), 0, true)
call BlzFrameSetAlpha(playerFaceButton[playerIndex], 255)
set HasPicked[playerIndex] = true
endfunction
function TeamViewerRepick takes unit u, player p returns nothing
local integer playerIndex = GetPlayerId(p)
call BlzFrameSetText(playerFaceTooltip[playerIndex], "")
call BlzFrameSetTexture(playerFaceIcon[playerIndex], ButtonDefaultIcon, 0, true)
call BlzFrameSetTexture(playerFaceIconPushed[playerIndex], ButtonDefaultIcon, 0, true)
call BlzFrameSetAlpha(playerFaceButton[playerIndex], 255)
set HasPicked[playerIndex] = false
endfunction
endlibrary
library HeroInfo
// 11
//Plugin for by Tasyen
//This Creates a TextDisplay which displays the name and the Extended tooltip of selected units
globals
private framehandle TextDisplay
public framehandle TextDisplayTeam
private real TextAreaSizeX = 0.3
private real TextAreaSizeY = 0.125
private real TextAreaOffsetX = 0.00
private real TextAreaOffsetY = 0.18
private framepointtype TextAreaPoint = FRAMEPOINT_TOPLEFT //pos the Tooltip with which Point
private framepointtype TextAreaRelativePoint = FRAMEPOINT_LEFT //pos the Tooltip to which Point of the Relative
private boolean TextAreaRelativeGame = true //(false) relativ to box, (true) relativ to GameUI
endglobals
function HeroInfoDestroy takes nothing returns nothing
call BlzDestroyFrame(TextDisplay)
set TextDisplay = null
endfunction
function HeroInfoInit takes nothing returns nothing
local string x = UIHeroQuality_GRAY_COLOR + "██████████" + "|r"
local string y = ""
set TextDisplay = BlzCreateFrame("HeroSelectorTextArea", HeroSelectorBox, 0, 0)
set TextDisplayTeam = BlzCreateFrame("HeroSelectorTextArea", HeroSelectorBox, 0, 0)
call BlzFrameSetSize(TextDisplay , TextAreaSizeX, TextAreaSizeY)
call BlzFrameSetVisible(TextDisplay,true)
call BlzFrameSetTextAlignment(TextDisplay,TEXT_JUSTIFY_CENTER,TEXT_JUSTIFY_MIDDLE)
call BlzFrameSetPoint(TextDisplay, TextAreaPoint, BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), TextAreaRelativePoint, TextAreaOffsetX, TextAreaOffsetY)
call BlzFrameSetText(TextDisplay, "Select a Hero")
set y = UIHeroQuality_QUALITY_COLOR + "Spell Damage: " + x + " 0/10|n"
set y = y + UIHeroQuality_QUALITY_COLOR + "Attack Damage: " + x + " 0/10|n"
set y = y + UIHeroQuality_QUALITY_COLOR + "Healing: " + x + " 0/10|n"
set y = y + UIHeroQuality_QUALITY_COLOR + "Survivavility: " + x + " 0/10|n"
set y = y + UIHeroQuality_QUALITY_COLOR + "Movement: " + x + " 0/10|n"
set y = y + UIHeroQuality_QUALITY_COLOR + "Crowd Control: " + x + " 0/10|n"
call BlzFrameAddText(TextDisplay, y)
call BlzFrameSetSize(TextDisplayTeam , TextAreaSizeX, TextAreaSizeY)
call BlzFrameSetVisible(TextDisplayTeam,true)
call BlzFrameSetTextAlignment(TextDisplayTeam,TEXT_JUSTIFY_CENTER,TEXT_JUSTIFY_MIDDLE)
call BlzFrameSetPoint(TextDisplayTeam, FRAMEPOINT_BOTTOMLEFT, BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), TextAreaRelativePoint, TextAreaOffsetX, -0.10)
call BlzFrameSetText(TextDisplayTeam, "Team Composition")
call BlzFrameAddText(TextDisplayTeam, y)
endfunction
function HeroInfoButtonSelected takes player p, integer unitCode returns nothing
local HeroData h = HeroData.GetDataByHeroID(unitCode)
local string s = UIHeroQuality_BuildHeroInfo.evaluate(h,p)
if GetLocalPlayer() == p then
call BlzFrameSetText(TextDisplay, GetObjectName(unitCode))
call BlzFrameAddText(TextDisplay, s)
endif
endfunction
endlibrary
library HeroSelector
//HeroSelector V1.5b
//API
//=====
//HeroSelectorForcePick()
//HeroSelectorForcePickPlayer(player p)
//HeroSelectorForcePickRace(race r)
//HeroSelectorForcePickTeam(integer teamNr)
//HeroSelectorForceRandom()
//HeroSelectorForceRandomRace(race r)
//HeroSelectorForceRandomTeam(integer teamNr)
//HeroSelectorDoPick(player p)
//HeroSelectorDoRandom(player p)
//HeroSelectorShow(boolean flag)
//HeroSelectorShowForce(boolean flag, force f)
//HeroSelectorShowRace(boolean flag, race r)
//HeroSelectorShowPlayer(boolean flag, player p)
//HeroSelectorShowTeam(boolean flag, integer teamNr)
//HeroSelectorEnableBan(boolean flag)
//HeroSelectorEnableBanRace
//HeroSelectorEnableBanTeam
//HeroSelectorEnableBanPlayer
//HeroSelectorEnableBanForce
//HeroSelectorEnablePick(boolean flag)
//HeroSelectorEnablePickForce
//HeroSelectorEnablePickPlayer
//HeroSelectorEnablePickTeam
//HeroSelectorEnablePickRace
//HeroSelectorRollOption(player p, boolean includeRandomOnly, integer exculdedIndex, integer category) returns integer
//HeroSelectorCounterChangeUnitCode(integer unitCode, integer add, player p)
//HeroSelectorEnableButtonIndex(integer unitCode, integer buttonIndex)
//HeroSelectorDisableButtonIndex(integer buttonIndex, integer teamNr)
//HeroSelectorButtonRequirementDone(integer unitCode, player p) returns boolean
//HeroSelectorDeselectButton(integer buttonIndex)
//HeroSelectorAddUnit(integer unitCode, boolean onlyRandom)
//HeroSelectorAddUnitCategory(integer unitCode, integer category)
//HeroSelectorSetUnitCategory(integer unitCode, integer category)
//HeroSelectorSetUnitReqPlayer(integer unitCode, player p)
//HeroSelectorSetUnitReqRace(integer unitCode, race r)
//HeroSelectorSetUnitReqForce(integer unitCode, force f)
//HeroSelectorSetUnitReqTeam(integer unitCode, integer teamNr)
//HeroSelectorSetUnitReqTechLevel(integer unitCode, integer techCode, integer techLevel)
//HeroSelectorSetFrameText(framehandle frame, string text)
//HeroSelectorSetFrameTextPlayer
//HeroSelectorSetFrameTextForce
//HeroSelectorSetFrameTextTeam
//HeroSelectorSetFrameTextRace
//HeroSelectorSetTitleText(string text)
//HeroSelectorSetTitleTextRace
//HeroSelectorSetTitleTextPlayer
//HeroSelectorSetTitleTextForce
//HeroSelectorSetTitleTextTeam
//HeroSelectorSetBanButtonText
//HeroSelectorSetBanButtonTextPlayer
//HeroSelectorSetBanButtonTextRace
//HeroSelectorSetBanButtonTextForce
//HeroSelectorSetBanButtonTextTeam
//HeroSelectorSetRandomButtonText
//HeroSelectorSetRandomButtonTextPlayer
//HeroSelectorSetRandomButtonTextForce
//HeroSelectorSetRandomButtonTextTeam
//HeroSelectorSetRandomButtonTextRace
//HeroSelectorSetAcceptButtonText
//HeroSelectorSetAcceptButtonTextPlayer
//HeroSelectorSetAcceptButtonTextForce
//HeroSelectorSetAcceptButtonTextTeam
//HeroSelectorSetAcceptButtonTextRace
//HeroSelectorAddCategory(string icon, string text) //should only be used before the category Buttons are created
//HeroSelectorGetDisabledIcon(string iconPath)
//HeroSelectorUpdate()
//=====
globals
//Setup
//Box
private string BoxFrameName = "HeroSelectorRaceBox" //this is the background box being created
private real BoxPosX = 0.55
private real BoxPosY = 0.34
private framepointtype BoxPosPoint = FRAMEPOINT_CENTER
private boolean AutoShow = true //(true) shows the box and the Selection at 0.0 for all players
//Unique Picks
private integer UnitCount = 1 //each hero is in total allowed to be picked this amount of times (includes random, repicking allows a hero again).
private integer UnitCountPerTeam = 1 //Each Team is allowed to pick this amount of each unitType
private string ToManyTooltip = "OUTOFSTOCKTOOLTIP"
//Ban
private boolean DelayBanUntilPick = false //(true) baning will not be applied instantly, instead it is applied when HeroSelectorEnablePick is called the next time.
//Category
private boolean CategoryAffectRandom = true //(false) random will not care about selected category
private boolean CategoryMultiSelect = false //(false) deselect other category when selecting one, (true) can selected multiple categories and all heroes having any of them are not filtered.
private real CategorySize = 0.02 //the size of the Category Button
private real CategorySpaceX = 0.0008 //space between 2 category Buttons, it is meant to need only one line of Categoryy Buttons.
private integer CategoryFilteredAlpha = 45 // Alpha value of Heroes being filtered by unselected categories
private boolean CategoryAutoDetectHero = true // Will create and remove added Heroes to read and setup the Category for the primary Attribute Str(4) Agi(8) Int(16)
//Icon path, tooltip Text (tries to localize)
//Indicator
private framehandle IndicatorSelected
private framehandle IndicatorSelectedParent
private string IndicatorPathPick = "UI\\Feedback\\Autocast\\UI-ModalButtonOn.mdl" //this model is used by the indicator during picking
private string IndicatorPathBan = "war3mapImported\\HeroSelectorBan.mdl" //this model is used by the indicator during baning
//Grid
private real SpaceBetweenX = 0.008 //space between 2 buttons in one row
private real SpaceBetweenY = 0.008 //space between 2 rows
private integer ButtonColCount = 8 //amount of buttons in one row
private integer ButtonRowCount = 5 //amount of rows
private boolean ChainedButtons = true //(true) connect to the previous button/ or row, (false) have a offset to the box topLeft in this moving a button has no effect on other buttons.
//Button
private real ButtonSize = 0.036 //size of each button
private boolean ButtonBlendAll = false //(true) when a hero icon uses transparenzy
private string EmptyButtonPath = "UI\\Widgets\\EscMenu\\Human\\blank-background.blp"
//Ban Button
private string BanButtonTextPrefix = "|cffcf2084" //Prefix Text for the Ban Button
private string BanButtonText = "CHAT_ACTION_BAN" //tries to get a Localized String
private real BanButtonSizeX = 0.13
private real BanButtonSizeY = 0.03
private string BanTooltip = "DISALLOWED"
private boolean BanIgnoreRequirment = true // (true) Ban is not restricted by Requirments
//Accept Button
private string AcceptButtonTextPrefix = ""
private string AcceptButtonText = "ACCEPT"
private real AcceptButtonSizeX = 0.085
private real AcceptButtonSizeY = 0.03
private boolean AcceptButtonIsShown = true
private framepointtype AcceptButtonAnchor = FRAMEPOINT_BOTTOMRIGHT //places the Accept button with which Point to the bottom, with right he is at the left
//Random Button
private string RandomButtonTextPrefix = ""
private string RandomButtonText = "RANDOM" //tries Localizing
private real RandomButtonSizeX = 0.085
private real RandomButtonSizeY = 0.03
private boolean RandomButtonIsShown = true
private framepointtype RandomButtonAnchor = FRAMEPOINT_BOTTOMLEFT
private boolean RandomButtonPick = false //(true) pressing the random button will pick the option. (false) pressing the random button will select a button, random only heroes can not be selected, but that does not matter. This weak random and randomonly should not be combined.
//Tooltip
private string TooltipPrefix = "|cffffcc00"
private real TooltipOffsetX = 0
private real TooltipOffsetY = 0
private framepointtype TooltipPoint = FRAMEPOINT_BOTTOM //pos the Tooltip with which Point
private framepointtype TooltipRelativePoint = FRAMEPOINT_TOP //pos the Tooltip to which Point of the Relative
private boolean TooltipRelativIsBox = false //(true) use the box as anchor, (false) use the button as anchor
private string TooltipRequires = "QUESTCOMPONENTS"
//System variables, Do not touch
public integer HeroButtonCount = ButtonRowCount*ButtonColCount
private trigger CategoryClickTrigger = CreateTrigger()
private trigger AcceptButtonTrigger = CreateTrigger()
private trigger BanButtonTrigger = CreateTrigger()
private trigger RandomButtonTrigger = CreateTrigger()
private framehandle BanButton
private framehandle AcceptButton
private framehandle RandomButton
private player array DelayBanPlayer
private integer array DelayBanUnitCode
private integer DelayBanCount = 0
public framehandle array CategoryButton
public framehandle array CategoryIconFrame
public framehandle array CategoryIconPushedFrame
public framehandle array CategoryTooltipFrame
public framehandle array CategoryTooltipFrameBox
public string array CategoryText
public string array CategoryTexture
public string array CategoryTextureDisabled
private integer array CategoryButtonValue
public integer CategoryButtonCount = 0
private integer array UsedTeamNr
private integer UsedTeamNrCount = 0
private integer ButtonHeroCount = 0
private integer array ButtonHeroUnitCode
private integer array HeroTotalCount
public integer array HeroCategory
private integer array HeroRegType
private player array HeroRegPlayer
private force array HeroRegForce
private integer array HeroRegNumber
private integer array HeroRegNumber2
private race array HeroRegRace
private integer HeroCount = 0
private integer array HeroUnitCode
private integer array HeroButtonIndex
public hashtable Hash = InitHashtable()
framehandle HeroSelectorBox
private framehandle HeroSelectorBoxSeperator
private framehandle HeroSelectorBoxTitle
private integer array HeroButtonUnitCode
private integer HeroButtonUnitCodeCount = 0
private framehandle array HeroButtonIcon
private framehandle array HeroButtonIconPushed
private framehandle array HeroButtonIconDisabled
private framehandle array HeroButtonTooltip
private framehandle array HeroButtonTooltipBox
private framehandle array HeroButtonFrame
private trigger HeroButtonClickTrigger = CreateTrigger()
private integer array PlayerSelectedButtonIndex
private integer array PlayerSelectedCategory
private integer array PlayerLastSelectedCategoryIndex
endglobals
private function AutoDetectCategory takes integer unitCode returns integer
local integer value = 0
local unit u
local integer primaryAttribute
if IsUnitIdType(unitCode, UNIT_TYPE_MELEE_ATTACKER) then
set value = 1
elseif IsUnitIdType(unitCode, UNIT_TYPE_RANGED_ATTACKER) then
set value = 2
endif
if CategoryAutoDetectHero and IsUnitIdType(unitCode, UNIT_TYPE_HERO) then
set u = CreateUnit(Player(bj_PLAYER_NEUTRAL_EXTRA), unitCode, 0, 0, 270)
set primaryAttribute = BlzGetUnitIntegerField(u, UNIT_IF_PRIMARY_ATTRIBUTE)
call RemoveUnit(u)
set u = null
if ConvertHeroAttribute(primaryAttribute) == HERO_ATTRIBUTE_STR then
set value = value + 4
elseif ConvertHeroAttribute(primaryAttribute) == HERO_ATTRIBUTE_AGI then
set value = value + 8
elseif ConvertHeroAttribute(primaryAttribute) == HERO_ATTRIBUTE_INT then
set value = value + 16
endif
endif
return value
endfunction
private function GetBorderSize takes nothing returns real
if GetPlayerRace(GetLocalPlayer()) == RACE_HUMAN then
return 0.029
elseif GetPlayerRace(GetLocalPlayer()) == RACE_ORC then
return 0.029
elseif GetPlayerRace(GetLocalPlayer()) == RACE_UNDEAD then
return 0.035
elseif GetPlayerRace(GetLocalPlayer()) == RACE_NIGHTELF then
return 0.035
elseif GetPlayerRace(GetLocalPlayer()) == RACE_DEMON then
return 0.024
else
return 0.0
endif
endfunction
function HeroSelectorDestroy takes nothing returns nothing
local integer buttonIndex = 1
loop
exitwhen buttonIndex > HeroButtonCount
call BlzDestroyFrame(HeroButtonIcon[buttonIndex])
call BlzDestroyFrame(HeroButtonIconDisabled[buttonIndex])
call BlzDestroyFrame(HeroButtonFrame[buttonIndex])
call BlzDestroyFrame(HeroButtonTooltip[buttonIndex])
call BlzDestroyFrame(HeroButtonTooltipBox[buttonIndex])
set HeroButtonTooltip[buttonIndex] = null
set HeroButtonTooltipBox[buttonIndex] = null
set HeroButtonFrame[buttonIndex] = null
set HeroButtonIcon[buttonIndex] = null
set buttonIndex = buttonIndex + 1
endloop
set buttonIndex = 1
loop
exitwhen buttonIndex > CategoryButtonCount
call BlzDestroyFrame(CategoryButton[buttonIndex])
call BlzDestroyFrame(CategoryIconFrame[buttonIndex])
call BlzDestroyFrame(CategoryTooltipFrame[buttonIndex])
call BlzDestroyFrame(CategoryTooltipFrameBox[buttonIndex])
set CategoryButton[buttonIndex] = null
set CategoryIconFrame[buttonIndex] = null
set CategoryTooltipFrame[buttonIndex] = null
set CategoryTooltipFrameBox[buttonIndex] = null
set buttonIndex = buttonIndex + 1
endloop
call BlzDestroyFrame(HeroSelectorBox)
call BlzDestroyFrame(HeroSelectorBoxSeperator)
call BlzDestroyFrame(HeroSelectorBoxTitle)
call BlzDestroyFrame(BanButton)
call BlzDestroyFrame(RandomButton)
call BlzDestroyFrame(AcceptButton)
call BlzDestroyFrame(IndicatorSelected)
call BlzDestroyFrame(IndicatorSelectedParent)
set HeroSelectorBox = null
set HeroSelectorBoxTitle = null
set HeroSelectorBoxSeperator = null
set BanButton = null
set RandomButton = null
set AcceptButton = null
set IndicatorSelected = null
call DestroyTrigger(CategoryClickTrigger)
call DestroyTrigger(BanButtonTrigger)
call DestroyTrigger(RandomButtonTrigger)
call DestroyTrigger(HeroButtonClickTrigger)
set CategoryClickTrigger = null
set BanButtonTrigger = null
set RandomButtonTrigger = null
set HeroButtonClickTrigger = null
endfunction
//=====
//code start
//=====
function HeroSelectorGetDisabledIcon takes string icon returns string
//ReplaceableTextures\CommandButtons\BTNHeroPaladin.tga -> ReplaceableTextures\CommandButtonsDisabled\DISBTNHeroPaladin.tga
if SubString(icon, 34, 35) != "\\" then
return icon
endif //this string has not enough chars return it
//string.len(icon) < 34 then return icon end //this string has not enough chars return it
return SubString(icon, 0, 34) + "Disabled\\DIS" + SubString(icon, 35, StringLength(icon))
endfunction
function HeroSelectorAddCategory takes string icon, string text returns nothing
//adds an data category construct
set CategoryButtonCount = CategoryButtonCount + 1
set CategoryText[CategoryButtonCount] = text
set CategoryTexture[CategoryButtonCount] = icon
set CategoryTextureDisabled[CategoryButtonCount] = HeroSelectorGetDisabledIcon(icon)
if CategoryButtonCount > 1 then
set CategoryButtonValue[CategoryButtonCount] = CategoryButtonValue[CategoryButtonCount - 1]*2
else
set CategoryButtonValue[CategoryButtonCount] = 1
endif
endfunction
function HeroSelectorSetFrameText takes framehandle frame, string text returns nothing
call BlzFrameSetText(frame, text)
endfunction
function HeroSelectorSetFrameTextPlayer takes framehandle frame, string text, player p returns nothing
if GetLocalPlayer() == p then
call BlzFrameSetText(frame, text)
endif
endfunction
function HeroSelectorSetFrameTextTeam takes framehandle frame, string text, integer teamNr returns nothing
if GetPlayerTeam(GetLocalPlayer()) == teamNr then
call BlzFrameSetText(frame, text)
endif
endfunction
function HeroSelectorSetFrameTextRace takes framehandle frame, string text, race r returns nothing
if GetPlayerRace(GetLocalPlayer()) == r then
call BlzFrameSetText(frame, text)
endif
endfunction
function HeroSelectorSetFrameTextForce takes framehandle frame, string text, force f returns nothing
if BlzForceHasPlayer(f, GetLocalPlayer()) then
call BlzFrameSetText(frame, text)
endif
endfunction
function HeroSelectorSetTitleText takes string text returns nothing
call HeroSelectorSetFrameText(HeroSelectorBoxTitle, text)
endfunction
function HeroSelectorSetTitleTextPlayer takes string text, player who returns nothing
call HeroSelectorSetFrameTextPlayer(HeroSelectorBoxTitle, text, who)
endfunction
function HeroSelectorSetTitleTextForce takes string text, force who returns nothing
call HeroSelectorSetFrameTextForce(HeroSelectorBoxTitle, text, who)
endfunction
function HeroSelectorSetTitleTextTeam takes string text, integer who returns nothing
call HeroSelectorSetFrameTextTeam(HeroSelectorBoxTitle, text, who)
endfunction
function HeroSelectorSetTitleTextRace takes string text, race who returns nothing
call HeroSelectorSetFrameTextRace(HeroSelectorBoxTitle, text, who)
endfunction
function HeroSelectorSetBanButtonText takes string text returns nothing
call HeroSelectorSetFrameText(BanButton, text)
endfunction
function HeroSelectorSetBanButtonTextPlayer takes string text, player who returns nothing
call HeroSelectorSetFrameTextPlayer(BanButton, text, who)
endfunction
function HeroSelectorSetBanButtonTextForce takes string text, force who returns nothing
call HeroSelectorSetFrameTextForce(BanButton, text, who)
endfunction
function HeroSelectorSetBanButtonTextTeam takes string text, integer who returns nothing
call HeroSelectorSetFrameTextTeam(BanButton, text, who)
endfunction
function HeroSelectorSetBanButtonTextRace takes string text, race who returns nothing
call HeroSelectorSetFrameTextRace(BanButton, text, who)
endfunction
function HeroSelectorSetRandomButtonText takes string text returns nothing
call HeroSelectorSetFrameText(RandomButton, text)
endfunction
function HeroSelectorSetRandomButtonTextPlayer takes string text, player who returns nothing
call HeroSelectorSetFrameTextPlayer(RandomButton, text, who)
endfunction
function HeroSelectorSetRandomButtonTextForce takes string text, force who returns nothing
call HeroSelectorSetFrameTextForce(RandomButton, text, who)
endfunction
function HeroSelectorSetRandomButtonTextTeam takes string text, integer who returns nothing
call HeroSelectorSetFrameTextTeam(RandomButton, text, who)
endfunction
function HeroSelectorSetRandomButtonTextRace takes string text, race who returns nothing
call HeroSelectorSetFrameTextRace(RandomButton, text, who)
endfunction
function HeroSelectorSetAcceptButtonText takes string text returns nothing
call HeroSelectorSetFrameText(AcceptButton, text)
endfunction
function HeroSelectorSetAcceptButtonTextPlayer takes string text, player who returns nothing
call HeroSelectorSetFrameTextPlayer(AcceptButton, text, who)
endfunction
function HeroSelectorSetAcceptButtonTextForce takes string text, force who returns nothing
call HeroSelectorSetFrameTextForce(AcceptButton, text, who)
endfunction
function HeroSelectorSetAcceptButtonTextTeam takes string text, integer who returns nothing
call HeroSelectorSetFrameTextTeam(AcceptButton, text, who)
endfunction
function HeroSelectorSetAcceptButtonTextRace takes string text, race who returns nothing
call HeroSelectorSetFrameTextRace(AcceptButton, text, who)
endfunction
function HeroSelectorSetUnitCategory takes integer unitCode, integer category returns nothing
local integer index = LoadInteger(Hash, unitCode, 0)
set HeroCategory[index] = category
endfunction
function HeroSelectorAddUnitCategory takes integer unitCode, integer category returns nothing
local integer index = LoadInteger(Hash, unitCode, 0)
set HeroCategory[index] = BlzBitOr(category, HeroCategory[index])
endfunction
function HeroSelectorDeselectButton takes integer buttonIndex returns nothing
local integer playerIndex = 0
if buttonIndex > 0 then
if PlayerSelectedButtonIndex[GetPlayerId(GetLocalPlayer())] == buttonIndex then
call BlzFrameSetVisible(IndicatorSelected, false)
endif
loop
exitwhen playerIndex == GetBJMaxPlayers()
if PlayerSelectedButtonIndex[playerIndex] == buttonIndex then
set PlayerSelectedButtonIndex[playerIndex] = 0
endif
set playerIndex = playerIndex + 1
endloop
else
loop
exitwhen playerIndex == GetBJMaxPlayers()
set PlayerSelectedButtonIndex[playerIndex] = 0
set playerIndex = playerIndex + 1
endloop
call BlzFrameSetVisible(IndicatorSelected, false)
endif
endfunction
function HeroSelectorSetUnitReqRace takes integer unitCode, race r returns nothing
local integer index = LoadInteger(Hash, unitCode, 0)
set HeroRegType[index] = 1
set HeroRegRace[index] = r
endfunction
function HeroSelectorSetUnitReqForce takes integer unitCode, force f returns nothing
local integer index = LoadInteger(Hash, unitCode, 0)
set HeroRegType[index] = 4
set HeroRegForce[index] = f
endfunction
function HeroSelectorSetUnitReqPlayer takes integer unitCode, player p returns nothing
local integer index = LoadInteger(Hash, unitCode, 0)
set HeroRegType[index] = 3
set HeroRegPlayer[index] = p
endfunction
function HeroSelectorSetUnitReqTeam takes integer unitCode, integer teamNr returns nothing
local integer index = LoadInteger(Hash, unitCode, 0)
set HeroRegType[index] = 2
set HeroRegNumber[index] = teamNr
endfunction
function HeroSelectorSetUnitReqTechLevel takes integer unitCode, integer techCode, integer techLevel returns nothing
local integer index = LoadInteger(Hash, unitCode, 0)
set HeroRegType[index] = 5
set HeroRegNumber[index] = techCode
set HeroRegNumber2[index] = techLevel
endfunction
function HeroSelectorButtonRequirementDone takes integer unitCode, player p returns boolean
//true when no requirement is set or the requirment call is successful
local integer index = LoadInteger(Hash, unitCode, 0)
if GetPlayerState(p,PLAYER_STATE_OBSERVER) >= 1 then
return true
endif
if HeroRegType[index] == 0 then //no requirement
return true
elseif HeroRegType[index] == 1 and HeroRegRace[index] == GetPlayerRace(p) then
return true
elseif HeroRegType[index] == 2 and HeroRegNumber[index] == GetPlayerTeam(p) then
return true
elseif HeroRegType[index] == 3 and HeroRegPlayer[index] == p then
return true
elseif HeroRegType[index] == 4 and BlzForceHasPlayer(HeroRegForce[index], p) then
return true
elseif HeroRegType[index] == 5 and GetPlayerTechCount(p, HeroRegNumber[index], true) >= HeroRegNumber2[index] then
return true
endif
return false
endfunction
function HeroSelectorDisableButtonIndex takes integer buttonIndex, integer teamNr returns nothing
local integer playerIndex = 0
if buttonIndex > 0 then
if teamNr == -1 or teamNr == GetPlayerTeam(GetLocalPlayer()) then
call BlzFrameSetEnable(HeroButtonFrame[buttonIndex], false)
endif
if PlayerSelectedButtonIndex[GetPlayerId(GetLocalPlayer())] == buttonIndex then
call BlzFrameSetVisible(IndicatorSelected, false)
endif
//deselect this Button from all players or the team
loop
exitwhen playerIndex == GetBJMaxPlayers()
if (teamNr == -1 or teamNr == GetPlayerTeam(Player(playerIndex))) and PlayerSelectedButtonIndex[playerIndex] == buttonIndex then
set PlayerSelectedButtonIndex[playerIndex] = 0
endif
set playerIndex = playerIndex + 1
endloop
endif
endfunction
function HeroSelectorEnableButtonIndex takes integer unitCode, integer buttonIndex returns nothing
if buttonIndex > 0 then
call BlzFrameSetEnable(HeroButtonFrame[buttonIndex], true and (BanIgnoreRequirment and BlzFrameIsVisible(BanButton) ) or HeroSelectorButtonRequirementDone(unitCode, GetLocalPlayer()))
endif
endfunction
function HeroSelectorUpdateTooltip takes integer unitCode returns nothing
local integer unitCodeIndex = LoadInteger(Hash, unitCode, 0)
local integer buttonIndex = HeroButtonIndex[unitCodeIndex]
local framehandle frame = HeroButtonTooltip[buttonIndex]
local integer teamKey = StringHash("TeamCount"+I2S(GetPlayerTeam(GetLocalPlayer())))
if HeroTotalCount[unitCodeIndex] > UnitCount then
call BlzFrameSetText(frame, TooltipPrefix + GetObjectName(unitCode) + "\n|r(" + GetLocalizedString(BanTooltip) + ")")
else
if HeroTotalCount[unitCodeIndex] == UnitCount or LoadInteger(Hash, unitCode, teamKey) >= UnitCountPerTeam then
call BlzFrameSetText(frame, TooltipPrefix + GetObjectName(unitCode) + "\n|r(" + GetLocalizedString(ToManyTooltip) + ")")
elseif not HeroSelectorButtonRequirementDone(unitCode, GetLocalPlayer()) then
if GetPlayerRace(GetLocalPlayer()) == RACE_ORC then
call BlzFrameSetText(frame, TooltipPrefix + GetObjectName(unitCode) + "\n|r(Alliance Team)")
else
call BlzFrameSetText(frame, TooltipPrefix + GetObjectName(unitCode) + "\n|r(Horde Team)")
endif
else
call BlzFrameSetText(frame, TooltipPrefix + GetObjectName(unitCode))
endif
endif
endfunction
function HeroSelectorCounterChangeUnitCode takes integer unitCode, integer add, player p returns nothing
local integer unitCodeIndex = LoadInteger(Hash, unitCode, 0)
local integer buttonIndex = HeroButtonIndex[unitCodeIndex]
local integer teamNr = GetPlayerTeam(p)
local integer teamKey = StringHash("TeamCount"+I2S(teamNr))
set HeroTotalCount[unitCodeIndex] = HeroTotalCount[unitCodeIndex] + add
call SaveInteger(Hash, unitCode, teamKey, LoadInteger(Hash, unitCode, teamKey) + add)
if HeroTotalCount[unitCodeIndex] >= UnitCount then
//disable for all
call HeroSelectorDisableButtonIndex(buttonIndex, -1)
else
//enable for all
call HeroSelectorEnableButtonIndex(unitCode, buttonIndex)
if LoadInteger(Hash, unitCode, teamKey) >= UnitCountPerTeam then
//disable for this team
call HeroSelectorDisableButtonIndex(buttonIndex, teamNr)
endif
endif
call HeroSelectorUpdateTooltip(unitCode)
endfunction
function HeroSelectorRollOption takes player p, boolean includeRandomOnly, integer exculdedIndex, integer category returns integer
local integer teamNr = GetPlayerTeam(p)
local integer array options
local integer optionCount = 0
local integer teamKey = StringHash("TeamCount"+I2S(teamNr))
local boolean allowed
local integer index = 1
local integer unitCode
local integer unitCodeIndex
/*if p == Player(7) then
return 'HGR1'
endif*/
loop
exitwhen index > HeroCount
set unitCode = HeroUnitCode[index]
set unitCodeIndex = LoadInteger(Hash, unitCode, 0)
set allowed = true
//total limited reached?
if HeroTotalCount[unitCodeIndex] >= UnitCount then
set allowed = false
//print(GetObjectName(unitCode))
//print("rejected total limit")
endif
//team limited reached?
if allowed and LoadInteger(Hash, unitCode, teamKey) >= UnitCountPerTeam then
//print(GetObjectName(unitCode))
//print("rejected team limit")
set allowed = false
endif
//allow randomOnly?
if allowed and not includeRandomOnly and HeroButtonIndex[unitCodeIndex] == 0 then
//print(GetObjectName(unitCode))
//print("rejected random only")
set allowed = false
endif
//this index is excluded? This can make sure you get another button.
if allowed and HeroButtonIndex[unitCodeIndex] > 0 and HeroButtonIndex[unitCodeIndex] == exculdedIndex then
//print(GetObjectName(unitCode))
//print("rejected exclude")
set allowed = false
endif
//fullfills the requirement?
if allowed and not HeroSelectorButtonRequirementDone(unitCode, p) then
//print(GetObjectName(unitCode))
//print("rejected requirement")
set allowed = false
endif
//when having an given an category only allow options having that category atleast partly
if allowed and category > 0 and BlzBitAnd(category, HeroCategory[unitCodeIndex]) == 0 then
//print(GetObjectName(unitCode))
//print(" rejected category", category, HeroSelector.UnitData[unitCode].Category)
set allowed = false
endif
if allowed then
set optionCount = optionCount + 1
set options[optionCount] = unitCode
endif
set index = index + 1
endloop
//nothing is allwoed?
if optionCount == 0 then
return 0
else
return options[GetRandomInt(1, optionCount)]
endif
endfunction
function HeroSelectorEnablePickDelayBanAction takes nothing returns nothing
loop
exitwhen DelayBanCount <= 0
call HeroSelectorCounterChangeUnitCode(DelayBanUnitCode[DelayBanCount], UnitCount + 1, DelayBanPlayer[DelayBanCount])
set DelayBanCount = DelayBanCount - 1
endloop
endfunction
function HeroSelectorUpdate takes nothing returns nothing
local integer buttonIndex = 1
local integer unitCodeIndex
local integer teamNr
local integer teamIndex = 0
local integer teamKey
loop
exitwhen buttonIndex > HeroButtonCount
//have data for this button?
if HeroButtonUnitCode[buttonIndex] > 0 then
set unitCodeIndex = LoadInteger(Hash, HeroButtonUnitCode[buttonIndex],0)
if HeroTotalCount[unitCodeIndex] >= UnitCount then
//disable for all
call HeroSelectorDisableButtonIndex(buttonIndex, -1)
else
//enable for all
call HeroSelectorEnableButtonIndex(HeroButtonUnitCode[buttonIndex], buttonIndex)
set teamIndex = 0
loop
exitwhen teamIndex > UsedTeamNrCount
set teamNr = UsedTeamNr[teamIndex]
set teamKey = StringHash("TeamCount"+I2S(teamNr))
if LoadInteger(Hash, HeroButtonUnitCode[buttonIndex], teamKey) >= UnitCountPerTeam then
//disable for this team
call HeroSelectorDisableButtonIndex(buttonIndex, teamNr)
endif
set teamIndex = teamIndex + 1
endloop
endif
call BlzFrameSetTexture(HeroButtonIcon[buttonIndex], BlzGetAbilityIcon(HeroButtonUnitCode[buttonIndex]), 0, ButtonBlendAll)
call BlzFrameSetTexture(HeroButtonIconPushed[buttonIndex], BlzGetAbilityIcon(HeroButtonUnitCode[buttonIndex]), 0, ButtonBlendAll)
call BlzFrameSetTexture(HeroButtonIconDisabled[buttonIndex], HeroSelectorGetDisabledIcon(BlzGetAbilityIcon(HeroButtonUnitCode[buttonIndex])), 0, ButtonBlendAll)
//call BlzFrameSetText(HeroButtonTooltip[buttonIndex], TooltipPrefix + GetObjectName(HeroButtonUnitCode[buttonIndex]))
call HeroSelectorUpdateTooltip(HeroButtonUnitCode[buttonIndex])
else
//no, make it unclickable and empty
call BlzFrameSetEnable(HeroButtonFrame[buttonIndex], false)
call BlzFrameSetTexture(HeroButtonIcon[buttonIndex], EmptyButtonPath, 0, true)
call BlzFrameSetTexture(HeroButtonIconPushed[buttonIndex], EmptyButtonPath, 0, true)
call BlzFrameSetTexture(HeroButtonIconDisabled[buttonIndex], EmptyButtonPath, 0, true)
endif
set buttonIndex = buttonIndex + 1
endloop
endfunction
function HeroSelectorEnablePickAction takes boolean flag returns nothing
call BlzFrameSetVisible(AcceptButton, true and AcceptButtonIsShown)
call BlzFrameSetVisible(RandomButton, true and RandomButtonIsShown)
call BlzFrameSetVisible(BanButton, false)
call BlzFrameSetEnable(AcceptButton, flag)
call BlzFrameSetEnable(RandomButton, flag)
call BlzFrameSetModel(IndicatorSelected, IndicatorPathPick, 0)
if BanIgnoreRequirment then
call HeroSelectorUpdate()
endif
endfunction
function HeroSelectorEnablePick takes boolean flag returns nothing
call HeroSelectorEnablePickDelayBanAction()
call HeroSelectorEnablePickAction(flag)
endfunction
function HeroSelectorEnablePickPlayer takes boolean flag, player p returns nothing
call HeroSelectorEnablePickDelayBanAction()
if GetLocalPlayer() == p then
call HeroSelectorEnablePickAction(flag)
endif
endfunction
function HeroSelectorEnablePickTeam takes boolean flag, integer teamNr returns nothing
call HeroSelectorEnablePickDelayBanAction()
if GetPlayerTeam(GetLocalPlayer()) == teamNr then
call HeroSelectorEnablePickAction(flag)
endif
endfunction
function HeroSelectorEnablePickRace takes boolean flag, race r returns nothing
call HeroSelectorEnablePickDelayBanAction()
if GetPlayerRace(GetLocalPlayer()) == r then
call HeroSelectorEnablePickAction(flag)
endif
endfunction
function HeroSelectorEnablePickForce takes boolean flag, force f returns nothing
call HeroSelectorEnablePickDelayBanAction()
if BlzForceHasPlayer(f, GetLocalPlayer()) then
call HeroSelectorEnablePickAction(flag)
endif
endfunction
function HeroSelectorEnableBanPlayerAction takes boolean flag returns nothing
call BlzFrameSetVisible(AcceptButton, false)
call BlzFrameSetVisible(RandomButton, false)
call BlzFrameSetVisible(BanButton, true)
call BlzFrameSetEnable(BanButton, flag)
call BlzFrameSetModel(IndicatorSelected, IndicatorPathBan, 0)
if BanIgnoreRequirment then
call HeroSelectorUpdate()
endif
endfunction
function HeroSelectorEnableBanPlayer takes boolean flag, player p returns nothing
if GetLocalPlayer() == p then
call HeroSelectorEnableBanPlayerAction(flag)
endif
endfunction
function HeroSelectorEnableBanForce takes boolean flag, force f returns nothing
if BlzForceHasPlayer(f, GetLocalPlayer()) then
call HeroSelectorEnableBanPlayerAction(flag)
endif
endfunction
function HeroSelectorEnableBanTeam takes boolean flag, integer teamNr returns nothing
if GetPlayerTeam(GetLocalPlayer()) == teamNr then
call HeroSelectorEnableBanPlayerAction(flag)
endif
endfunction
function HeroSelectorEnableBanRace takes boolean flag, race r returns nothing
if GetPlayerRace(GetLocalPlayer()) == r then
call HeroSelectorEnableBanPlayerAction(flag)
endif
endfunction
function HeroSelectorEnableBan takes boolean flag returns nothing
call HeroSelectorEnableBanPlayerAction(flag)
endfunction
function HeroSelectorframeLoseFocus takes framehandle frame returns nothing
if BlzFrameGetEnable(frame) then
call BlzFrameSetEnable(frame, false)
call BlzFrameSetEnable(frame, true)
endif
endfunction
function HeroSelectorShowFramePlayer takes framehandle frame, boolean flag, player p returns nothing
if GetLocalPlayer() == p then
call BlzFrameSetVisible(frame, flag)
endif
endfunction
function HeroSelectorShowFrameForce takes framehandle frame, boolean flag, force f returns nothing
if BlzForceHasPlayer(f, GetLocalPlayer()) then
call BlzFrameSetVisible(frame, flag)
endif
endfunction
function HeroSelectorShowFrameTeam takes framehandle frame, boolean flag, integer teamNr returns nothing
if GetPlayerTeam(GetLocalPlayer()) == teamNr then
call BlzFrameSetVisible(frame, flag)
endif
endfunction
function HeroSelectorShowFrameRace takes framehandle frame, boolean flag, race r returns nothing
if GetPlayerRace(GetLocalPlayer()) == r then
call BlzFrameSetVisible(frame, flag)
endif
endfunction
function HeroSelectorShowPlayer takes boolean flag, player who returns nothing
call HeroSelectorShowFramePlayer(HeroSelectorBox, flag, who)
endfunction
function HeroSelectorShowTeam takes boolean flag, integer who returns nothing
call HeroSelectorShowFrameTeam(HeroSelectorBox, flag, who)
endfunction
function HeroSelectorShowRace takes boolean flag, race who returns nothing
call HeroSelectorShowFrameRace(HeroSelectorBox, flag, who)
endfunction
function HeroSelectorShowForce takes boolean flag, force who returns nothing
call HeroSelectorShowFrameForce(HeroSelectorBox, flag, who)
endfunction
function HeroSelectorShow takes boolean flag returns nothing
call BlzFrameSetVisible(HeroSelectorBox, flag)
endfunction
function HeroSelectorAddUnit takes integer unitCode, boolean onlyRandom returns nothing
//no unitCode => empty field
if unitCode == 0 then
set ButtonHeroCount = ButtonHeroCount + 1
else
//Such an object Exist? not unique?
if GetObjectName(unitCode) == "" or HaveSavedBoolean(Hash, unitCode, 0) then
return
endif
set HeroCount = HeroCount + 1
set HeroUnitCode[HeroCount] = unitCode
call SaveBoolean(Hash, unitCode, 0, true)
call SaveInteger(Hash, unitCode, 0, HeroCount)
set HeroCategory[HeroCount] = AutoDetectCategory(unitCode)
if not onlyRandom then
set ButtonHeroCount = ButtonHeroCount + 1
set HeroButtonIndex[HeroCount] = ButtonHeroCount
set ButtonHeroUnitCode[ButtonHeroCount] = unitCode
endif
endif
endfunction
function HeroSelectorDoRandom takes player p returns nothing
local integer category = 0
local integer unitCode
local unit u
if CategoryAffectRandom then
set category = PlayerSelectedCategory[GetPlayerId(p)]
endif
set unitCode = HeroSelectorRollOption(p, true, 0, category)
if unitCode == 0 then
return
endif
//call TeamViewerButtonSelected.evaluate(p, unitCode)
set u = CreateUnit(p, unitCode, 0, 0, 0)
call HeroSelectorCounterChangeUnitCode(unitCode, 1, p)
set udg_HeroSelectorEventUnit = u
set udg_HeroSelectorEventIsRandom = true
set udg_HeroSelectorEventUnitCode = unitCode
set udg_HeroSelectorEventPlayer = p
set udg_HeroSelectorEvent = 0.0
set udg_HeroSelectorEvent = 1.0
set udg_HeroSelectorEvent = 0.0
set u = null
endfunction
function HeroSelectorDoPick takes player p returns boolean
local integer unitCode
local unit u
//pick what currently is selected, returns true on success returns false when something went wrong,
local integer buttonIndex = PlayerSelectedButtonIndex[GetPlayerId(p)]
if buttonIndex <= 0 then
return false
endif //reject nothing selected
set unitCode = HeroButtonUnitCode[buttonIndex]
if not HeroSelectorButtonRequirementDone(unitCode, p) then
return false
endif //reject requirment not fullfilled
set u = CreateUnit(p, unitCode, 0, 0, 0)
call HeroSelectorCounterChangeUnitCode(unitCode, 1, p)
set udg_HeroSelectorEventUnit = u
set udg_HeroSelectorEventIsRandom = false
set udg_HeroSelectorEventUnitCode = unitCode
set udg_HeroSelectorEventPlayer = p
set udg_HeroSelectorEvent = 0.0
set udg_HeroSelectorEvent = 1.0
set udg_HeroSelectorEvent = 0.0
set u = null
return true
endfunction
function HeroSelectorForceRandom takes nothing returns nothing
//this is a wrapper for doRandom allowing different dataTypes
local player p
local integer playerIndex = 0
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
call HeroSelectorDoRandom(p)
endif
set playerIndex = playerIndex + 1
endloop
set p = null
endfunction
function HeroSelectorForceRandomTeam takes integer who returns nothing
//this is a wrapper for doRandom allowing different dataTypes
local player p
local integer playerIndex = 0
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
if GetPlayerTeam(p) == who then
call HeroSelectorDoRandom(p)
endif
endif
set playerIndex = playerIndex + 1
endloop
set p = null
endfunction
function HeroSelectorForceRandomRace takes race who returns nothing
//this is a wrapper for doRandom allowing different dataTypes
local player p
local integer playerIndex = 0
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
if GetPlayerRace(p) == who then
call HeroSelectorDoRandom(p)
endif
endif
set playerIndex = playerIndex + 1
endloop
set p = null
endfunction
function HeroSelectorForcePick takes nothing returns nothing
//this is a wrapper for doRandom allowing different dataTypes
local player p
local integer playerIndex = 0
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
if not HeroSelectorDoPick(p) then
call HeroSelectorDoRandom(p)
endif
endif
set playerIndex = playerIndex + 1
endloop
endfunction
function HeroSelectorForcePickTeam takes integer who returns nothing
//this is a wrapper for doRandom allowing different dataTypes
local player p
local integer playerIndex = 0
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
if GetPlayerTeam(p) == who then
if not HeroSelectorDoPick(p) then
call HeroSelectorDoRandom(p)
endif
endif
endif
set playerIndex = playerIndex + 1
endloop
endfunction
function HeroSelectorForcePickRace takes race r returns nothing
//this is a wrapper for doRandom allowing different dataTypes
local player p
local integer playerIndex = 0
loop
exitwhen playerIndex == GetBJMaxPlayers()
set p = Player(playerIndex)
if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING then
if GetPlayerRace(p) == r then
if not HeroSelectorDoPick(p) then
call HeroSelectorDoRandom(p)
endif
endif
endif
set playerIndex = playerIndex + 1
endloop
endfunction
function HeroSelectorForcePickPlayer takes player p returns nothing
if not HeroSelectorDoPick(p) then
call HeroSelectorDoRandom(p)
endif
endfunction
function HeroSelectorActionPressHeroButton takes nothing returns nothing
local framehandle fh = BlzGetTriggerFrame()
local player p = GetTriggerPlayer()
local integer buttonIndex = LoadInteger(Hash, GetHandleId(fh), 0)
local integer unitCode = HeroButtonUnitCode[buttonIndex]
local integer lastIndex = PlayerSelectedButtonIndex[GetPlayerId(p)]
set PlayerSelectedButtonIndex[GetPlayerId(p)] = buttonIndex
call HeroSelectorframeLoseFocus(BlzGetTriggerFrame())
if GetLocalPlayer() == p then
call BlzFrameSetVisible(IndicatorSelected, true)
call BlzFrameSetPoint(IndicatorSelected, FRAMEPOINT_TOPLEFT, fh, FRAMEPOINT_TOPLEFT, -0.001, 0.001)
call BlzFrameSetPoint(IndicatorSelected, FRAMEPOINT_BOTTOMRIGHT, fh, FRAMEPOINT_BOTTOMRIGHT, -0.0012, -0.0016)
endif
if Players[GetPlayerId(p)].hero == 0 then
set udg_HeroSelectorEventUnit = null
set udg_HeroSelectorEventUnitCode = unitCode
set udg_HeroSelectorEventPlayer = p
set udg_HeroSelectorEvent = 0.0
set udg_HeroSelectorEvent = 2.0
set udg_HeroSelectorEvent = 0.0
endif
set fh = null
set p = null
endfunction
function HeroSelectorActionRandomButton takes nothing returns nothing
local player p = GetTriggerPlayer()
local integer playerIndex = GetPlayerId(p)
local integer unitCode
local integer unitCodeIndex
local integer buttonIndex
call HeroSelectorframeLoseFocus(BlzGetTriggerFrame())
if RandomButtonPick then
call HeroSelectorDoRandom(p)
else
set unitCode = HeroSelectorRollOption(p, false, PlayerSelectedButtonIndex[playerIndex], PlayerSelectedCategory[playerIndex])
if unitCode > 0 and GetLocalPlayer() == p then
set unitCodeIndex = LoadInteger(Hash, unitCode, 0)
set buttonIndex = HeroButtonIndex[unitCodeIndex]
call BlzFrameClick(HeroButtonFrame[buttonIndex])
endif
endif
set p = null
endfunction
function HeroSelectorActionAcceptButton takes nothing returns nothing
call HeroSelectorframeLoseFocus(BlzGetTriggerFrame())
call HeroSelectorDoPick(GetTriggerPlayer())
endfunction
function HeroSelectorActionBanButton takes nothing returns nothing
local player p = GetTriggerPlayer()
local integer playerIndex = GetPlayerId(p)
local integer buttonIndex = PlayerSelectedButtonIndex[playerIndex]
local integer unitCode = HeroButtonUnitCode[buttonIndex]
call HeroSelectorframeLoseFocus(BlzGetTriggerFrame())
if buttonIndex > 0 then
if not DelayBanUntilPick then
call HeroSelectorCounterChangeUnitCode(unitCode, UnitCount + 1, p)
else
set DelayBanCount = DelayBanCount + 1
set DelayBanPlayer[DelayBanCount] = p
set DelayBanUnitCode[DelayBanCount] = unitCode
endif
set udg_HeroSelectorEventUnit = null
set udg_HeroSelectorEventUnitCode = unitCode
set udg_HeroSelectorEventPlayer = p
set udg_HeroSelectorEvent = 0.0
set udg_HeroSelectorEvent = 3.0
set udg_HeroSelectorEvent = 0.0
endif
set p = null
endfunction
function HeroSelectorActionCategoryButton takes nothing returns nothing
local integer buttonIndex
local framehandle fh = BlzGetTriggerFrame()
local integer categoryIndex = LoadInteger(Hash, GetHandleId(fh), 0)
local integer lastCategoryIndex
local player p = GetTriggerPlayer()
local integer playerIndex = GetPlayerId(p)
local integer unitCodeIndex
call HeroSelectorframeLoseFocus(fh)
//has this category already?
if BlzBitAnd(PlayerSelectedCategory[playerIndex], CategoryButtonValue[categoryIndex]) != 0 then
//yes, unable
set PlayerSelectedCategory[playerIndex] = PlayerSelectedCategory[playerIndex] - CategoryButtonValue[categoryIndex]
if GetLocalPlayer() == p then
call BlzFrameSetTexture(CategoryIconFrame[categoryIndex], CategoryTextureDisabled[categoryIndex], 0, true)
call BlzFrameSetTexture(CategoryIconPushedFrame[categoryIndex], CategoryTextureDisabled[categoryIndex], 0, true)
endif
else
if not CategoryMultiSelect and PlayerSelectedCategory[playerIndex] != 0 then
set lastCategoryIndex = PlayerLastSelectedCategoryIndex[playerIndex]
call BlzFrameSetTexture(CategoryIconFrame[lastCategoryIndex], CategoryTextureDisabled[lastCategoryIndex], 0, true)
call BlzFrameSetTexture(CategoryIconPushedFrame[lastCategoryIndex], CategoryTextureDisabled[lastCategoryIndex], 0, true)
set PlayerSelectedCategory[playerIndex] = 0
endif
//no, enable
set PlayerSelectedCategory[playerIndex] = PlayerSelectedCategory[playerIndex] + CategoryButtonValue[categoryIndex]
if GetLocalPlayer() == p then
call BlzFrameSetTexture(CategoryIconFrame[categoryIndex], CategoryTexture[categoryIndex], 0, true)
call BlzFrameSetTexture(CategoryIconPushedFrame[categoryIndex], CategoryTexture[categoryIndex], 0, true)
endif
set PlayerLastSelectedCategoryIndex[playerIndex] = categoryIndex
endif
if GetLocalPlayer() == p then
//update all buttons
//buttons not having at least 1 selected category becomes partly transparent
set buttonIndex = 1
loop
exitwhen buttonIndex > HeroButtonCount
if HeroButtonUnitCode[buttonIndex] > 0 then
set unitCodeIndex = LoadInteger(Hash, HeroButtonUnitCode[buttonIndex],0)
if PlayerSelectedCategory[playerIndex] == 0 or BlzBitAnd(HeroCategory[unitCodeIndex], PlayerSelectedCategory[playerIndex]) > 0 then
call BlzFrameSetAlpha(HeroButtonFrame[buttonIndex], 255)
else
call BlzFrameSetAlpha(HeroButtonFrame[buttonIndex], CategoryFilteredAlpha)
endif
endif
set buttonIndex = buttonIndex + 1
endloop
endif
set fh = null
set p = null
endfunction
function HeroSelectorInit takes nothing returns nothing
local boolean loaded = BlzLoadTOCFile("war3mapImported\\HeroSelector.toc") //ex/import also "HeroSelector.fdf"
local integer buttonIndex
local real titleSize = 0.015
local real borderSize = GetBorderSize()
local integer colCount = ButtonColCount
local integer rowCount = ButtonRowCount
local framehandle box = BlzCreateFrame(BoxFrameName, BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
local framehandle boxBottom = BlzCreateFrame("HeroSelectorRaceTopBox", box, 0, 0)
local integer rowRemaining = colCount
local real y = -borderSize - titleSize - 0.0125 - CategorySize
local real x = borderSize
local integer playerIndex = 0
local integer teamIndexLoop
local integer teamNr
call ExecuteFunc("HeroSelectorAction_InitHeroes")
//find all Teams in usage
loop
exitwhen playerIndex == GetBJMaxPlayers()
set teamNr = GetPlayerTeam(Player(playerIndex))
if teamNr != -1 then
set teamIndexLoop = UsedTeamNrCount
loop
exitwhen teamIndexLoop == 0
exitwhen UsedTeamNr[teamIndexLoop] == teamNr
set teamIndexLoop = teamIndexLoop - 1
endloop
if teamIndexLoop == 0 then
set UsedTeamNrCount = UsedTeamNrCount + 1
set UsedTeamNr[UsedTeamNrCount] = teamNr
endif
endif
set playerIndex = playerIndex + 1
endloop
call TriggerAddAction(HeroButtonClickTrigger, function HeroSelectorActionPressHeroButton)
set HeroSelectorBoxTitle = BlzCreateFrame("HeroSelectorTitle", box, 0, 0)
set IndicatorSelectedParent = BlzCreateFrameByType("BUTTON", "MyHeroIndikatorParent", box, "", 0)
call BlzFrameSetLevel(IndicatorSelectedParent, -1)
set IndicatorSelected = BlzCreateFrameByType("SPRITE", "MyHeroIndikator", IndicatorSelectedParent, "", 0)
set HeroSelectorBox = box
set HeroSelectorBoxSeperator = boxBottom
call BlzFrameSetLevel(HeroSelectorBox, -1)
call BlzFrameSetLevel(HeroSelectorBoxSeperator, -1)
call BlzFrameSetModel(IndicatorSelected, IndicatorPathPick, 0)
call BlzFrameSetScale(IndicatorSelected, ButtonSize/0.036) //scale the model to the button size.
call BlzFrameSetVisible(IndicatorSelected, false)
call BlzFrameSetAbsPoint(box, BoxPosPoint, BoxPosX, BoxPosY)
call BlzFrameSetSize(box, borderSize*2 + ButtonSize*colCount + SpaceBetweenX*(colCount-1), borderSize*2 + ButtonSize*rowCount + SpaceBetweenY*(rowCount - 1) + titleSize + CategorySize + 0.0145)
call BlzFrameSetPoint(HeroSelectorBoxTitle, FRAMEPOINT_TOP, box, FRAMEPOINT_TOP, 0, -borderSize*0.6)
call BlzFrameSetText(HeroSelectorBoxTitle, "Hero Selection")
call BlzFrameSetTextAlignment(HeroSelectorBoxTitle, TEXT_JUSTIFY_MIDDLE, TEXT_JUSTIFY_CENTER)
call BlzFrameSetSize(HeroSelectorBoxTitle, BlzFrameGetWidth(box) - borderSize*2, 0.03)
// human UI size differs much, needs other numbers
if GetPlayerRace(GetLocalPlayer()) == RACE_HUMAN then
call BlzFrameSetPoint(boxBottom, FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, borderSize*0.055, - 0.9*borderSize - titleSize - 0.003 -CategorySize)
call BlzFrameSetPoint(boxBottom, FRAMEPOINT_TOPRIGHT, box, FRAMEPOINT_TOPRIGHT, -borderSize*0.055, - 0.9*borderSize - titleSize - 0.003 -CategorySize)
else
call BlzFrameSetPoint(boxBottom, FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, borderSize*0.25, - 0.9*borderSize - titleSize - 0.003 -CategorySize)
call BlzFrameSetPoint(boxBottom, FRAMEPOINT_TOPRIGHT, box, FRAMEPOINT_TOPRIGHT, -borderSize*0.25, - 0.9*borderSize - titleSize - 0.003 -CategorySize)
endif
call BlzFrameSetSize(boxBottom, 0.01, 0.1)
if colCount*rowCount < ButtonHeroCount then
call BJDebugMsg("FieldCount:"+ I2S(colCount*rowCount) + "HeroCount" + I2S(ButtonHeroCount))
endif
set buttonIndex = 1
loop
exitwhen buttonIndex > HeroButtonCount
set HeroButtonFrame[buttonIndex] = BlzCreateFrame("HeroSelectorButton", box, 0, buttonIndex)
set HeroButtonIcon[buttonIndex] = BlzGetFrameByName("HeroSelectorButtonIcon", buttonIndex)
set HeroButtonIconPushed[buttonIndex] = BlzGetFrameByName("HeroSelectorButtonIconPushed", buttonIndex)
set HeroButtonIconDisabled[buttonIndex] = BlzGetFrameByName("HeroSelectorButtonIconDisabled", buttonIndex)
set HeroButtonUnitCode[buttonIndex] = ButtonHeroUnitCode[buttonIndex]
call SaveInteger(Hash, GetHandleId(HeroButtonFrame[buttonIndex]), 0, buttonIndex)
set HeroButtonTooltipBox[buttonIndex] = BlzCreateFrame("HeroSelectorTextBox", box, 0, buttonIndex)
set HeroButtonTooltip[buttonIndex] = BlzCreateFrame("HeroSelectorText", HeroButtonTooltipBox[buttonIndex], 0, buttonIndex)
call BlzFrameSetTooltip(HeroButtonFrame[buttonIndex], HeroButtonTooltipBox[buttonIndex])
if not TooltipRelativIsBox then
call BlzFrameSetPoint(HeroButtonTooltip[buttonIndex], TooltipPoint, HeroButtonFrame[buttonIndex], TooltipRelativePoint, TooltipOffsetX ,TooltipOffsetY)
else
call BlzFrameSetPoint(HeroButtonTooltip[buttonIndex], TooltipPoint, box, TooltipRelativePoint, TooltipOffsetX ,TooltipOffsetY)
endif
call BlzFrameSetPoint(HeroButtonTooltipBox[buttonIndex], FRAMEPOINT_BOTTOMLEFT, HeroButtonTooltip[buttonIndex], FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
call BlzFrameSetPoint(HeroButtonTooltipBox[buttonIndex], FRAMEPOINT_TOPRIGHT, HeroButtonTooltip[buttonIndex], FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
call BlzTriggerRegisterFrameEvent(HeroButtonClickTrigger, HeroButtonFrame[buttonIndex], FRAMEEVENT_CONTROL_CLICK)
call BlzFrameSetSize(HeroButtonFrame[buttonIndex], ButtonSize, ButtonSize)
if HeroButtonUnitCode[buttonIndex] > 0 then
call BlzFrameSetTexture(HeroButtonIcon[buttonIndex], BlzGetAbilityIcon(HeroButtonUnitCode[buttonIndex]), 0, ButtonBlendAll)
call BlzFrameSetTexture(HeroButtonIconPushed[buttonIndex], BlzGetAbilityIcon(HeroButtonUnitCode[buttonIndex]), 0, ButtonBlendAll)
call BlzFrameSetTexture(HeroButtonIconDisabled[buttonIndex], HeroSelectorGetDisabledIcon(BlzGetAbilityIcon(HeroButtonUnitCode[buttonIndex])), 0, ButtonBlendAll)
call BlzFrameSetText(HeroButtonTooltip[buttonIndex], TooltipPrefix + GetObjectName(HeroButtonUnitCode[buttonIndex]))
call BlzFrameSetEnable(HeroButtonFrame[buttonIndex], HeroSelectorButtonRequirementDone(HeroButtonUnitCode[buttonIndex], GetLocalPlayer()))
else
call BlzFrameSetEnable(HeroButtonFrame[buttonIndex], false)
call BlzFrameSetTexture(HeroButtonIcon[buttonIndex], EmptyButtonPath, 0, true)
call BlzFrameSetTexture(HeroButtonIconPushed[buttonIndex], EmptyButtonPath, 0, true)
call BlzFrameSetTexture(HeroButtonIconDisabled[buttonIndex], EmptyButtonPath, 0, true)
endif
if ChainedButtons then //buttons are connected to the previous one or the previous row
if buttonIndex == 1 then
call BlzFrameSetPoint(HeroButtonFrame[buttonIndex], FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, borderSize, y)
elseif rowRemaining <= 0 then
call BlzFrameSetPoint(HeroButtonFrame[buttonIndex], FRAMEPOINT_TOPLEFT, HeroButtonFrame[buttonIndex - colCount], FRAMEPOINT_BOTTOMLEFT, 0, -SpaceBetweenY)
set rowRemaining = colCount
else
call BlzFrameSetPoint(HeroButtonFrame[buttonIndex], FRAMEPOINT_LEFT, HeroButtonFrame[buttonIndex - 1], FRAMEPOINT_RIGHT, SpaceBetweenX, 0)
endif
else //buttons have an offset to the TopLeft of the box
if rowRemaining <= 0 then
set x = borderSize
set rowRemaining = colCount
set y = y - SpaceBetweenY - ButtonSize
elseif buttonIndex != 1 then
set x = x + ButtonSize + SpaceBetweenX
endif
call BlzFrameSetPoint(HeroButtonFrame[buttonIndex], FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, x, y)
endif
set rowRemaining = rowRemaining - 1
set buttonIndex = buttonIndex + 1
endloop
set y = -0.9*borderSize - titleSize - 0.0025
set x = borderSize*0.65
//create category buttons added before the box was created
set buttonIndex = 1
loop
exitwhen buttonIndex > CategoryButtonCount
set CategoryButton[buttonIndex] = BlzCreateFrame("HeroSelectorCategoryButton", box, 0, 0)
set CategoryIconFrame[buttonIndex] = BlzGetFrameByName("HeroSelectorCategoryButtonIcon", 0)
set CategoryIconPushedFrame[buttonIndex] = BlzGetFrameByName("HeroSelectorCategoryButtonIconPushed", 0)
set CategoryTooltipFrameBox[buttonIndex] = BlzCreateFrame("HeroSelectorTextBox", box, 0, buttonIndex)
set CategoryTooltipFrame[buttonIndex] = BlzCreateFrame("HeroSelectorText", CategoryTooltipFrameBox[buttonIndex], 0, buttonIndex)
call BlzFrameSetText(CategoryTooltipFrame[buttonIndex], GetLocalizedString(CategoryText[buttonIndex]))
call BlzFrameSetPoint(CategoryTooltipFrameBox[buttonIndex], FRAMEPOINT_BOTTOMLEFT, CategoryTooltipFrame[buttonIndex], FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
call BlzFrameSetPoint(CategoryTooltipFrameBox[buttonIndex], FRAMEPOINT_TOPRIGHT, CategoryTooltipFrame[buttonIndex], FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
call BlzFrameSetPoint(CategoryTooltipFrame[buttonIndex], FRAMEPOINT_BOTTOM, CategoryButton[buttonIndex], FRAMEPOINT_TOP, 0, 0)
call BlzFrameSetTooltip(CategoryButton[buttonIndex], CategoryTooltipFrameBox[buttonIndex])
call BlzFrameSetSize(CategoryButton[buttonIndex], CategorySize, CategorySize)
call BlzFrameSetTexture(CategoryIconFrame[buttonIndex], CategoryTextureDisabled[buttonIndex], 0, true)
call BlzFrameSetTexture(CategoryIconPushedFrame[buttonIndex], CategoryTextureDisabled[buttonIndex], 0, true)
call BlzTriggerRegisterFrameEvent(CategoryClickTrigger, CategoryButton[buttonIndex], FRAMEEVENT_CONTROL_CLICK)
if buttonIndex == 1 then
call BlzFrameSetPoint(CategoryButton[buttonIndex], FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, x, y)
else
call BlzFrameSetPoint(CategoryButton[buttonIndex], FRAMEPOINT_LEFT, CategoryButton[buttonIndex - 1], FRAMEPOINT_RIGHT, CategorySpaceX, 0)
endif
call SaveInteger(Hash, GetHandleId(CategoryButton[buttonIndex]), 0, buttonIndex)
set buttonIndex = buttonIndex + 1
endloop
call TriggerAddAction(CategoryClickTrigger, function HeroSelectorActionCategoryButton)
set AcceptButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 0)
set RandomButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 1)
set BanButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 2)
call TriggerAddAction(AcceptButtonTrigger, function HeroSelectorActionAcceptButton)
call TriggerAddAction(RandomButtonTrigger, function HeroSelectorActionRandomButton)
call TriggerAddAction(BanButtonTrigger, function HeroSelectorActionBanButton)
call BlzTriggerRegisterFrameEvent(AcceptButtonTrigger, AcceptButton, FRAMEEVENT_CONTROL_CLICK)
call BlzTriggerRegisterFrameEvent(RandomButtonTrigger, RandomButton, FRAMEEVENT_CONTROL_CLICK)
call BlzTriggerRegisterFrameEvent(BanButtonTrigger, BanButton, FRAMEEVENT_CONTROL_CLICK)
call BlzFrameSetSize(AcceptButton, AcceptButtonSizeX, AcceptButtonSizeY)
call BlzFrameSetSize(RandomButton, RandomButtonSizeX, RandomButtonSizeY)
call BlzFrameSetSize(BanButton, BanButtonSizeX, BanButtonSizeY)
//OK, READY, ACCEPT
call BlzFrameSetText(AcceptButton, AcceptButtonTextPrefix + GetLocalizedString(AcceptButtonText))
call BlzFrameSetText(RandomButton, RandomButtonTextPrefix + GetLocalizedString(RandomButtonText))
call BlzFrameSetText(BanButton, BanButtonTextPrefix + GetLocalizedString(BanButtonText))
call BlzFrameSetPoint(AcceptButton, AcceptButtonAnchor, box, FRAMEPOINT_BOTTOM, 0, 0)
call BlzFrameSetPoint(RandomButton, RandomButtonAnchor, box, FRAMEPOINT_BOTTOM, 0, 0)
call BlzFrameSetPoint(BanButton, FRAMEPOINT_BOTTOM, box, FRAMEPOINT_BOTTOM, 0, 0)
call BlzFrameSetVisible(BanButton, false)
call BlzFrameSetVisible(AcceptButton, AcceptButtonIsShown)
call BlzFrameSetVisible(RandomButton, RandomButtonIsShown)
if not AutoShow then
call BlzFrameSetVisible(box, false)
endif
call ExecuteFunc("HeroInfoInit")
//call ExecuteFunc("TeamViewerInit")
endfunction
endlibrary
scope HeroSelectorAction initializer Init //uses HeroSelector, TeamViewer, HeroInfo
//HeroSelectorAction V1.4.0
//what happens to the unit beeing picked, player is the one having pressed the button
function HeroSelectorUnitCreated takes nothing returns nothing
local player p = udg_HeroSelectorEventPlayer
local integer playerIndex = GetPlayerId(p)
local unit u = udg_HeroSelectorEventUnit
local boolean isRandom = udg_HeroSelectorEventIsRandom
local integer id = GetUnitUserData(u)
local Team t = GetPlayerTeamEx(p)
local HeroData d = HeroData.GetDataByHeroID(GetUnitTypeId(u))
call RemoveUnit(Players[playerIndex].dummyPreview)
if isRandom then
if t == 1 then
call Message.ShowToForce(Team[2].forceP,GetPlayerName(p) + " has randomed "+GetUnitName(u),MESSAGE_STYLE_INFO)
elseif t == 2 then
call Message.ShowToForce(Team[1].forceP,GetPlayerName(p) + " has randomed "+GetUnitName(u),MESSAGE_STYLE_INFO)
endif
else
if t == 1 then
call Message.ShowToForce(Team[2].forceP,GetPlayerName(p) + " has choosen "+GetUnitName(u),MESSAGE_STYLE_INFO)
elseif t == 2 then
call Message.ShowToForce(Team[1].forceP,GetPlayerName(p) + " has choosen "+GetUnitName(u),MESSAGE_STYLE_INFO)
endif
endif
call UnitAddAbility(u,'Abun')
call BlzUnitDisableAbility(u,'Amov',true,false)
call UnitAddAbility(u,'A02Y')
call SetUnitPosition(u, GetPlayerStartLocationX(p), GetPlayerStartLocationY(p))
call UnitMakeAbilityPermanent(u,true,'A02Y')
set Index[id].lock = true
set Players[playerIndex].hero = Hero.create(u,d)
call RegisterHeroRespawn(u)
call HeroSelectorEnablePickPlayer(false, p) //only one pick for this player
if GetPlayerController(p) == MAP_CONTROL_COMPUTER then
call TeamComposition.AddHeroInfo(d,t,false,true)
call TeamComposition.AddHeroInfo(d,t,true,false)
else
call TeamComposition.AddHeroInfo(d,t,true,false)
endif
call SelectUnitForPlayer(Players[playerIndex].traitUnit,p,true)
if Game.LocalPlayer == p then
call StartSound(gg_snd_HeroPick)
endif
set p = null
set u = null
endfunction
//happens when the banButton is pressed, player is the one having pressed the button
function HeroSelectorUnitBaned takes nothing returns nothing
local player p = udg_HeroSelectorEventPlayer
local integer playerIndex = GetPlayerId(p)
local integer unitCode = udg_HeroSelectorEventUnitCode
call HeroSelectorEnableBanPlayer(false, p) //only one ban
set p = null
endfunction
function HeroSelectorButtonSelected takes nothing returns nothing
//player who pressed the button
//unitCode the unitCode selected
//this is not picked.
local player p = udg_HeroSelectorEventPlayer
local integer playerIndex = GetPlayerId(p)
local integer unitCode = udg_HeroSelectorEventUnitCode
local HeroData d = HeroData.GetDataByHeroID(unitCode)
local unit dummy
//call TeamViewerButtonSelected(p, unitCode)
call TeamComposition.AddHeroInfo(Players[playerIndex].lastDataPreview,GetPlayerTeamEx(p),false,false)
set Players[playerIndex].lastDataPreview = d
call TeamComposition.AddHeroInfo(d,GetPlayerTeamEx(p),false,true)
call HeroInfoButtonSelected(p,d.TypeID)
call RemoveUnit(Players[playerIndex].dummyPreview)
set dummy = CreateUnit(p,d.ChooseDummy,GetRectCenterX(gg_rct_ObeliskArea),GetRectCenterY(gg_rct_ObeliskArea),0)
call UnitGenerateAlarms(dummy,false)
call SetUnitScale(dummy,0,0,0)
call SetUnitAbilityLevel(dummy,d.HeroAbility1,4)
call BlzSetUnitAbilityManaCost(dummy,d.HeroAbility1,3,0)
call BlzSetUnitAbilityCooldown(dummy,d.HeroAbility1,3,0)
//call BlzUnitDisableAbility(dummy,d.HeroAbility1,true,false)
call SetUnitAbilityLevel(dummy,d.HeroAbility2,4)
call BlzSetUnitAbilityManaCost(dummy,d.HeroAbility2,3,0)
call BlzSetUnitAbilityCooldown(dummy,d.HeroAbility2,3,0)
//call BlzUnitDisableAbility(dummy,d.HeroAbility2,true,false)
call SetUnitAbilityLevel(dummy,d.HeroAbility3,4)
call BlzSetUnitAbilityManaCost(dummy,d.HeroAbility3,3,0)
call BlzSetUnitAbilityCooldown(dummy,d.HeroAbility3,3,0)
//call BlzUnitDisableAbility(dummy,d.HeroAbility3,true,false)
call SetUnitAbilityLevel(dummy,d.HeroAbility4,3)
call BlzSetUnitAbilityManaCost(dummy,d.HeroAbility4,2,0)
call BlzSetUnitAbilityCooldown(dummy,d.HeroAbility4,2,0)
//call BlzUnitDisableAbility(dummy,d.HeroAbility4,true,false)
call SetUnitAbilityLevel(dummy,d.HeroAbility5,1)
call BlzSetUnitAbilityManaCost(dummy,d.HeroAbility5,0,0)
call BlzSetUnitAbilityCooldown(dummy,d.HeroAbility5,0,0)
//call BlzUnitDisableAbility(dummy,d.HeroAbility5,true,false)
call SetUnitAbilityLevel(dummy,d.HeroAbility6,1)
call BlzSetUnitAbilityManaCost(dummy,d.HeroAbility6,0,0)
call BlzSetUnitAbilityCooldown(dummy,d.HeroAbility6,0,0)
//call BlzUnitDisableAbility(dummy,d.HeroAbility6,true,false)
call BuildDescriptionByData(d.HeroUp1,dummy)
call BuildDescriptionByData(d.HeroUp2,dummy)
call BuildDescriptionByData(d.HeroUp3,dummy)
call UnitRemoveAbility(dummy,'A01M')
call UnitRemoveAbility(dummy,'A04C')
call UnitRemoveAbility(dummy,'A01N')
call UnitRemoveAbility(dummy,'A02X')
call SetUnitAbilityLevel(dummy,d.HeroUp4.UpId,1)
call BlzFrameSetTexture(HeroesIcon[playerIndex - 2], BlzGetAbilityIcon(d.TypeID),0, true)
call BlzFrameSetAlpha(HeroesIcon[playerIndex - 2],150)
call SelectUnitForPlayer(dummy,p,true)
set Players[playerIndex].dummyPreview = dummy
set p = null
set dummy = null
endfunction
function HeroSelectorRepick takes unit u returns nothing
local integer unitCode
local player p = GetOwningPlayer(u)
local integer playerIndex = GetPlayerId(p)
call UnitRemoveBuffsBJ(bj_REMOVEBUFFS_ALL, u) //this is done to undo metamorph
set unitCode = GetUnitTypeId(u)
if unitCode == 0 then
return
endif
call HeroSelectorCounterChangeUnitCode(unitCode, -1, p)
call HeroSelectorShowPlayer(true, p)
call HeroSelectorEnablePickPlayer(true, p)
//call TeamViewerRepick(u, p)
call RemoveUnit(u)
endfunction
//This runs before the box is created with that the system has the needed data right when it is needed.
//you can add units somewhere else but it is done after the box was created you have to use the update function to update the textures of shown buttons
public function InitHeroes takes nothing returns nothing
//create categories setuped in config
local integer index
local integer categoryMelee = 1 //autodetected
local integer categoryRanged = 2 //autodetected
local integer categoryStr = 4
local integer categoryAgi = 8
local integer categoryInt = 16
call HeroSelectorAddCategory("ReplaceableTextures\\CommandButtons\\BTNSteelMelee", "Melee") //1, automatic detected when adding an unit
call HeroSelectorAddCategory("ReplaceableTextures\\CommandButtons\\BTNHumanMissileUpOne", "Ranged") //2, automatic detected when adding an unit
call HeroSelectorAddCategory("war3mapImported\\infocard-heroattributes-str.blp", "Strength") //4
call HeroSelectorAddCategory("war3mapImported\\infocard-heroattributes-agi", "Agility") //8
call HeroSelectorAddCategory("war3mapImported\\infocard-heroattributes-int", "Intelligence") //16
//Agility
call HeroSelectorAddUnit('HBC1', false)
call HeroSelectorAddUnitCategory('HBC1', categoryAgi + categoryMelee)
call HeroSelectorAddUnit('HDS1', false)
call HeroSelectorAddUnitCategory('HDS1', categoryAgi + categoryMelee)
call HeroSelectorAddUnit('HDR1', false)
call HeroSelectorSetUnitReqRace('HDR1', RACE_HUMAN)
call HeroSelectorAddUnitCategory('HDR1', categoryAgi + categoryRanged)
call HeroSelectorAddUnit('HFR1', false)
call HeroSelectorSetUnitReqRace('HFR1', RACE_ORC)
call HeroSelectorAddUnitCategory('HFR1', categoryAgi + categoryMelee)
call HeroSelectorAddUnit('HGW1', false)
call HeroSelectorAddUnitCategory('HGW1', categoryAgi + categoryRanged)
call HeroSelectorAddUnit('HGG1', false)
call HeroSelectorAddUnitCategory('HGG1', categoryAgi + categoryRanged)
call HeroSelectorAddUnit('HGR1', false)
call HeroSelectorSetUnitReqRace('HGR1', RACE_HUMAN)
call HeroSelectorAddUnitCategory('HGR1', categoryAgi + categoryRanged)
call HeroSelectorAddUnit('HHH1', false)
call HeroSelectorSetUnitReqRace('HHH1', RACE_ORC)
call HeroSelectorAddUnitCategory('HHH1', categoryAgi + categoryRanged)
call HeroSelectorAddUnit('HSW1', false)
call HeroSelectorAddUnitCategory('HSW1', categoryAgi + categoryMelee)
call HeroSelectorAddUnit('HSA1', false)
call HeroSelectorAddUnitCategory('HSA1', categoryAgi + categoryMelee)
call HeroSelectorAddUnit('HWD1', false)
call HeroSelectorAddUnitCategory('HWD1', categoryAgi + categoryMelee)
call HeroSelectorAddUnit('HZE1', false)
call HeroSelectorSetUnitReqRace('HZE1', RACE_ORC)
call HeroSelectorAddUnitCategory('HZE1', categoryAgi + categoryMelee)
call HeroSelectorAddUnit('HTR1', false)
call HeroSelectorAddUnitCategory('HTR1', categoryAgi + categoryMelee)
//Intelligence
call HeroSelectorAddUnit('HAD1', false)
call HeroSelectorSetUnitReqRace('HAD1', RACE_HUMAN)
call HeroSelectorAddUnitCategory('HAD1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HDQ1', false)
call HeroSelectorAddUnitCategory('HDQ1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HDE1', false)
call HeroSelectorAddUnitCategory('HDE1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HEN1', false)
call HeroSelectorAddUnitCategory('HEN1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HFI1', false)
call HeroSelectorAddUnitCategory('HFI1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HMM1', false)
call HeroSelectorAddUnitCategory('HMM1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HAD1', false)
call HeroSelectorAddUnitCategory('HAD1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HOS1', false)
call HeroSelectorSetUnitReqRace('HOS1', RACE_ORC)
call HeroSelectorAddUnitCategory('HOS1', categoryInt + categoryMelee)
call HeroSelectorAddUnit('HSB1', false)
call HeroSelectorAddUnitCategory('HSB1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HTD1', false)
call HeroSelectorAddUnitCategory('HTD1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HVP1', false)
call HeroSelectorSetUnitReqRace('HVP1', RACE_ORC)
call HeroSelectorAddUnitCategory('HVP1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HWL1', false)
call HeroSelectorSetUnitReqRace('HWL1', RACE_ORC)
call HeroSelectorAddUnitCategory('HWL1', categoryInt + categoryRanged)
call HeroSelectorAddUnit('HMB1', false)
call HeroSelectorSetUnitReqRace('HMB1', RACE_HUMAN)
call HeroSelectorAddUnitCategory('HMB1', categoryInt + categoryRanged)
//Strength
call HeroSelectorAddUnit('HAM1', false)
call HeroSelectorSetUnitReqRace('HAM1', RACE_ORC)
call HeroSelectorAddUnitCategory('HAM1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HJK1', false)
call HeroSelectorSetUnitReqRace('HJK1', RACE_ORC)
call HeroSelectorAddUnitCategory('HJK1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HDG1', false)
call HeroSelectorAddUnitCategory('HDG1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HEB1', false)
call HeroSelectorSetUnitReqRace('HEB1', RACE_HUMAN)
call HeroSelectorAddUnitCategory('HEB1', categoryStr + categoryRanged)
call HeroSelectorAddUnit('HFB1', false)
call HeroSelectorAddUnitCategory('HFB1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HFS1', false)
call HeroSelectorAddUnitCategory('HFS1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HIA1', false)
call HeroSelectorAddUnitCategory('HIA1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HAM1', false)
call HeroSelectorAddUnitCategory('HAM1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HLM1', false)
call HeroSelectorAddUnitCategory('HLM1', categoryStr + categoryRanged)
call HeroSelectorAddUnit('HPB1', false)
call HeroSelectorAddUnitCategory('HPB1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HAM1', false)
call HeroSelectorAddUnitCategory('HAM1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HSC1', false)
call HeroSelectorSetUnitReqRace('HSC1', RACE_HUMAN)
call HeroSelectorAddUnitCategory('HSC1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HSG1', false)
call HeroSelectorSetUnitReqRace('HSG1', RACE_HUMAN)
call HeroSelectorAddUnitCategory('HSG1', categoryStr + categoryMelee)
call HeroSelectorAddUnit('HTH1', false)
call HeroSelectorAddUnitCategory('HTH1', categoryStr + categoryMelee)
endfunction
private function Init takes nothing returns nothing
local trigger trig
set trig = CreateTrigger()
call TriggerRegisterVariableEvent(trig, "udg_HeroSelectorEvent", EQUAL, 2.0 )
call TriggerAddAction(trig, function HeroSelectorButtonSelected)
set trig = CreateTrigger()
call TriggerRegisterVariableEvent(trig, "udg_HeroSelectorEvent", EQUAL, 1.0 )
call TriggerAddAction(trig, function HeroSelectorUnitCreated)
set trig = CreateTrigger()
call TriggerRegisterVariableEvent(trig, "udg_HeroSelectorEvent", EQUAL, 3.0 )
call TriggerAddAction(trig, function HeroSelectorUnitBaned)
endfunction
endscope
/*
- Spell Damage
- Attack Damage
- Healing
- Survivavility
- Movement
- Crowd Control
*/
scope UIHeroQuality
globals
public constant string QUALITY_COLOR = "|cffff9600"
public constant string GRAY_COLOR = "|cff808080"
private constant string BAR_PRI_COLOR = "|cff0000ff"
private constant string BAR_SEC_COLOR = "|cffc0c0c0"
endglobals
struct TeamComposition extends array
integer spellDamage
integer preSpellDamage
integer attackDamage
integer preAttackDamage
integer healing
integer preHealing
integer survivavility
integer preSurvivavility
integer movement
integer preMovement
integer crowdControl
integer preCrowdControl
integer totalCountSD
integer preCountSD
integer totalCountAD
integer preCountAD
integer totalCountH
integer preCountH
integer totalCountSV
integer preCountSV
integer totalCountMV
integer preCountMV
integer totalCountCC
integer preCountCC
private static method BuildTeamQualityBar takes integer a, integer b returns string
local string x = "███████████"
local integer i
local string y
local string z
local string v
if b < 0 then
set b = b * (-1)
set y = SubString(x,0,(a - b) * 3)
set z = SubString(x,0,b * 3)
set v = SubString(x,0,(10 - a) * 3)
return BAR_PRI_COLOR + y + "|r" + "|cffff0000" + z + "|r" + GRAY_COLOR + v + "|r " + I2S(a - b) + "/10"
else
set y = SubString(x,0,a * 3)
set z = SubString(x,0,b * 3)
set v = SubString(x,0,(10 - (a + b)) * 3)
return BAR_PRI_COLOR + y + "|r" + BAR_SEC_COLOR + z + "|r" + GRAY_COLOR + v + "|r " + I2S(a + b) + "/10"
endif
endmethod
private static method BarMath takes integer a, integer b returns integer
local integer r
local integer d
local real s
if a == 0 then
return a
endif
set d = a / b
set s = I2R(a) / I2R(b)
set r = R2I(ModuloReal(s * 100,100))
if r >= 50 then
return d + 1
endif
return d
endmethod
public static method AddHeroicAbilityInfo takes Team t, integer sdlevel, integer adlevel, integer hlevel, integer svlevel, integer mvlevel, integer cclevel returns nothing
local thistype this = t
local integer i
local integer j
local string r = ""
if not BlzFrameIsVisible(HeroSelectorBox) then
return
endif
if sdlevel != 0 then
set totalCountSD = totalCountSD + 1
endif
set spellDamage = spellDamage + sdlevel
set i = BarMath(spellDamage,totalCountSD)
set j = BarMath(spellDamage + preSpellDamage,totalCountSD + preCountSD)
set r = QUALITY_COLOR + "Spell Damage:|r " + BuildTeamQualityBar(i,j - i) + "|n"
if adlevel != 0 then
set totalCountAD = totalCountAD + 1
endif
set attackDamage = attackDamage + adlevel
set i = BarMath(attackDamage,totalCountAD)
set j = BarMath(attackDamage + preAttackDamage,totalCountAD + preCountAD)
set r = r + QUALITY_COLOR + "Attack Damage:|r " + BuildTeamQualityBar(i,j - i) + "|n"
if hlevel != 0 then
set totalCountH = totalCountH + 1
endif
set healing = healing + hlevel
set i = BarMath(healing,totalCountH)
set j = BarMath(healing + preHealing,totalCountH + preCountH)
set r = r + QUALITY_COLOR + "Healing:|r " + BuildTeamQualityBar(i,j - i) + "|n"
if svlevel != 0 then
set totalCountSV = totalCountSV + 1
endif
set survivavility = survivavility + svlevel
set i = BarMath(survivavility,totalCountSV)
set j = BarMath(survivavility + preSurvivavility,totalCountSV + preCountSV)
set r = r + QUALITY_COLOR + "Survivavility:|r " + BuildTeamQualityBar(i,j - i) + "|n"
if mvlevel != 0 then
set totalCountMV = totalCountMV + 1
endif
set movement = movement + mvlevel
set i = BarMath(movement,totalCountMV)
set j = BarMath(movement + preMovement,totalCountMV + preCountSD)
set r = r + QUALITY_COLOR + "Movement:|r " + BuildTeamQualityBar(i,j - i) + "|n"
if cclevel != 0 then
set totalCountCC = totalCountCC + 1
endif
set crowdControl = crowdControl + cclevel
set i = BarMath(crowdControl,totalCountCC)
set j = BarMath(crowdControl + preCrowdControl,totalCountCC + preCountCC)
set r = r + QUALITY_COLOR + "Crowd Control:|r " + BuildTeamQualityBar(i,j - i) + "|n"
if IsPlayerInForce(Game.LocalPlayer,t.forceP) then
call BlzFrameSetText(HeroInfo_TextDisplayTeam, "Team Composition")
call BlzFrameAddText(HeroInfo_TextDisplayTeam, r)
endif
endmethod
public static method AddHeroInfo takes HeroData h, Team t, boolean pick, boolean preview returns nothing
local thistype this = t
local string r = ""
local integer i = 0
local integer j = 0
if h == 0 then
return
endif
if pick then
if h.spellDamageLevel != 0 then
set totalCountSD = totalCountSD + 1
endif
if h.attackDamageLevel != 0 then
set totalCountAD = totalCountAD + 1
endif
if h.healingLevel != 0 then
set totalCountH = totalCountH + 1
endif
if h.survivavilityLevel != 0 then
set totalCountSV = totalCountSV + 1
endif
if h.movementLevel != 0 then
set totalCountMV = totalCountMV + 1
endif
if h.crowdControlLevel != 0 then
set totalCountCC = totalCountCC + 1
endif
set spellDamage = spellDamage + h.spellDamageLevel
set attackDamage = attackDamage + h.attackDamageLevel
set healing = healing + h.healingLevel
set survivavility = survivavility + h.survivavilityLevel
set movement = movement + h.movementLevel
set crowdControl = crowdControl + h.crowdControlLevel
endif
if preview then
if h.spellDamageLevel != 0 then
set preCountSD = preCountSD + 1
endif
if h.attackDamageLevel != 0 then
set preCountAD = preCountAD + 1
endif
if h.healingLevel != 0 then
set preCountH = preCountH + 1
endif
if h.survivavilityLevel != 0 then
set preCountSV = preCountSV + 1
endif
if h.movementLevel != 0 then
set preCountMV = preCountMV + 1
endif
if h.crowdControlLevel != 0 then
set preCountCC = preCountCC + 1
endif
set preSpellDamage = preSpellDamage + h.spellDamageLevel
set preAttackDamage = preAttackDamage + h.attackDamageLevel
set preHealing = preHealing + h.healingLevel
set preSurvivavility = preSurvivavility + h.survivavilityLevel
set preMovement = preMovement + h.movementLevel
set preCrowdControl = preCrowdControl + h.crowdControlLevel
else
if h.spellDamageLevel != 0 then
set preCountSD = preCountSD - 1
endif
if h.attackDamageLevel != 0 then
set preCountAD = preCountAD - 1
endif
if h.healingLevel != 0 then
set preCountH = preCountH - 1
endif
if h.survivavilityLevel != 0 then
set preCountSV = preCountSV - 1
endif
if h.movementLevel != 0 then
set preCountMV = preCountMV - 1
endif
if h.crowdControlLevel != 0 then
set preCountCC = preCountCC - 1
endif
set preSpellDamage = preSpellDamage - h.spellDamageLevel
set preAttackDamage = preAttackDamage - h.attackDamageLevel
set preHealing = preHealing - h.healingLevel
set preSurvivavility = preSurvivavility - h.survivavilityLevel
set preMovement = preMovement - h.movementLevel
set preCrowdControl = preCrowdControl - h.crowdControlLevel
endif
set i = BarMath(spellDamage,totalCountSD)
set j = BarMath(spellDamage + preSpellDamage,totalCountSD + preCountSD)
set r = QUALITY_COLOR + "Spell Damage:|r " + BuildTeamQualityBar(i,j - i) + "|n"
set i = BarMath(attackDamage,totalCountAD)
set j = BarMath(attackDamage + preAttackDamage,totalCountAD + preCountAD)
set r = r + QUALITY_COLOR + "Attack Damage:|r " + BuildTeamQualityBar(i,j - i) + "|n"
set i = BarMath(healing,totalCountH)
set j = BarMath(healing + preHealing,totalCountH + preCountH)
set r = r + QUALITY_COLOR + "Healing:|r " + BuildTeamQualityBar(i,j - i) + "|n"
set i = BarMath(survivavility,totalCountSV)
set j = BarMath(survivavility + preSurvivavility,totalCountSV + preCountSV)
set r = r + QUALITY_COLOR + "Survivavility:|r " + BuildTeamQualityBar(i,j - i) + "|n"
set i = BarMath(movement,totalCountMV)
set j = BarMath(movement + preMovement,totalCountMV + preCountMV)
set r = r + QUALITY_COLOR + "Movement:|r " + BuildTeamQualityBar(i,j - i) + "|n"
set i = BarMath(crowdControl,totalCountCC)
set j = BarMath(crowdControl + preCrowdControl,totalCountCC + preCountCC)
set r = r + QUALITY_COLOR + "Crowd Control:|r " + BuildTeamQualityBar(i,j - i) + "|n"
/*if h.spellDamageLevel != 0 then
else
set i = BarMath(spellDamage,totalCountSD)
set r = QUALITY_COLOR + "Spell Damage:|r " + BuildTeamQualityBar(i,0) + "|n"
endif
if h.attackDamageLevel != 0 then
else
set i = BarMath(attackDamage,totalCountAD)
set r = r + QUALITY_COLOR + "Attack Damage:|r " + BuildTeamQualityBar(i,0) + "|n"
endif
if h.healingLevel != 0 then
else
set i = BarMath(healing,totalCountH)
set r = r + QUALITY_COLOR + "Healing:|r " + BuildTeamQualityBar(i,0) + "|n"
endif
if h.survivavilityLevel != 0 then
else
set i = BarMath(survivavility,totalCountSV)
set r = r + QUALITY_COLOR + "Survivavility:|r " + BuildTeamQualityBar(i,0) + "|n"
endif
if h.movementLevel != 0 then
else
set i = BarMath(movement,totalCountMV)
set r = r + QUALITY_COLOR + "Movement:|r " + BuildTeamQualityBar(i,0) + "|n"
endif
if h.crowdControlLevel != 0 then
else
set i = BarMath(crowdControl,totalCountCC)
set r = r + QUALITY_COLOR + "Crowd Control:|r " + BuildTeamQualityBar(i,0) + "|n"
endif*/
if IsPlayerInForce(Game.LocalPlayer,t.forceP) then
call BlzFrameSetText(HeroInfo_TextDisplayTeam, "Team Composition")
call BlzFrameAddText(HeroInfo_TextDisplayTeam, r)
endif
endmethod
endstruct
private function QualityToBar takes integer q returns string
local string x = "███████████"
local string y = SubString(x,0,q * 3)
local string z
set z = SubString(x,0,(10 - q) * 3)
return BAR_PRI_COLOR + y + "|r" + GRAY_COLOR + z+"|r " + I2S(q) + "/10"
endfunction
public function BuildHeroInfo takes HeroData h, player p returns string
local string s = QUALITY_COLOR + "Spell Damage:|r " + QualityToBar(h.spellDamageLevel) + "|n"
local Team t = GetPlayerTeamEx(p)
set s = s + QUALITY_COLOR + "Attack Damage:|r " + QualityToBar(h.attackDamageLevel) + "|n"
set s = s + QUALITY_COLOR + "Healing:|r " + QualityToBar(h.healingLevel) + "|n"
set s = s + QUALITY_COLOR + "Survivavility:|r " + QualityToBar(h.survivavilityLevel) + "|n"
set s = s + QUALITY_COLOR + "Movement:|r " + QualityToBar(h.movementLevel) + "|n"
set s = s + QUALITY_COLOR + "Crowd Control:|r " + QualityToBar(h.crowdControlLevel) + "|n"
return s
endfunction
endscope
scope UIMisc
globals
framehandle cb00
framehandle cb10
framehandle cb20
framehandle cb02
framehandle cb12
framehandle cb22
endglobals
struct PlayerKeyData extends array
boolean ctrl
boolean alt
/*static timer Clock
static trigger SyncTrigger
public static method ReadSyncData takes nothing returns nothing
local string s = BlzGetTriggerSyncData()
local player p = GetTriggerPlayer()
if s == "0" then
set thistype[GetPlayerId(p)].ctrl = false
set thistype[GetPlayerId(p)].alt = true
endif
set p = null
endmethod
public static method ClientCheck takes nothing returns nothing
local boolean b = BlzIsLocalClientActive()
local string s = ""
if not b then
set s = "0"
endif
call BlzSendSyncData("SyncKeys",s)
endmethod*/
public static method create takes player p returns thistype
local thistype this = thistype[GetPlayerId(p)]
set ctrl = false
set alt = false
return this
endmethod
/*public static method Initialize takes nothing returns nothing
local integer i = 0
set Clock = CreateTimer()
set SyncTrigger = CreateTrigger()
call TriggerAddAction(SyncTrigger,function thistype.ReadSyncData)
loop
call BlzTriggerRegisterPlayerSyncEvent(SyncTrigger, Player(i), "SyncKeys", false)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TimerStart(Clock,0.01,true,function thistype.ClientCheck)
endmethod*/
endstruct
function FixTextMessage takes nothing returns nothing
local framehandle m = BlzGetOriginFrame(ORIGIN_FRAME_UNIT_MSG, 0)
local framehandle c = BlzGetOriginFrame(ORIGIN_FRAME_CHAT_MSG, 0)
call BlzFrameClearAllPoints(m)
call BlzFrameClearAllPoints(c)
// -
if ( ( I2R(BlzGetLocalClientWidth()) / I2R(BlzGetLocalClientHeight()) ) > 1.61 ) then
call BlzFrameSetAbsPoint(m, FRAMEPOINT_BOTTOMLEFT, -0.125, 0.235)
call BlzFrameSetAbsPoint(m, FRAMEPOINT_TOPRIGHT, 0.5, 0.435)
call BlzFrameSetAbsPoint(c, FRAMEPOINT_BOTTOMLEFT, 0.05, 0.2125)//0.1625
call BlzFrameSetAbsPoint(c, FRAMEPOINT_TOPRIGHT, 0.6, 0.4)
else
if ( ( I2R(BlzGetLocalClientWidth()) / I2R(BlzGetLocalClientHeight()) ) > 1.4 ) then
call BlzFrameSetAbsPoint(m, FRAMEPOINT_BOTTOMLEFT, -0.0625, 0.235)
call BlzFrameSetAbsPoint(m, FRAMEPOINT_TOPRIGHT, 0.50625, 0.435)
call BlzFrameSetAbsPoint(c, FRAMEPOINT_BOTTOMLEFT, 0.175, 0.2125)
call BlzFrameSetAbsPoint(c, FRAMEPOINT_TOPRIGHT, 0.725, 0.4)
else
call BlzFrameSetAbsPoint(m, FRAMEPOINT_BOTTOMLEFT, 0.01, 0.235)
call BlzFrameSetAbsPoint(m, FRAMEPOINT_TOPRIGHT, 0.626, 0.435)
call BlzFrameSetAbsPoint(c, FRAMEPOINT_BOTTOMLEFT, 0.175, 0.2125)
call BlzFrameSetAbsPoint(c, FRAMEPOINT_TOPRIGHT, 0.725, 0.4)
endif
endif
endfunction
function GetCommandButtonFrameByXY takes integer x, integer y returns framehandle
if y == 0 then
if x == 0 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,0)
elseif x == 1 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,1)
elseif x == 2 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,2)
elseif x == 3 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,3)
endif
elseif y == 1 then
if x == 0 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,4)
elseif x == 1 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,5)
elseif x == 2 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,6)
elseif x == 3 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,7)
endif
elseif y == 2 then
if x == 0 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,8)
elseif x == 1 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,9)
elseif x == 2 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,10)
elseif x == 3 then
return BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,11)
endif
endif
return null
endfunction
public function init takes nothing returns nothing
call FixTextMessage()
set cb00 = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,1)
set cb10 = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,2)
set cb20 = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,3)
set cb02 = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,8)
set cb12 = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,9)
set cb22 = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,10)
endfunction
endscope
scope UIItems
globals
private string array TexturePath
endglobals
struct PlayerItemUI extends array
Table borders
public method hideAll takes nothing returns nothing
if Game.LocalPlayer == Player(this) then
call BlzFrameSetVisible(borders.framehandle[0],false)
call BlzFrameSetVisible(borders.framehandle[1],false)
call BlzFrameSetVisible(borders.framehandle[2],false)
call BlzFrameSetVisible(borders.framehandle[3],false)
call BlzFrameSetVisible(borders.framehandle[4],false)
call BlzFrameSetVisible(borders.framehandle[5],false)
endif
endmethod
public method updateItemPos takes integer i, Item it, player p returns nothing
local framehandle fh = borders.framehandle[i]
local string show = ""
call BlzFrameSetVisible(fh,false)
if it != 0 then
if it.itemType > 1 then
if Game.LocalPlayer == p then
set show = TexturePath[it.tier - 1]
call BlzFrameSetVisible(fh,true)
endif
endif
endif
call BlzFrameSetTexture(BlzGetFrameByName("ItemBorderTexture",(6 * this)+i),show,0,true)
set fh = null
endmethod
public static method setup takes integer p returns nothing
local thistype this = thistype[p]
local integer i = 0
local framehandle fh
set borders = Table.create()
loop
set fh = BlzCreateSimpleFrame("ItemBorder",BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON,i),(6 * this)+i)
call BlzFrameSetPoint(fh, FRAMEPOINT_CENTER, BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON,i), FRAMEPOINT_CENTER, 0, 0)
call BlzFrameSetSize(fh,0.03125,0.03125)
call BlzFrameSetAlpha(fh,170)
call BlzFrameSetVisible(fh,false)
set borders.framehandle[i] = fh
set i = i + 1
exitwhen i == 6
endloop
set fh = null
endmethod
endstruct
public function UpdateInventory takes unit u, player p returns nothing
local integer j = 0
local item i
local Item it
local PlayerItemUI ui = PlayerItemUI[GetPlayerId(p)]
loop
set i = UnitItemInSlot(u,j)
set it = GetItemUserData(i)
call ui.updateItemPos(j,it,p)
set j = j + 1
exitwhen j == 6
endloop
set i = null
endfunction
private function OnSelect takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetTriggerPlayer()
if GetUnitAbilityLevel(u,'AInv') != 0 and IsUnitType(u,UNIT_TYPE_HERO) then
call UpdateInventory(u,p)
else
call PlayerItemUI[GetPlayerId(p)].hideAll()
call UIItemUpgrade_HideButtons.evaluate(p)
endif
set u = null
set p = null
endfunction
public function Setup takes nothing returns nothing
local trigger t = CreateTrigger()
call BlzLoadTOCFile("war3mapImported\\ItemBorder.toc")
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SELECTED)
call TriggerAddCondition(t,function OnSelect)
set TexturePath[0] = "war3mapImported\\ItemBorderGreen"
set TexturePath[1] = "war3mapImported\\ItemBorderYellow"
set TexturePath[2] = "war3mapImported\\ItemBorderRed"
set t = null
endfunction
endscope
library UIAbilityNumber
private function ShowNumber takes nothing returns boolean
local boolean b1 = (BlzFrameIsVisible(cb00) and BlzFrameIsVisible(cb10) and BlzFrameIsVisible(cb20))
local boolean b2 = (BlzFrameIsVisible(cb02) and BlzFrameIsVisible(cb12) and BlzFrameIsVisible(cb22))
return (b1 and not b2) or b1
endfunction
struct AbilityNumber extends array
implement Alloc
integer abilityID
unit owner
framehandle buttonFrame
framehandle parentFrame
framehandle numberFrame
Link link
static timer Clock = null
static LinkedList list
public method setValue takes integer v returns nothing
call BlzFrameSetText(numberFrame,I2S(v))
endmethod
private static method Loop takes nothing returns nothing
local Link h = list.head
local thistype an
local integer lvl
local player p
loop
exitwhen h == 0
set an = h.data
set p = GetOwningPlayer(an.owner)
if IsUnitSelected(an.owner,p) then
set lvl = GetUnitAbilityLevel(an.owner,an.abilityID)
if lvl != 0 then
if Game.LocalPlayer == p or GetPlayerState(Game.LocalPlayer,PLAYER_STATE_OBSERVER) == 1 then
if BlzFrameIsVisible(an.buttonFrame) and ShowNumber() then
call BlzFrameSetVisible(an.parentFrame,true)
else
call BlzFrameSetVisible(an.parentFrame,false)
endif
endif
endif
else
call BlzFrameSetVisible(an.parentFrame,false)
endif
set h = h.next
endloop
set p = null
endmethod
public static method create takes integer a, unit u returns thistype
local thistype this = thistype.allocate()
set abilityID = a
set owner = u
set link = list.add(this)
set buttonFrame = GetCommandButtonFrameByXY.evaluate(BlzGetAbilityPosX(a),BlzGetAbilityPosY(a))
set parentFrame = BlzCreateSimpleFrame("AbilityNumberIcon",buttonFrame,a)
call BlzFrameSetPoint(parentFrame, FRAMEPOINT_BOTTOM, buttonFrame, FRAMEPOINT_BOTTOMRIGHT, -0.0085,0.001)
set numberFrame = BlzGetFrameByName("AbilityNumberText",a)
call BlzFrameSetTexture(BlzGetFrameByName("AbilityNumberTexture",a), "UI\\Widgets\\Console\\Human\\human-transport-slot", 0, true)
call BlzFrameSetLevel(parentFrame,9)
call BlzFrameSetText(numberFrame, "0")
call BlzFrameSetVisible(parentFrame,false)
if list.size == 1 then
call TimerStart(Clock,0.10,true,function thistype.Loop)
endif
return this
endmethod
endstruct
public function Setup takes nothing returns nothing
call BlzLoadTOCFile("war3mapImported\\AbilityNumber.toc")
set AbilityNumber.list = LinkedList.create()
set AbilityNumber.Clock = CreateTimer()
endfunction
endlibrary
scope PlayerPingUI
globals
private constant string PING_SFX = "war3mapImported\\exclamationsign.mdx"
endglobals
struct PlayerPing extends array
static trigger ClickEvent = null
static trigger CtrlPress = null
static trigger CtrlRelease = null
public static method CtrlP takes nothing returns nothing
local player p = GetTriggerPlayer()
local thistype this = thistype[GetPlayerId(p)]
set PlayerKeyData[GetPlayerId(p)].ctrl = true
set p = null
endmethod
public static method CtrlR takes nothing returns nothing
local player p = GetTriggerPlayer()
local thistype this = thistype[GetPlayerId(p)]
set PlayerKeyData[GetPlayerId(p)].ctrl = false
set p = null
endmethod
public static method Click takes nothing returns nothing
local player p = GetTriggerPlayer()
local integer id = GetPlayerId(p)
local thistype this = thistype[id]
local Players ps = Players[id]
local Team t = GetPlayerTeamEx(p)
local effect sfx = null
local string path = ""
local real sz = 0
local ARGB rgb
local integer o
local real x
local real y
local real xt
local real yt
if PlayerKeyData[id].ctrl and BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_LEFT then
set x = BlzGetTriggerPlayerMouseX()
set y = BlzGetTriggerPlayerMouseY()
set rgb = ARGB.fromPlayer(p)
if x != 0 and y != 0 then
set o = AIExtras_CheckForNearbyObjective.evaluate(x,y)
if o == -1 then
set xt = AncientObelisk.x
set yt = AncientObelisk.y
set sz = 0.25
if ps.AIPing_CD == 0 then
set ps.AIPing_CD = 5
call Message.ShowToForce(t.forceP,rgb.str(GetPlayerName(p))+"|r wants to fight within the Obelisk",MESSAGE_STYLE_KILL_HERO)
call AIExtras_AIAttendObjective.evaluate(t,0,0)
endif
elseif o > 0 then
if o < 10 then
set xt = Base[o].x
set yt = Base[o].y
set sz = 0.35
if ps.AIPing_CD == 0 then
set ps.AIPing_CD = 5
if Base[o].owner == 0 then
call Message.ShowToForce(t.forceP,ARGB.fromPlayer(p).str(GetPlayerName(p))+"|r wants to control the Tower",MESSAGE_STYLE_KILL_HERO)
elseif Base[o].owner == t then
call Message.ShowToForce(t.forceP,ARGB.fromPlayer(p).str(GetPlayerName(p))+"|r wants to defend the Tower",MESSAGE_STYLE_KILL_HERO)
else
call Message.ShowToForce(t.forceP,ARGB.fromPlayer(p).str(GetPlayerName(p))+"|r wants to attack the Tower",MESSAGE_STYLE_KILL_HERO)
endif
call AIExtras_AIAttendObjective.evaluate(t,o,0)
endif
else
set xt = GetUnitX(GoldMine[o-10].gold)
set yt = GetUnitY(GoldMine[o-10].gold)
set sz = 0.40
if ps.AIPing_CD == 0 then
set ps.AIPing_CD = 5
if GoldMine[o-10].owner == 0 then
call Message.ShowToForce(t.forceP,ARGB.fromPlayer(p).str(GetPlayerName(p))+"|r wants to control the Gold Mine",MESSAGE_STYLE_KILL_HERO)
elseif GoldMine[o-10].owner == t then
call Message.ShowToForce(t.forceP,ARGB.fromPlayer(p).str(GetPlayerName(p))+"|r wants to defend the Gold Mine",MESSAGE_STYLE_KILL_HERO)
else
call Message.ShowToForce(t.forceP,ARGB.fromPlayer(p).str(GetPlayerName(p))+"|r wants to attack the Gold Mine",MESSAGE_STYLE_KILL_HERO)
endif
call AIExtras_AIAttendObjective.evaluate(t,0,o-10)
endif
endif
else
set xt = x
set yt = y
set sz = 0.25
if ps.AIPing_CD == 0 then
set ps.AIPing_CD = 3
call AIExtras_AILookAtZone.evaluate(t,x,y,2000,2.0)
endif
endif
if IsPlayerAlly(Game.LocalPlayer,p) then
call PingMinimapEx(xt,yt,3.0,rgb.red,rgb.green,rgb.blue,true)
set path = PING_SFX
endif
set sfx = AddSpecialEffect(path,xt,yt)
call BlzSetSpecialEffectScale(sfx,sz)
call BlzSetSpecialEffectColorByPlayer(sfx,p)
call BlzSetSpecialEffectYaw(sfx,4.71239)
call DestroyEffect(sfx)
set sfx = null
endif
endif
set p = null
endmethod
public static method Init takes player p returns nothing
local thistype this = thistype[GetPlayerId(p)]
call TriggerRegisterPlayerEvent(ClickEvent, p, EVENT_PLAYER_MOUSE_UP)
call BlzTriggerRegisterPlayerKeyEvent(CtrlPress,p,OSKEY_LCONTROL,2,true)
call BlzTriggerRegisterPlayerKeyEvent(CtrlRelease,p,OSKEY_LCONTROL,0,false)
call BlzTriggerRegisterPlayerKeyEvent(CtrlRelease,p,OSKEY_LCONTROL,4,false)
endmethod
endstruct
public function SetupInit takes nothing returns nothing
set PlayerPing.ClickEvent = CreateTrigger()
set PlayerPing.CtrlPress = CreateTrigger()
set PlayerPing.CtrlRelease = CreateTrigger()
call TriggerAddAction(PlayerPing.ClickEvent,function PlayerPing.Click)
call TriggerAddAction(PlayerPing.CtrlPress,function PlayerPing.CtrlP)
call TriggerAddAction(PlayerPing.CtrlRelease,function PlayerPing.CtrlR)
call Preload(PING_SFX)
endfunction
endscope
scope UIItemUpgrade
globals
private framehandle array ItemUpButton[6]
private framehandle array ItemUpIcon[6]
private framehandle array ItemUpTooltip[6]
private framehandle array ItemUpTooltipText[6]
private framehandle array ItemEnButton[6]
private framehandle array ItemEnIcon[6]
private framehandle array ItemEnTooltip[6]
private framehandle array ItemEnTooltipText[6]
private Table ItemUpFrameIndex
private trigger KeyEvent
private constant string SFX_DONE = "Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl"
endglobals
public function HideButtons takes player p returns nothing
if Game.LocalPlayer == p then
call BlzFrameSetVisible(ItemUpButton[0],false)
call BlzFrameSetVisible(ItemUpButton[1],false)
call BlzFrameSetVisible(ItemUpButton[2],false)
call BlzFrameSetVisible(ItemUpButton[3],false)
call BlzFrameSetVisible(ItemUpButton[4],false)
call BlzFrameSetVisible(ItemUpButton[5],false)
call BlzFrameSetVisible(ItemEnButton[0],false)
call BlzFrameSetVisible(ItemEnButton[1],false)
call BlzFrameSetVisible(ItemEnButton[2],false)
call BlzFrameSetVisible(ItemEnButton[3],false)
call BlzFrameSetVisible(ItemEnButton[4],false)
call BlzFrameSetVisible(ItemEnButton[5],false)
endif
set PlayerKeyData[GetPlayerId(p)].alt = false
endfunction
private function Actions takes nothing returns nothing
local player p = GetTriggerPlayer()
local boolean showEn = false
local boolean showUp = false
local item temp = null
local integer i = 0
local string s1 = ""
local string s2 = ""
local string s3 = ""
local string s4 = ""
local Hero h
local Item it
local item ite
local Enchant e
if not PlayerKeyData[GetPlayerId(p)].alt then
set PlayerKeyData[GetPlayerId(p)].alt = true
set h = GetPlayerHero(p)
if h != 0 then
if UnitAlive(h.hero) and IsUnitSelected(h.hero,p) then
set e = GetUnitData(h.hero,"CURRENT_ENCHANT")
loop
set ite = UnitItemInSlot(h.hero,i)
set it = GetItemUserData(ite)
set showEn = false
set showUp = false
set s1 = ""
set s2 = ""
set s3 = ""
set s4 = ""
set temp = null
if it != 0 then
if it.itemType >= 2 then
if it.tier < 3 then
set showUp = true
set s1 = BuildText(it,it.tier + 1)
set s2 = "Previewing: "+ it.itemName + "|r - Tier "+I2S(it.tier + 1)
endif
if e != 0 then
if e.enchantType == ENCHANT_TYPE_ANY then
set showEn = true
set temp = CreateItem(e.enchantID,Game.HIDE_X,Game.HIDE_Y)
call SetItemVisible(temp,false)
set s3 = BlzGetItemExtendedTooltip(temp)
set s4 = BlzGetItemTooltip(temp)
if it.enchant != 0 then
set s3 = s3 + "|n|nThis item is already enchanted with: |cffb4b4b4"+ it.enchant.name+"|r"
endif
elseif e.enchantType == it.itemType then
set showEn = true
set temp = CreateItem(e.enchantID,Game.HIDE_X,Game.HIDE_Y)
call SetItemVisible(temp,false)
set s3 = BlzGetItemExtendedTooltip(temp)
set s4 = BlzGetItemTooltip(temp)
if it.enchant != 0 then
set s3 = s3 + "|n|nThis item is already enchanted with: |cffb4b4b4"+ it.enchant.name+"|r"
endif
endif
call RemoveItem(temp)
endif
if Game.LocalPlayer == p then
if showUp then
call BlzFrameSetVisible(ItemUpButton[i],true)
call BlzFrameSetText(ItemUpTooltipText[i],s2+"|n"+s1)
endif
if showEn then
call BlzFrameSetVisible(ItemEnButton[i],true)
call BlzFrameSetTexture(ItemEnIcon[i], e.iconPath, 0, true)
call BlzFrameSetText(ItemEnTooltipText[i],s4+"|n"+s3)
endif
endif
endif
endif
set i = i + 1
exitwhen i == 6
endloop
endif
endif
else
if PlayerKeyData[GetPlayerId(p)].alt then
set PlayerKeyData[GetPlayerId(p)].alt = false
call HideButtons(p)
endif
endif
set p = null
set temp = null
endfunction
private function ButtonClickAction takes nothing returns nothing
local framehandle frame = BlzGetTriggerFrame()
local player p = GetTriggerPlayer()
local integer index = ItemUpFrameIndex.integer[GetHandleId(frame)]
local Hero h = GetPlayerHero(p)
local integer g = GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)
local Enchant e
local item i
local Item it
local boolean b
local real x
local real y
local string s1 = ""
local string s2 = ""
if h != 0 then
set i = UnitItemInSlot(h.hero,index)
set it = GetItemUserData(i)
set x = GetUnitX(h.hero)
set y = GetUnitY(h.hero)
set b = IsHeroInBase(p) or GetUnitAbilityLevel(h.hero,'B05Q') != 0
if ItemUpButton[index] == frame then
if b and it != 0 and IsUnitSelected(h.hero,p) then
if not it.drooped then
if g >= 500 then
if it.tier < 3 then
call AddPlayerGold(p,-500)
call it.levelup()
call DestroyEffect(AddSpecialEffectTarget(SFX_DONE,h.hero,"origin"))
call PlaySoundForPlayer(p,gg_snd_UpgradeItem)
if it.tier < 3 then
set s1 = BuildText(it,it.tier + 1)
set s2 = "Previewing: "+ it.itemName + "|r - Tier "+I2S(it.tier + 1)
else
set s1 = "This item is already at max level"
set s2 = "Item Preview"
endif
if Game.LocalPlayer == p then
call BlzFrameSetText(ItemUpTooltipText[index],s2+"|n"+s1)
endif
else
call Message.ShowToPlayer(p,"The item is already at max level.",MESSAGE_STYLE_ERROR)
endif
else
call Message.ShowToPlayer(p,"Not enough gold (500) needed.",MESSAGE_STYLE_ERROR)
endif
endif
else
call Message.ShowToPlayer(p,"The hero need to be near a shop.",MESSAGE_STYLE_ERROR)
endif
endif
if ItemEnButton[index] == frame then
set e = GetUnitData(h.hero,"CURRENT_ENCHANT")
if b and it != 0 and IsUnitSelected(h.hero,p) and e != 0 then
if it.enchant.name != e.name then
if e.enchantType == ENCHANT_TYPE_ANY or it.tier == 3 then
if it.enchant != 0 then
call it.enchant.remove(it.wielder,it)
endif
set it.enchant = e
call e.add(h.hero,it)
call BlzSetItemExtendedTooltip(it.itemS,BuildText(it,it.tier))
call DestroyEffect(AddSpecialEffectTarget(SFX_DONE,h.hero,"origin"))
call SetUnitData(h.hero,"CURRENT_ENCHANT",0)
call Enchant_ResetEnchantAbility(p)
else
call Message.ShowToPlayer(p,"Only Items tier 3 can be enchanted with effect enchantment",MESSAGE_STYLE_ERROR)
endif
else
call Message.ShowToPlayer(p,"This Item has already enchanted with the same enchantment",MESSAGE_STYLE_ERROR)
endif
endif
endif
endif
if Game.LocalPlayer == p then
call BlzFrameSetEnable(frame, false)
call BlzFrameSetEnable(frame, true)
call StopCamera()
endif
set p = null
set frame = null
endfunction
public function SetupForPlayer takes player p returns nothing
call BlzTriggerRegisterPlayerKeyEvent(KeyEvent,p,OSKEY_LALT,0,false)
endfunction
public function Setup takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
set ItemUpFrameIndex = Table.create()
set KeyEvent = CreateTrigger()
call TriggerAddAction(KeyEvent,function Actions)
//call BlzLoadTOCFile("war3mapimported\\BoxedText.toc")
loop
set ItemUpButton[i] = BlzCreateFrameByType("GLUEBUTTON", "ItemUpButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", i)
set ItemUpIcon[i] = BlzCreateFrameByType("BACKDROP", "ItemUpIcon", ItemUpButton[i], "", 0)
call BlzFrameClearAllPoints(ItemUpButton[i])
call BlzFrameSetParent(ItemUpButton[i],BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON,i))
if i == 0 or i == 2 or i == 4 then
call BlzFrameSetPoint(ItemUpButton[i], FRAMEPOINT_BOTTOM, BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON,i), FRAMEPOINT_BOTTOMLEFT, -0.011,0.000)
else
call BlzFrameSetPoint(ItemUpButton[i], FRAMEPOINT_BOTTOM, BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON,i), FRAMEPOINT_BOTTOMRIGHT, 0.011,0.000)
endif
call BlzFrameSetTexture(ItemUpIcon[i], "ReplaceableTextures\\CommandButtons\\BTNItem_TierUp.blp", 0, true)
call BlzFrameSetSize(ItemUpButton[i], 0.017, 0.017)
call BlzFrameSetLevel(ItemUpButton[i],9)
call BlzFrameSetAllPoints(ItemUpIcon[i], ItemUpButton[i])
set ItemUpTooltip[i] = BlzCreateFrame("QuestButtonBaseTemplate", ItemUpButton[i], 0, i)
set ItemUpTooltipText[i] = BlzCreateFrameByType("TEXT", "MyScriptDialogButtonTooltip", ItemUpTooltip[i], "", i)
call BlzFrameSetSize(ItemUpTooltipText[i], 0.25, 0)
call BlzFrameSetPoint(ItemUpTooltip[i], FRAMEPOINT_BOTTOMLEFT, ItemUpTooltipText[i], FRAMEPOINT_BOTTOMLEFT, -0.01, -0.01)
call BlzFrameSetPoint(ItemUpTooltip[i], FRAMEPOINT_TOPRIGHT, ItemUpTooltipText[i], FRAMEPOINT_TOPRIGHT, 0.01, 0.01)
call BlzFrameSetTooltip(ItemUpButton[i], ItemUpTooltip[i])
call BlzFrameSetPoint(ItemUpTooltipText[i], FRAMEPOINT_BOTTOM, ItemUpButton[i], FRAMEPOINT_TOP, 0, 0.01)
call BlzFrameSetEnable(ItemUpTooltipText[i], false)
call BlzFrameSetVisible(ItemUpButton[i],false)
call BlzTriggerRegisterFrameEvent(t, ItemUpButton[i], FRAMEEVENT_CONTROL_CLICK)
set ItemUpFrameIndex.integer[GetHandleId(ItemUpButton[i])] = i
//For Enchant
set ItemEnButton[i] = BlzCreateFrameByType("GLUEBUTTON", "ItemEnButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 6+i)
call BlzFrameClearAllPoints(ItemEnButton[i])
set ItemEnIcon[i] = BlzCreateFrameByType("BACKDROP", "ItemEnIcon", ItemEnButton[i], "", 0)
call BlzFrameSetParent(ItemEnButton[i],BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON,i))
if i == 0 or i == 2 or i == 4 then
call BlzFrameSetPoint(ItemEnButton[i], FRAMEPOINT_BOTTOM, BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON,i), FRAMEPOINT_BOTTOMLEFT, -0.011,0.017)
else
call BlzFrameSetPoint(ItemEnButton[i], FRAMEPOINT_BOTTOM, BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON,i), FRAMEPOINT_BOTTOMRIGHT, 0.011,0.017)
endif
call BlzFrameSetTexture(ItemEnIcon[i], "ReplaceableTextures\\CommandButtons\\BTNINV_Enchant_FormulaEpic_01.blp", 0, true)
call BlzFrameSetSize(ItemEnButton[i], 0.017, 0.017)
call BlzFrameSetLevel(ItemEnButton[i],9)
call BlzFrameSetAllPoints(ItemEnIcon[i], ItemEnButton[i])
set ItemEnTooltip[i] = BlzCreateFrame("BoxedText", ItemEnButton[i], 0, 6+i)
set ItemEnTooltip[i] = BlzCreateFrame("QuestButtonBaseTemplate", ItemEnButton[i], 0, 6+i)
set ItemEnTooltipText[i] = BlzCreateFrameByType("TEXT", "MyScriptDialogButtonTooltip", ItemEnTooltip[i], "", 6+i)
call BlzFrameSetSize(ItemEnTooltipText[i], 0.25, 0)
call BlzFrameSetPoint(ItemEnTooltip[i], FRAMEPOINT_BOTTOMLEFT, ItemEnTooltipText[i], FRAMEPOINT_BOTTOMLEFT, -0.01, -0.01)
call BlzFrameSetPoint(ItemEnTooltip[i], FRAMEPOINT_TOPRIGHT, ItemEnTooltipText[i], FRAMEPOINT_TOPRIGHT, 0.01, 0.01)
call BlzFrameSetTooltip(ItemEnButton[i], ItemEnTooltip[i])
call BlzFrameSetPoint(ItemEnTooltipText[i], FRAMEPOINT_BOTTOM, ItemEnButton[i], FRAMEPOINT_TOP, 0, 0.01)
call BlzFrameSetEnable(ItemEnTooltipText[i], false)
call BlzFrameSetVisible(ItemEnButton[i],false)
call BlzTriggerRegisterFrameEvent(t, ItemEnButton[i], FRAMEEVENT_CONTROL_CLICK)
set ItemUpFrameIndex.integer[GetHandleId(ItemEnButton[i])] = i
set i = i + 1
exitwhen i == 6
endloop
call TriggerAddAction(t, function ButtonClickAction)
set t = null
endfunction
endscope
scope GameButtons initializer Init
globals
framehandle CommanderButtonFrame
framehandle CommanderIconFrame
framehandle WarHallButtonFrame
framehandle WarHallIconFrame
framehandle StashButtonFrame
framehandle StashIconFrame
framehandle HumanResourcesFrame
framehandle HumanResourcesTextFrame
framehandle OrcResourcesFrame
framehandle OrcResourcesTextFrame
framehandle BigTextMessageFrame
framehandle BigTextMessageFrame2
framehandle array HeroesButton[9]
framehandle array HeroesIcon[9]
framehandle array HeroesIconText[9]
framehandle array HeroesLevelIcon[9]
framehandle array HeroesLevelIconText[9]
endglobals
private function ClickIconHero takes nothing returns nothing
local framehandle f = BlzGetTriggerFrame()
local player p = GetTriggerPlayer()
local Hero h
local integer i = 0
loop
exitwhen i == 9
if f == HeroesButton[i] then
set h = GetPlayerHero(Player(i + 2))
if h != 0 then
if Game.LocalPlayer == p then
call SelectUnit(h.hero,true)
call SetCameraPosition(GetUnitX(h.hero),GetUnitY(h.hero))
endif
endif
exitwhen true
endif
set i = i + 1
endloop
set f = null
set p = null
endfunction
public function HeroesUI takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
call TriggerAddAction(t, function ClickIconHero)
loop
set HeroesButton[i] = BlzCreateFrameByType("GLUEBUTTON", "HeroButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", i)
set HeroesIcon[i] = BlzCreateFrameByType( "BACKDROP", "HeroIcon", HeroesButton[i], "", i )
call BlzFrameSetAllPoints(HeroesIcon[i], HeroesButton[i])
if i >= 5 then
//call BlzFrameSetAbsPoint(HeroesIcon[i], FRAMEPOINT_CENTER, 0.51 + 0.035 * (i - 5), 0.56 )
call BlzFrameSetAbsPoint(HeroesButton[i], FRAMEPOINT_CENTER, 0.51 + 0.035 * (i - 5), 0.56 )
else
//call BlzFrameSetAbsPoint(HeroesIcon[i], FRAMEPOINT_CENTER, 0.29 - 0.035 * (i), 0.56 )
call BlzFrameSetAbsPoint(HeroesButton[i], FRAMEPOINT_CENTER, 0.29 - 0.035 * (i), 0.56 )
endif
call BlzFrameSetEnable(HeroesButton[i],true)
call BlzFrameSetSize(HeroesIcon[i], 0.035,0.035 )
call BlzFrameSetSize(HeroesButton[i], 0.035, 0.035)
call BlzFrameSetTexture(HeroesIcon[i], "UI\\Widgets\\Glues\\GlueScreen-Checkbox-Background",0, true)
//-----
set HeroesIconText[i] = BlzCreateFrameByType( "TEXT", "HeroIconText", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", i )
call BlzFrameSetPoint(HeroesIconText[i],FRAMEPOINT_CENTER,HeroesIcon[i],FRAMEPOINT_CENTER,0,0)
call BlzFrameSetVisible(HeroesIconText[i],false)
call BlzFrameSetScale(HeroesIconText[i], 2.0 )
//call BlzFrameSetLevel(HeroesIconText[i],1)
//-----
set HeroesLevelIcon[i] = BlzCreateFrameByType( "BACKDROP", "HeroLevelIcon", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", i )
call BlzFrameSetPoint(HeroesLevelIcon[i],FRAMEPOINT_BOTTOMRIGHT,HeroesIcon[i],FRAMEPOINT_BOTTOMRIGHT,0,0)
call BlzFrameSetSize(HeroesLevelIcon[i], 0.015,0.015 )
call BlzFrameSetTexture(HeroesLevelIcon[i], "UI\\Widgets\\Glues\\GlueScreen-Checkbox-Background",0, true)
set HeroesLevelIconText[i] = BlzCreateFrameByType( "TEXT", "HeroLevelIconText", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", i )
call BlzFrameSetPoint(HeroesLevelIconText[i],FRAMEPOINT_CENTER,HeroesLevelIcon[i],FRAMEPOINT_CENTER,0,0)
call BlzFrameSetVisible(HeroesLevelIconText[i],false)
call BlzFrameSetScale(HeroesLevelIconText[i], 0.80 )
call BlzFrameSetText(HeroesLevelIconText[i],"0")
call BlzTriggerRegisterFrameEvent(t, HeroesButton[i], FRAMEEVENT_CONTROL_CLICK)
set i = i + 1
exitwhen i == 10
endloop
endfunction
public function ResourcesUI takes nothing returns nothing
set HumanResourcesFrame = BlzCreateFrameByType( "BACKDROP", "HumanResources", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", 0 )
call BlzFrameSetAbsPoint(HumanResourcesFrame, FRAMEPOINT_CENTER, 0.46, 0.56 )
call BlzFrameSetSize(HumanResourcesFrame , 0.070,0.035 )
call BlzFrameSetTexture(HumanResourcesFrame, "ui\\widgets\\console\\human\\human-transport-slot",0, true)
set HumanResourcesTextFrame = BlzCreateFrameByType( "TEXT", "HumanResourcesText", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", 0 )
call BlzFrameSetPoint(HumanResourcesTextFrame,FRAMEPOINT_CENTER,HumanResourcesFrame,FRAMEPOINT_CENTER,0,0)
call BlzFrameSetText(HumanResourcesTextFrame , ALLIANCE_COLOR+I2S(0)+"|r")
call BlzFrameSetScale(HumanResourcesTextFrame , 2.0 )
//----------------
set OrcResourcesFrame = BlzCreateFrameByType( "BACKDROP", "OrcResources", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", 0 )
call BlzFrameSetAbsPoint(OrcResourcesFrame , FRAMEPOINT_CENTER, 0.34, 0.56 )
call BlzFrameSetSize(OrcResourcesFrame, 0.070,0.035 )
call BlzFrameSetTexture(OrcResourcesFrame, "ui\\widgets\\console\\human\\human-transport-slot",0, true)
set OrcResourcesTextFrame = BlzCreateFrameByType( "TEXT", "OrcResourcesText", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", 0 )
call BlzFrameSetPoint(OrcResourcesTextFrame,FRAMEPOINT_CENTER,OrcResourcesFrame,FRAMEPOINT_CENTER,0,0)
call BlzFrameSetText(OrcResourcesTextFrame, HORDE_COLOR+I2S(0)+"|r")
call BlzFrameSetScale(OrcResourcesTextFrame, 2.0 )
endfunction
private function ButtonClickAction takes nothing returns nothing
local framehandle frame = BlzGetTriggerFrame()
local player p = GetTriggerPlayer()
local Team t = GetPlayerTeamEx(p)
if frame == CommanderButtonFrame then
if t != 0 then
if IsUnitSelected(t.commander.heroUnit,p) then
call SetCameraPositionForPlayer(p,GetUnitX(t.commander.heroUnit),GetUnitY(t.commander.heroUnit))
else
call SelectUnitForPlayer(t.commander.heroUnit,p,true)
endif
endif
endif
if frame == WarHallButtonFrame then
if t != 0 then
if IsUnitSelected(t.warHall,p) then
call SetCameraPositionForPlayer(p,GetUnitX(t.warHall),GetUnitY(t.warHall))
else
call SelectUnitForPlayer(t.warHall,p,true)
endif
endif
endif
if frame == StashButtonFrame then
if t != 0 then
if IsUnitSelected(Baul[GetPlayerId(p)],p) then
call SetCameraPositionForPlayer(p,GetUnitX(Baul[GetPlayerId(p)]),GetUnitY(Baul[GetPlayerId(p)]))
else
call SelectUnitForPlayer(Baul[GetPlayerId(p)],p,true)
endif
endif
endif
if Game.LocalPlayer == p then
call BlzFrameSetEnable(frame, false)
call BlzFrameSetEnable(frame, true)
call StopCamera()
endif
set p = null
set frame = null
endfunction
public function CreateBotLeftButtons takes nothing returns nothing
local trigger t = CreateTrigger()
set CommanderButtonFrame = BlzCreateFrameByType("GLUEBUTTON", "CommanderButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
set CommanderIconFrame = BlzCreateFrameByType("BACKDROP", "CommanderButtonIcon", CommanderButtonFrame, "", 0)
set WarHallButtonFrame = BlzCreateFrameByType("GLUEBUTTON", "WarHallButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
set WarHallIconFrame = BlzCreateFrameByType("BACKDROP", "WarHallButtonIcon", WarHallButtonFrame, "", 0)
set StashButtonFrame = BlzCreateFrameByType("GLUEBUTTON", "StashButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
set StashIconFrame = BlzCreateFrameByType("BACKDROP", "StashButtonIcon", StashButtonFrame, "", 0)
//-
call BlzFrameSetAllPoints(CommanderIconFrame, CommanderButtonFrame)
call BlzFrameSetTexture(CommanderIconFrame, "ReplaceableTextures\\CommandButtons\\BTNINV_helm_crown_C_01_silver", 0, true)
call BlzFrameSetAbsPoint(CommanderButtonFrame, FRAMEPOINT_BOTTOMLEFT, 0.04, 0.16)
//call BlzFrameSetLevel(CommanderButtonFrame,0)
call BlzFrameSetSize(CommanderButtonFrame, 0.035, 0.035)
call BlzFrameSetVisible(CommanderButtonFrame,false)
//-
call BlzFrameSetAllPoints(WarHallIconFrame, WarHallButtonFrame)
if IsPlayerInForce(Game.LocalPlayer,Team[1].forceP) then
call BlzFrameSetTexture(WarHallIconFrame, "ReplaceableTextures\\CommandButtons\\BTNFortress", 0, true)
else
call BlzFrameSetTexture(WarHallIconFrame, "ReplaceableTextures\\CommandButtons\\BTNCastle", 0, true)
endif
call BlzFrameSetAbsPoint(WarHallButtonFrame, FRAMEPOINT_BOTTOMLEFT, 0.08, 0.16)
//call BlzFrameSetLevel(WarHallButtonFrame,0)
call BlzFrameSetSize(WarHallButtonFrame, 0.035, 0.035)
call BlzFrameSetVisible(WarHallButtonFrame,false)
//-
call BlzFrameSetAllPoints(StashIconFrame, StashButtonFrame)
if IsPlayerInForce(Game.LocalPlayer,Team[2].forceP) then
call BlzFrameSetTexture(StashIconFrame, "ReplaceableTextures\\CommandButtons\\BTNFarm", 0, true)
else
call BlzFrameSetTexture(StashIconFrame, "ReplaceableTextures\\CommandButtons\\BTNPigFarm", 0, true)
endif
call BlzFrameSetAbsPoint(StashButtonFrame, FRAMEPOINT_BOTTOMLEFT, 0.0, 0.16)
//call BlzFrameSetLevel(StashButtonFrame,0)
call BlzFrameSetSize(StashButtonFrame, 0.035, 0.035)
call BlzFrameSetVisible(StashButtonFrame,false)
//-
if not IsPlayerObserver(Game.LocalPlayer) then
call BlzFrameSetVisible(CommanderButtonFrame,true)
call BlzFrameSetVisible(WarHallButtonFrame,true)
call BlzFrameSetVisible(StashButtonFrame,true)
endif
//Events
call TriggerAddAction(t, function ButtonClickAction)
call BlzTriggerRegisterFrameEvent(t, CommanderButtonFrame, FRAMEEVENT_CONTROL_CLICK)
call BlzTriggerRegisterFrameEvent(t, WarHallButtonFrame, FRAMEEVENT_CONTROL_CLICK)
call BlzTriggerRegisterFrameEvent(t, StashButtonFrame, FRAMEEVENT_CONTROL_CLICK)
set t = null
endfunction
public function ChangeBigMessageText takes integer x returns nothing
if x == 0 then
call BlzFrameSetVisible(BigTextMessageFrame,false)
call BlzFrameSetVisible(BigTextMessageFrame2,false)
return
endif
call BlzFrameSetText(BigTextMessageFrame,HORDE_COLOR+"GAME STARTS IN: |r" + I2S(x))
call BlzFrameSetText(BigTextMessageFrame2,"|cff000000GAME STARTS IN: " + I2S(x) + "|r")
call BlzFrameSetVisible(BigTextMessageFrame,true)
call BlzFrameSetVisible(BigTextMessageFrame2,true)
endfunction
private function Init takes nothing returns nothing
set BigTextMessageFrame = BlzCreateFrameByType( "TEXT", "BigMessageText", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", 0 )
set BigTextMessageFrame2 = BlzCreateFrameByType( "TEXT", "BigMessageText2", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI,0), "", 0 )
call BlzFrameSetAbsPoint(BigTextMessageFrame, FRAMEPOINT_TOP, 0.40 , 0.50 )
call BlzFrameSetScale(BigTextMessageFrame, 2.50)
call BlzFrameSetEnable(BigTextMessageFrame,true)
call BlzFrameSetVisible(BigTextMessageFrame,false)
call BlzFrameSetLevel(BigTextMessageFrame,1)
call BlzFrameSetAbsPoint(BigTextMessageFrame2, FRAMEPOINT_TOP, 0.40 , 0.498 )
call BlzFrameSetScale(BigTextMessageFrame2, 2.50)
call BlzFrameSetEnable(BigTextMessageFrame2,true)
call BlzFrameSetVisible(BigTextMessageFrame2,false)
call BlzFrameSetLevel(BigTextMessageFrame2,0)
endfunction
endscope
library GameConstants uses MiscLibrary
globals
constant integer GAME_MODE_NORMAL = 1
constant integer GAME_MODE_LMS = 2
constant integer GAME_MODE_OD = 3
endglobals
struct Game extends array
public static constant real CAMERA_SMOTH_FACTOR = 17
public static constant player PLAYER_NEUTRAL_HOSTILE = Player(PLAYER_NEUTRAL_AGGRESSIVE)
public static constant player PLAYER_NEUTRAL_EXTRA = Player(PLAYER_NEUTRAL_PASSIVE)
public static constant player PLAYER_WARCHIEF_HORDE = Player(0)
public static constant player PLAYER_WARCHIEF_ALLIANCE = Player(1)
public static constant integer PLAYER_MAX = 11
public static constant real PLAYER_NEUTRAL_HANDICAP = 1.0
public static constant integer PLAYER_INITIAL_GOLD = 300
public static constant integer PICK_TIME = 90
public static real TIME_TO_INIT_GAME = 90
public static constant real TIME_OF_DAY = 6.00
public static constant real HIDE_X = 6528
public static constant real HIDE_Y = -6907
public static constant integer FACTION_NEUTRAL = 0
public static constant integer FACTION_HUMAN = 1
public static constant integer FACTION_ORC = 2
public static constant integer FACTION_NIGHTELF = 3
public static constant integer FACTION_UNDEAD = 4
public static constant integer FLAG_NO_COMBAT = 'A00F'
public static constant integer FLAG_WARD = 'A04R'
public static constant integer FLAG_NO_AGGRO = 'A06E'
public static constant integer FLAG_HERO_CREEP = 'A089'
public static constant integer FLAG_DISABLED = 'A0CS'
public static constant integer DUMMY_CASTER = 'u001'
public static constant integer DEFAULT_CAMERA = 1800
static player FirstPlayer = null
static player LocalPlayer = null
static real TIME_PRELOADING = 12.00
static boolean GameStarted = false
static boolean CreepsSpawned = false
static boolean IsSinglePlayer = false
static boolean IsReplay = false
static boolean IsOnline = false
static boolean GameOver = false
static boolean TestMode = false
static Team Winner = 0
static integer ResourcesToWin = 3000
//LMS
static integer Rounds = 15
static integer Round = 0
static boolean RoundStarted = false
static string FireworksSfx = "Abilities\\Spells\\Human\\Flare\\FlareTarget.mdl"
static integer Mode
static integer PickDuration = 0
static unit LockCamera = null
static fogmodifier VisionTeam1 = null
static fogmodifier VisionTeam2 = null
public static method DefineVariables takes nothing returns nothing
set LocalPlayer = GetLocalPlayer()
set IsSinglePlayer = true
set CreepsSpawned = false
set Mode = 0
endmethod
endstruct
endlibrary
scope Initialization initializer init
globals
private constant string PRELOAD_MSG = "PRELOADING OBJECTS, PLEASE WAIT"
string HIGHLIGHT = "|cff99b4d1"
timerdialog GameModeDialog
timer GameModeTimer
group Shops
endglobals
private function CreateTextForMerchant takes string str, unit u returns nothing
local texttag txt = CreateTextTag()
call SetTextTagText(txt,"|cff8080ff"+str+"|r",TextTagSize2Height(10))
call SetTextTagPermanent(txt,true)
call SetTextTagPos(txt,GetUnitX(u) - 60,GetUnitY(u),150)
set txt = null
endfunction
private function UnPauseAllBaseUnits takes nothing returns nothing
local unit temp
loop
set temp = FirstOfGroup(Shops)
exitwhen temp == null
call GroupRemoveUnit(Shops,temp)
call UnitAddAbility(temp,'Aneu')
endloop
call ReleaseGroup(Shops)
set Shops = null
endfunction
private function PauseAllBaseUnits takes nothing returns nothing
local group g = NewGroup()
local unit temp
set Shops = NewGroup()
call GroupEnumUnitsInRect(g,gg_rct_PickItemsAlliance,null)
loop
set temp = FirstOfGroup(Shops)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if GetUnitAbilityLevel(temp,'Apit') != 0 then
call UnitRemoveAbility(temp,'Aneu')
call GroupAddUnit(Shops,temp)
endif
endloop
call GroupEnumUnitsInRect(g,gg_rct_PickItemsHorde,null)
loop
set temp = FirstOfGroup(Shops)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if GetUnitAbilityLevel(temp,'Apit') != 0 then
call UnitRemoveAbility(temp,'Aneu')
call GroupAddUnit(Shops,temp)
endif
endloop
call ReleaseGroup(g)
endfunction
private function InitEnviromentFix takes nothing returns nothing
//Doodads Tower
call SetDoodadAnimationRect(bj_mapInitialPlayableArea, 'D001', "stand ready attack",false)
//Mine
call SetBuildingFacing(gg_unit_n00N_0058,160)
call SetBuildingFacing(gg_unit_n00N_0033,35)
call SetBuildingFacing(gg_unit_n00N_0118,335)
call SetBuildingFacing(gg_unit_n00N_0117,220)
//Spell Enhancement
call SetBuildingFacing(gg_unit_n007_0063,70)
call SetUnitAnimation(gg_unit_n007_0063,"stand work")
//call SetBuildingFacing(gg_unit_n004_0176,20)
call SetUnitAnimation(gg_unit_n004_0176,"stand work")
//Shops Facing
//Horde
call SetBuildingFacing(gg_unit_n00O_0246,90) //Armor 1
call CreateTextForMerchant("Armor 1",gg_unit_n00O_0246)
call SetBuildingFacing(gg_unit_n00P_0044,90) //Armor 2
call CreateTextForMerchant("Armor 2",gg_unit_n00P_0044)
call SetBuildingFacing(gg_unit_n00T_0250,90) //Weapon 1
call CreateTextForMerchant("Weapon 1",gg_unit_n00T_0250)
call SetBuildingFacing(gg_unit_n012_0108,90) //Weapon 2
call CreateTextForMerchant("Weapon 2",gg_unit_n012_0108)
call SetBuildingFacing(gg_unit_n00E_0258,135) //Magic Accs 1
call CreateTextForMerchant("Magic 1",gg_unit_n00E_0258)
call SetBuildingFacing(gg_unit_n00Z_0106,135) //Magic Accs 2
call CreateTextForMerchant("Magic 2",gg_unit_n00Z_0106)
call SetBuildingFacing(gg_unit_n00U_0256,180) //trinkets 1
call CreateTextForMerchant("Trinket 1",gg_unit_n00U_0256)
call SetBuildingFacing(gg_unit_n01A_0062,180) //trinket 2
call CreateTextForMerchant("Trinket 2",gg_unit_n01A_0062)
call SetBuildingFacing(gg_unit_n00B_0048,45) //Consumables
call CreateTextForMerchant("Consumables",gg_unit_n00B_0048)
call SetBuildingFacing(gg_unit_n000_0254,305) //market
call CreateTextForMerchant("Starting Items",gg_unit_n000_0254)
//Alliance
call SetBuildingFacing(gg_unit_n00A_0045,290) //Armor 1
call CreateTextForMerchant("Armor 1",gg_unit_n003_0245)
call SetBuildingFacing(gg_unit_n003_0245,270) //Armor 2
call CreateTextForMerchant("Armor 2",gg_unit_n00A_0045)
call SetBuildingFacing(gg_unit_ma00_0249,270) //Weapon 1
call CreateTextForMerchant("Weapon 1",gg_unit_ma00_0249)
call SetBuildingFacing(gg_unit_n011_0032,270) //Weapon 2
call CreateTextForMerchant("Weapon 2",gg_unit_n011_0032)
call SetBuildingFacing(gg_unit_n001_0257,315) //Magic Accs 1
call CreateTextForMerchant("Magic 1",gg_unit_n001_0257)
call SetBuildingFacing(gg_unit_n010_0096,315) //Magic Accs 2
call CreateTextForMerchant("Magic 2",gg_unit_n010_0096)
call SetBuildingFacing(gg_unit_n00D_0012,0) //Trinket 1
call CreateTextForMerchant("Trinket 1",gg_unit_n00D_0012)
call SetBuildingFacing(gg_unit_n01B_0061,0) //Trinket 2
call CreateTextForMerchant("Trinket 2",gg_unit_n01B_0061)
call SetBuildingFacing(gg_unit_n00B_0248,225) //Consumables
call CreateTextForMerchant("Consumables",gg_unit_n00B_0248)
call SetBuildingFacing(gg_unit_n000_0253,270) //Market
call CreateTextForMerchant("Starting Items",gg_unit_n000_0253)
call PauseAllBaseUnits()
endfunction
private function callbackPause takes nothing returns nothing
call UnPauseAllBaseUnits()
call ReleaseTimer(GetExpiredTimer())
endfunction
private function InitGame takes nothing returns boolean
call StartSound(gg_snd_GameStart)
call ModifyGateBJ( bj_GATEOPERATION_DESTROY, gg_dest_Dofv_3954 )
call ModifyGateBJ( bj_GATEOPERATION_DESTROY, gg_dest_Dofv_3955 )
call SuspendTimeOfDay(false)
call GameButtons_CreateBotLeftButtons.evaluate()
call CommanderLib_Setup()
call BlzStartUnitAbilityCooldown(Team[1].warHall,'A0BJ',600)
call BlzStartUnitAbilityCooldown(Team[2].warHall,'A0BJ',600)
call BlzStartUnitAbilityCooldown(Team[1].warHall,'A02U',600)
call BlzStartUnitAbilityCooldown(Team[2].warHall,'A02U',600)
call BlzStartUnitAbilityCooldown(Team[1].warHall,'A0BK',600)
call BlzStartUnitAbilityCooldown(Team[2].warHall,'A0BK',600)
call BlzStartUnitAbilityCooldown(Team[1].warHall,'A0D9',600)
call BlzStartUnitAbilityCooldown(Team[2].warHall,'A0D9',600)
call BlzUnitDisableAbility(Team[1].warHall,'A0BJ',false,false)
call BlzUnitDisableAbility(Team[2].warHall,'A0BJ',false,false)
call BlzUnitDisableAbility(Team[1].warHall,'A02U',false,false)
call BlzUnitDisableAbility(Team[2].warHall,'A02U',false,false)
call BlzUnitDisableAbility(Team[1].warHall,'A0BK',false,false)
call BlzUnitDisableAbility(Team[2].warHall,'A0BK',false,false)
set GameLoop.Minutes = 0
set GameLoop.Seconds = 0
set Game.GameStarted = true
call PauseTimer(GameModeTimer)
call DestroyTimer(GameModeTimer)
set GameModeTimer = null
return false
endfunction
private function PickHeroesEnd takes nothing returns nothing
local integer i = 2
local player p
local string n = ""
local Hero h
loop
set p = Player(i)
set h = GetPlayerHero(p)
if Players[i].isPlaying then
if h == 0 then
call HeroSelectorForcePickPlayer(p)
set h = GetPlayerHero(p)
endif
call HeroSelectorShowPlayer(false,p)
call GameMultiboard_ShowForPlayer.evaluate(p,true)
call BlzUnitDisableAbility(h.hero,'Amov',false,false)
call UnitRemoveAbility(h.hero,'Abun')
call PauseUnit(Baul[i],false)
call SetCameraPositionForPlayer(p,GetPlayerStartLocationX(p),GetPlayerStartLocationY(p))
if p != Game.PLAYER_WARCHIEF_HORDE and p != Game.PLAYER_WARCHIEF_ALLIANCE then
if GetPlayerController(p) == MAP_CONTROL_COMPUTER then
set n = Players[i].ai+I2S(i-1)+" ("+h.Name+")"
call SetPlayerName(p,n)
set Players[i].name = n
call MultiboardUpdatePlayerName(p,n)
call Players[i].hero.heroAI.itemBuild.purchaseStartingItems()
call Players[i].hero.heroAI.itemBuild.purchaseItem(true)
else
set n = GetPlayerName(p)+" ("+h.Name+")"
call SetPlayerName(p,n)
endif
endif
if Game.LocalPlayer == p then
call EnablePreSelect( true, true )
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
call ReleaseTimer(GetExpiredTimer())
call LoadFunction.Destroy()
call DestroyFogModifier(Game.VisionTeam1)
call DestroyFogModifier(Game.VisionTeam2)
set Game.VisionTeam1 = null
set Game.VisionTeam2 = null
call ShowUnit(Game.LockCamera,false)
call ShowUnit(gg_unit_n00C_0039,true)
set GameLoop.Minutes = 0
set GameLoop.Seconds = 0
call HeroSelectorDestroy()
if Game.Mode == GAME_MODE_NORMAL then
set GameModeTimer = CreateTimer()
call TimerStart(GameModeTimer,Game.TIME_TO_INIT_GAME,false,function InitGame)
call GameButtons_ChangeBigMessageText.evaluate(R2I(Game.TIME_TO_INIT_GAME))
endif
//----------------
call UnPauseAllBaseUnits()
set p = null
endfunction
private function GameModeEnd takes nothing returns nothing
call TimerDialogDisplay(GameModeDialog,false)
call DestroyTimerDialog(GameModeDialog)
call PauseTimer(GameModeTimer)
call DestroyTimer(GameModeTimer)
set GameModeTimer = null
set GameModeDialog = null
call GameMode.verifyWinner()
call Players.RemoveVotingUnits()
call GameButtons_ResourcesUI()
call GameButtons_HeroesUI()
if GameMode.winner.name == "Normal" or GameMode.winner == 0 then
set Game.Mode = GAME_MODE_NORMAL
if GameMode.winner == 0 then
call Message.Show("The "+HIGHLIGHT+"Normal Game|r"+" mode has been selected by default",MESSAGE_STYLE_INFO)
else
call Message.Show("The "+HIGHLIGHT+"Normal Game|r"+" mode has been selected by voting",MESSAGE_STYLE_INFO)
endif
call Message.Show("Choose your Hero, battle starts in 2 Min",MESSAGE_STYLE_INFO)
call RemoveWalls.execute(1)
call Hostile_Setup()
call BaseLib_Setup()
call GoldMine_GSetup()
call GuardPath_Setup()
call AncientObelisk_Setup()
call DefenderSquad_Setup.evaluate()
call WarHall_Setup.evaluate()
call WarTroops_Setup()
call TimerStart(NewTimer(),Game.PICK_TIME,false,function PickHeroesEnd)
endif
if GameMode.winner.name == "Last Man Standing" then
set Game.Mode = GAME_MODE_LMS
call Message.Show("The "+HIGHLIGHT+"Last Man Standing|r"+" mode has been selected by voting",MESSAGE_STYLE_INFO)
call Message.Show("Choose your Hero, the first round will begin in 2 min",MESSAGE_STYLE_LMS)
call RemoveWalls.execute(2)
call RemoveUnit(gg_unit_n00C_0039)
call LastManStanding_Setup.evaluate()
call LastManStanding_Start.evaluate()
set Game.GameStarted = true
call TimerStart(NewTimer(),Game.PICK_TIME,false,function PickHeroesEnd)
endif
/*if GameMode.winner.name == "Obelisk Defend" then
set Game.Mode = GAME_MODE_OD
call Message.Show("The "+HIGHLIGHT+"Obelisk Defend|r"+" mode has been selected by voting",MESSAGE_STYLE_INFO)
call Message.Show("Choose your Hero, the first round will begin in 2 min",MESSAGE_STYLE_LMS)
call RemoveWalls.execute(2)
call AncientObelisk_Setup()
call UnitRemoveAbility(AncientObelisk.obelisk,'Avul')
call ObeliskDefend_Setup.evaluate()
call ObeliskDefend_Start.evaluate()
set Game.GameStarted = true
call TimerStart(NewTimer(),Game.PICK_TIME,false,function PickHeroesEnd)
endif*/
call GameModes_End()
call Runes_Setup()
call GameMultiboard_Setup()
call HeroSelectorInit()
call HeroSelectorShowPlayer(true,Game.LocalPlayer)
call HeroSelectorEnablePick(true)
set Game.PickDuration = Game.PICK_TIME
call HeroSelectorSetTitleText("Pick a Hero: "+I2S(Game.PickDuration))
call GameLoop.Start()
endfunction
private function PresentationMessage takes nothing returns nothing
call DisplayTimedTextToPlayer(Game.LocalPlayer,0.8,0.7,300.0," |c00ffcc00GOLDEN LANDS v5|r ")
call DisplayTimedTextToPlayer(Game.LocalPlayer,0.8,0.7,300.0," |c00808080Preloading, Please wait.|r")
endfunction
private function InitCamera takes nothing returns nothing
call FogMaskEnable(false)
//call ShowInterface(false, 0.00 )
//call EnableUserControl(false)
call CinematicFadeBJ( bj_CINEFADETYPE_FADEOUT, 0, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
//call BlzHideCinematicPanels(true)
endfunction
private function SetupGame takes nothing returns boolean
call Game.DefineVariables()
call PresentationMessage()
set ON_INDEX = Event.create()
set ON_DEINDEX = Event.create()
call IndexEvent_Setup()
call DamageEngineInit.evaluate()
call UnitIndex_Setup()
call IsUnitMoving_Setup()
set ENABLE_INDEXER = false
call PreloadGen.Start()
call FogEnable(false)
call FogEnable(true)
//Misc Stuff
call SetMapFlag(MAP_LOCK_RESOURCE_TRADING, true)
//call CameraSetSmoothingFactor(Game.CAMERA_SMOTH_FACTOR)
//Misc Stuff
call TriggerSleepAction(Game.TIME_PRELOADING)
set ENABLE_INDEXER = true
call SetFloatGameState(GAME_STATE_TIME_OF_DAY,Game.TIME_OF_DAY)
call SuspendTimeOfDay(true)
//Not Related GamePlay initializations
call InitEnviromentFix()
call MapInfo_Setup()
call TreeRespawn_Setup()
//Not Related GamePlay initializations
//Core
call Message_init()
call TeamLib_Setup()
call ShowUnit(gg_unit_n00C_0039,false)
call UIMisc_init.execute()
call PlayerPingUI_SetupInit()
call UIAbilityNumber_Setup()
call UIItems_Setup.evaluate()
call UIItemUpgrade_Setup.evaluate()
call PlayerLib_Setup()
call PlayerLib_Observer()
//call PlayerKeyData.Initialize()
call InCombat_Setup()
call BountyExp_Setup()
//Core
//Items
call Enchant_Setup()
call WeaponData_Setup.execute()
call ArmorData_Setup.execute()
call TrinketData_Setup.execute()
call MagicData_Setup.execute()
call ConsumableData_Setup.execute()
call MiscData_Setup.execute()
//Items
//AI
call ItemBuild_Setup()
call AIRegion.Init()
//AI
call DamageTextTag_Setup()
call Perks_Setup()
call AbilityLibrary_Setup()
call Teleport_Setup.execute()
//call GateTower_Setup.execute()
set Game.VisionTeam1 = CreateFogModifierRadius(Player(0),FOG_OF_WAR_VISIBLE,GetRectCenterX(gg_rct_ObeliskArea),GetRectCenterY(gg_rct_ObeliskArea),800,true,false)
set Game.VisionTeam2 = CreateFogModifierRadius(Player(1),FOG_OF_WAR_VISIBLE,GetRectCenterX(gg_rct_ObeliskArea),GetRectCenterY(gg_rct_ObeliskArea),800,true,false)
call FogModifierStart(Game.VisionTeam1)
call FogModifierStart(Game.VisionTeam2)
set Game.LockCamera = CreateUnit(Game.PLAYER_NEUTRAL_EXTRA,'u000',GetRectCenterX(gg_rct_ObeliskArea),GetRectCenterY(gg_rct_ObeliskArea) + 175,0)
call UnitAddAbility(Game.LockCamera,'A06E')
if GetPlayerState(Game.LocalPlayer,PLAYER_STATE_OBSERVER) == 0 then
call SetCameraTargetController(Game.LockCamera, 0, 0, false)
endif
//call ShowInterface(true, 3 )
//call EnableUserControl(true)
call CinematicFadeBJ( bj_CINEFADETYPE_FADEIN, 3, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
//call BlzHideCinematicPanels(false)
call ClearTextMessages()
call GameModes_Setup()
set GameModeTimer = CreateTimer()
set GameModeDialog = CreateTimerDialog(GameModeTimer)
call TimerDialogSetTitle(GameModeDialog,"Voting Time:")
call TimerDialogDisplay(GameModeDialog,true)
call TimerStart(GameModeTimer,10.00,false,function GameModeEnd)
call Message.Show("The Players have 10 seconds to select the game mode",MESSAGE_STYLE_INFO)
call DestroyTrigger(GetTriggeringTrigger())
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterTimerEvent(t,0.1,false)
//call SetTerrainFogEx(0, 0, 6000, 0, 0.7, 0.9, 0.7)
call SetTerrainFogEx(0, 0, 5000, 1.0, 0.9, 0.49, 0.17)
call InitCamera()
call TriggerAddAction(t,function SetupGame)
set t = null
endfunction
endscope
library PlayerLib uses MiscLibrary
globals
Table MAX_VALUES
integer MAX_SPELL_DMG = 0
integer MAX_ATTACK_DMG = 0
integer MAX_HEAL_DONE = 0
integer MAX__DMG = 0
integer MAX_SP_D = 0
integer MAX_AT_D = 0
integer MAX_H_D = 0
integer MAX_CRIT_D = 0
integer MAX_DMG_D = 0
integer MAX_SP_T = 0
integer MAX_AT_T = 0
integer MAX_H_T = 0
integer MAX_CRIT_T = 0
integer MAX_DMG_T = 0
integer MAX_KILLS = 0
integer MAX_DEATHS = 0
integer MAX_GOLD = 0
integer MAX_HONOR = 0
integer MAX_GOLD_L = 0
integer MAX_BASES_T = 0
integer MAX_MINES_T = 0
integer MAX_OBELISK_T = 0
endglobals
public function BuildMax takes nothing returns nothing
local integer i = 2
local Players p
loop
set p = Players[i]
if p.spellDmgD > MAX_SP_D then
set MAX_SP_D = p.spellDmgD
endif
if p.attDmgD > MAX_AT_D then
set MAX_AT_D = p.attDmgD
endif
if p.healD > MAX_H_D then
set MAX_H_D = p.healD
endif
if p.maxCritD > MAX_CRIT_D then
set MAX_CRIT_D = p.maxCritD
endif
if p.totalDmgD > MAX_DMG_D then
set MAX_DMG_D = p.totalDmgD
endif
if p.spellDmgT > MAX_SP_T then
set MAX_SP_T = p.spellDmgT
endif
if p.attDmgT > MAX_AT_T then
set MAX_AT_T = p.attDmgT
endif
if p.maxCritT > MAX_CRIT_T then
set MAX_CRIT_T = p.maxCritT
endif
if p.totalDmgT > MAX_DMG_T then
set MAX_DMG_T = p.totalDmgT
endif
if p.totalGold > MAX_GOLD then
set MAX_GOLD = p.totalGold
endif
if p.totalHonor > MAX_HONOR then
set MAX_HONOR = p.totalHonor
endif
if p.goldLost > MAX_GOLD_L then
set MAX_GOLD_L = p.goldLost
endif
if p.basesT > MAX_BASES_T then
set MAX_BASES_T = p.basesT
endif
if p.minesT > MAX_MINES_T then
set MAX_MINES_T = p.minesT
endif
if p.obeliskT > MAX_OBELISK_T then
set MAX_OBELISK_T = p.obeliskT
endif
if p.kills > MAX_KILLS then
set MAX_KILLS = p.kills
endif
if p.deaths > MAX_DEATHS then
set MAX_DEATHS = p.deaths
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
endfunction
struct Players extends array
string name
Hero hero
unit dummy
unit baul
unit traitUnit
unit voteUnit
integer kills
integer deaths
integer suicides
integer gold
integer honor
real goldFactor
boolean left
boolean isPlaying
boolean camSmooth
boolean fog
integer heroesKilledTemp
boolean inArena
integer cameraDistance
string ai
//for multiboard
integer spellDmgD
integer attDmgD
integer healD
integer maxCritD
integer spellDmgT
integer attDmgT
integer healT
integer maxCritT
integer totalDmgD
integer totalDmgT
integer totalGold
integer totalHonor
integer goldLost
integer basesD
integer basesT
integer minesT
integer obeliskT
integer creepsE
integer creepsN
integer maxCritDTarget
integer maxCritDType
integer maxCritTSource
integer maxCritTType
boolean aoeShow
integer damageTextMode
Table tb
//for pick
unit dummyPreview
HeroData lastDataPreview
//for AI
integer AIPing_CD
public static integer PlayersActive = 0
public static integer PlayersTotal = 0
public static integer TraitCount = 0
public static method create takes player wichPlayer, string n returns thistype
local thistype this = GetPlayerId(wichPlayer)
if this <= 6 and wichPlayer != Game.PLAYER_WARCHIEF_ALLIANCE then
set dummy = CreateUnit(wichPlayer,'ddot',Team[1].startX,Team[1].startY,0)
elseif this <= 11 and wichPlayer != Game.PLAYER_WARCHIEF_HORDE then
set dummy = CreateUnit(wichPlayer,'ddot',Team[2].startX,Team[2].startY,0)
else
set dummy = CreateUnit(wichPlayer,'ddot',Game.HIDE_X,Game.HIDE_Y,0)
endif
if this >= 2 and this <= 11 then
set traitUnit = CreateUnit(wichPlayer,HeroicTraits_TRAIT_UNIT_ID,Game.HIDE_X,Game.HIDE_Y,0)
endif
if this >= 2 and this <= 11 and GetPlayerController(wichPlayer) != MAP_CONTROL_COMPUTER then
set voteUnit = CreateUnit(wichPlayer,'h00F',GetRectCenterX(gg_rct_ObeliskArea),GetRectCenterY(gg_rct_ObeliskArea),0)
if Game.LocalPlayer != wichPlayer then
call SetUnitScale(voteUnit,0,0,0)
endif
call SelectUnitForPlayer(voteUnit,wichPlayer,true)
endif
set cameraDistance = Game.DEFAULT_CAMERA
set name = n
set kills = 0
set deaths = 0
set suicides = 0
set gold = 0
set honor = 0
set left = false
set isPlaying = true
set camSmooth = true
set fog = true
set tb = Table.create()
set inArena = false
//alala
set spellDmgD = 0
set attDmgD = 0
set healD = 0
set attDmgT = 0
set maxCritD = 0
set spellDmgT = 0
set healT = 0
set maxCritT = 0
set totalDmgD = 0
set totalDmgT = 0
set totalGold = 0
set totalHonor = 0
set goldLost = 0
set basesD = 0
set basesT = 0
set minesT = 0
set obeliskT = 0
set creepsE = 0
set creepsN = 0
set maxCritDTarget = 0
set maxCritDType = 0
set maxCritTSource = 0
set maxCritTType = 0
set heroesKilledTemp = 0
set aoeShow = true
set damageTextMode = 1
set dummyPreview = null
set AIPing_CD = 0
return this
endmethod
public static method RemoveVotingUnits takes nothing returns nothing
local integer i = 2
loop
if thistype[i].voteUnit != null then
call RemoveUnit(thistype[i].voteUnit)
set thistype[i].voteUnit = null
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
endmethod
public static method CheckPositionPenalty takes nothing returns nothing
local integer i = 2
local DamageOptions op
local real x
local real y
local real hx
local real hy
if Game.Mode == GAME_MODE_NORMAL then
if not Game.GameStarted then
loop
if thistype[i].isPlaying and thistype[i].hero != 0 then
if i < 7 then
set x = Team[1].startX
set y = Team[1].startX
else
set x = Team[2].startX
set y = Team[2].startX
endif
if Distance(x,y,GetUnitX(thistype[i].hero.hero),GetUnitY(thistype[i].hero.hero)) > 2000 then
call SetUnitX(thistype[i].hero.hero,x)
call SetUnitY(thistype[i].hero.hero,y)
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
endif
else
if Game.Mode == GAME_MODE_LMS or Game.Mode == GAME_MODE_OD then
if Game.RoundStarted then
set x = GetRectCenterX(gg_rct_FightRegion)
set y = GetRectCenterY(gg_rct_FightRegion)
loop
if thistype[i].isPlaying and thistype[i].hero != 0 then
if thistype[i].inArena then
if not RectContainsCoords(gg_rct_FightRegion,GetUnitX(thistype[i].hero.hero),GetUnitY(thistype[i].hero.hero)) then
set op = DamageOptions.create()
set op.fixedDamage = true
call CodeDamage.Damage(thistype[i].hero.hero,thistype[i].hero.hero,100,udg_DamageTypePure,"",0,op)
endif
else
if Distance(GetPlayerStartLocationX(Player(i)),GetPlayerStartLocationY(Player(i)),GetUnitX(thistype[i].hero.hero),GetUnitY(thistype[i].hero.hero)) > 2700 then
call SetUnitX(thistype[i].hero.hero,x)
call SetUnitY(thistype[i].hero.hero,y)
endif
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
endif
endif
endif
endmethod
endstruct
function GetPlayerDummy takes player p returns unit
return Players[GetPlayerId(p)].dummy
endfunction
function GetPlayerHero takes player p returns Hero
return Players[GetPlayerId(p)].hero
endfunction
function GetPlayerTeamEx takes player p returns Team
if Team[1].isPlayerInTeam(p) then
return Team[1]
endif
if Team[2].isPlayerInTeam(p) then
return Team[2]
endif
return 0
endfunction
function IsHeroInBase takes player p returns boolean
local Hero h = GetPlayerHero(p)
if GetPlayerTeamEx(p) == 1 then
return RectContainsUnit(gg_rct_PickItemsHorde,h.hero)
else
return RectContainsUnit(gg_rct_PickItemsAlliance,h.hero)
endif
return false
endfunction
public function Observer takes nothing returns nothing
local integer i = 0
local integer j
local player p
local player p2
loop
set p = Player(i)
if GetPlayerState(p,PLAYER_STATE_OBSERVER) == 1 then
if Game.LocalPlayer == p then
call SetReservedLocalHeroButtons(10)
endif
set p2 = Player(0)
call SetPlayerAlliance(p,p2,ALLIANCE_PASSIVE,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_CONTROL,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_ADVANCED_CONTROL,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_SPELLS,true)
call SetPlayerAlliance(p2,p,ALLIANCE_PASSIVE,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_CONTROL,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_ADVANCED_CONTROL,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_SPELLS,true)
set p2 = Player(1)
call SetPlayerAlliance(p,p2,ALLIANCE_PASSIVE,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_CONTROL,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_ADVANCED_CONTROL,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_SPELLS,true)
call SetPlayerAlliance(p2,p,ALLIANCE_PASSIVE,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_CONTROL,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_ADVANCED_CONTROL,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_SPELLS,true)
set j = 2
loop
set p2 = Player(j)
call SetPlayerAlliance(p,p2,ALLIANCE_PASSIVE,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_CONTROL,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_ADVANCED_CONTROL,true)
call SetPlayerAlliance(p,p2,ALLIANCE_SHARED_SPELLS,true)
call SetPlayerAlliance(p2,p,ALLIANCE_PASSIVE,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_CONTROL,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_ADVANCED_CONTROL,true)
call SetPlayerAlliance(p2,p,ALLIANCE_SHARED_SPELLS,true)
set j = j + 1
exitwhen j > Game.PLAYER_MAX
endloop
endif
set i = i + 1
exitwhen i > bj_MAX_PLAYERS
endloop
set p = null
set p2 = null
endfunction
public function Setup takes nothing returns nothing
local integer i = 2
local player tempPlayer
local boolean cp
local Players p
call SetPlayerName(Game.PLAYER_WARCHIEF_ALLIANCE,"The Humans")
call SetPlayerName(Game.PLAYER_WARCHIEF_HORDE,"The Orcs")
call SetPlayerOnScoreScreen(Game.PLAYER_WARCHIEF_ALLIANCE, false)
call SetPlayerOnScoreScreen(Game.PLAYER_WARCHIEF_HORDE, false)
call SetPlayerState(Game.PLAYER_NEUTRAL_HOSTILE,PLAYER_STATE_GIVES_BOUNTY,0)
loop
set tempPlayer = Player(i)
if GetPlayerSlotState(tempPlayer) == PLAYER_SLOT_STATE_PLAYING then
set p = Players.create(tempPlayer,GetPlayerName(tempPlayer))
set Players.PlayersActive = Players.PlayersActive + 1
set Players.PlayersTotal = Players.PlayersTotal + 1
call SetCameraPositionForPlayer(tempPlayer,GetRectCenterX(gg_rct_ObeliskArea),GetRectCenterY(gg_rct_ObeliskArea))
//Force
set cp = GetPlayerController(tempPlayer) == MAP_CONTROL_COMPUTER
call DamageTT[i].setup()
call PlayerBounty.Init(i)
call PlayerKeyData.create(tempPlayer)
call PlayerPing.Init(tempPlayer)
call PlayerItemUI.setup(i)
call UIItemUpgrade_SetupForPlayer.evaluate(tempPlayer)
if i <= 6 then
call Team[1].addPlayer(tempPlayer)
call SetPlayerAllianceStateBJ(Game.PLAYER_WARCHIEF_HORDE,tempPlayer,bj_ALLIANCE_ALLIED_VISION)
call SetPlayerAllianceStateBJ(tempPlayer,Game.PLAYER_WARCHIEF_HORDE,bj_ALLIANCE_ALLIED_VISION)
if not cp then
set Team[1].AI_Automated = false
endif
else
call Team[2].addPlayer(tempPlayer)
call SetPlayerAllianceStateBJ(Game.PLAYER_WARCHIEF_ALLIANCE,tempPlayer,bj_ALLIANCE_ALLIED_VISION)
call SetPlayerAllianceStateBJ(tempPlayer,Game.PLAYER_WARCHIEF_ALLIANCE,bj_ALLIANCE_ALLIED_VISION)
if not cp then
set Team[2].AI_Automated = false
endif
endif
call AddPlayerGold(tempPlayer,Game.PLAYER_INITIAL_GOLD)
if cp then
if GetAIDifficulty(tempPlayer) == AI_DIFFICULTY_NEWBIE then
set p.ai = "E"
call AddPlayerBountyPercent.evaluate(tempPlayer,30)
call AddPlayerExpPercent.evaluate(tempPlayer,30)
elseif GetAIDifficulty(tempPlayer) == AI_DIFFICULTY_NORMAL then
set p.ai = "N"
call AddPlayerBountyPercent.evaluate(tempPlayer,50)
call AddPlayerExpPercent.evaluate(tempPlayer,50)
elseif GetAIDifficulty(tempPlayer) == AI_DIFFICULTY_INSANE then
set p.ai = "I"
call AddPlayerBountyPercent.evaluate(tempPlayer,70)
call AddPlayerExpPercent.evaluate(tempPlayer,70)
endif
else
if Game.FirstPlayer == null then
set Game.FirstPlayer = tempPlayer
else
set Game.IsSinglePlayer = false
endif
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
if Game.IsSinglePlayer then
call TestCommands_Setup.evaluate()
endif
call Players.create(Game.PLAYER_WARCHIEF_HORDE,"The Orcs")
call Team[1].addPlayer(Game.PLAYER_WARCHIEF_HORDE)
call PlayerBounty.Init(GetPlayerId(Game.PLAYER_WARCHIEF_HORDE))
call RemoveUnit(Players[0].traitUnit)
call Players.create(Game.PLAYER_WARCHIEF_ALLIANCE,"The Humans")
call Team[2].addPlayer(Game.PLAYER_WARCHIEF_ALLIANCE)
call PlayerBounty.Init(GetPlayerId(Game.PLAYER_WARCHIEF_ALLIANCE))
call RemoveUnit(Players[1].traitUnit)
call Players.create(Game.PLAYER_NEUTRAL_HOSTILE,"Neutral Hostile")
set tempPlayer = null
endfunction
endlibrary
library TeamLib uses PlayerLib, GameMultiboard
globals
private integer tempInt = 0
endglobals
struct Team extends array
string name
integer count
force forceP
integer playerCount
player captain
integer bases
integer goldmines
integer resources
integer heroesDeath
integer kills
integer deaths
rect startReg
real startX
real startY
integer waveTime
integer currentTime //for waves
Commander commander
unit warHall
unit gateTower1
unit gateTower2
boolean forceWaveSpawn
Base AI_TeamBaseTarget1
integer AI_TeamBasePriority1
GoldMine AI_TeamMineTarget1
integer AI_TeamMinePriority1
boolean AI_Automated
//LMS
integer heroesIn
integer heroesTotal
integer rounds
real totalThreat
integer dangerLevel
boolean giveR
public static method UpdateIncome takes nothing returns nothing
call SetPlayerState(GetEnumPlayer(),PLAYER_STATE_RESOURCE_LUMBER,tempInt)
endmethod
public static method UpdateResources takes nothing returns nothing
call SetPlayerState(GetEnumPlayer(), PLAYER_STATE_RESOURCE_FOOD_USED,tempInt)
endmethod
public method setIncome takes nothing returns nothing
call AddTeamGold(this,goldmines)
set tempInt = goldmines
call ForForce(forceP,function thistype.UpdateIncome)
endmethod
public method addPlayer takes player wichPlayer returns nothing
set playerCount = playerCount + 1
call ForceAddPlayer(forceP,wichPlayer)
endmethod
public method isPlayerInTeam takes player wichPlayer returns boolean
return IsPlayerInForce(wichPlayer,forceP)
endmethod
public method addResource takes integer r returns nothing
if Game.GameOver then
return
endif
if resources < Game.ResourcesToWin then
set resources = resources + r
if resources > Game.ResourcesToWin then
set resources = Game.ResourcesToWin
endif
endif
if resources == Game.ResourcesToWin then
if count == 15 then
set count = 0
call Message.Show(name + " needs to control the Obelisk to win the game.",MESSAGE_STYLE_WARNING)
else
set count = count + 1
endif
else
if Game.ResourcesToWin - resources <= 200 then
if count == 15 then
set count = 0
call Message.Show(name + " needs "+I2S(Game.ResourcesToWin - resources)+" Resources to Win.",MESSAGE_STYLE_WARNING)
else
set count = count + 1
endif
endif
endif
if this == 1 then
call BlzFrameSetText(OrcResourcesTextFrame, HORDE_COLOR+I2S(resources)+"|r")
elseif this == 2 then
call BlzFrameSetText(HumanResourcesTextFrame, ALLIANCE_COLOR+I2S(resources)+"|r")
endif
call VictoryConditions_CheckVictoryNormal.evaluate(this)
call MultiboardUpdateTeamResources(this)
set tempInt = resources
call ForForce(forceP,function thistype.UpdateResources)
endmethod
public method Create takes rect start, string n returns nothing
set .forceP = CreateForce()
set .name = n
set .count = 10
set .startReg = start
set .resources = 0
set .bases = 0
set .goldmines = 0
set .waveTime = 0
set .currentTime = 0
set .forceWaveSpawn = false
set .heroesDeath = 0
set .kills = 0
set .deaths = 0
set .rounds = 0
set totalThreat = 0
set dangerLevel = 0
set AI_TeamBasePriority1 = 0
set AI_TeamMinePriority1 = 0
set AI_Automated = true
set giveR = false
set .startX = GetRectCenterX(.startReg)
set .startY = GetRectCenterY(.startReg)
endmethod
endstruct
public function Setup takes nothing returns nothing
call Team[1].Create(gg_rct_HordeStart,"The Orcs")
set Team[1].captain = Game.PLAYER_WARCHIEF_HORDE
set Team[1].gateTower1 = gg_unit_h008_0036
set Team[1].gateTower2 = gg_unit_h008_0123
set Team[1].warHall = gg_unit_n005_0052
call SetUnitOwner(gg_unit_h008_0036,Game.PLAYER_WARCHIEF_HORDE,true)
call SetUnitOwner(gg_unit_h008_0123,Game.PLAYER_WARCHIEF_HORDE,true)
call RemoveGuardPosition(gg_unit_h008_0036)
call RemoveGuardPosition(gg_unit_h008_0123)
call Team[2].Create(gg_rct_AllianceStart,"The Humans")
set Team[2].captain = Game.PLAYER_WARCHIEF_ALLIANCE
set Team[2].gateTower1 = gg_unit_h007_0115
set Team[2].gateTower2 = gg_unit_h007_0121
set Team[2].warHall = gg_unit_n008_0064
call SetUnitOwner(gg_unit_h007_0115,Game.PLAYER_WARCHIEF_ALLIANCE,true)
call SetUnitOwner(gg_unit_h007_0121,Game.PLAYER_WARCHIEF_ALLIANCE,true)
call RemoveGuardPosition(gg_unit_h007_0115)
call RemoveGuardPosition(gg_unit_h007_0121)
endfunction
endlibrary
scope VictoryConditions initializer Init
globals
rect array END_POSITIONS
effect array LASER[200]
endglobals
private function LoopSfx takes nothing returns nothing
local real x
local real y
local integer i
local effect sfx
if Game.Winner == 1 then
set i = 2
loop
if Players[i].isPlaying then
if GetRandomInt(1,100) <= 35 then
call QueueUnitAnimation(Players[i].hero.hero,Players[i].hero.WinAni)
endif
if GetRandomInt(1,100) <= 15 then
set x = GetUnitX(Players[i].hero.hero) + GetRandomReal(-100,100)
set y = GetUnitY(Players[i].hero.hero) + GetRandomReal(-100,100)
set sfx = AddSpecialEffect(Game.FireworksSfx,x,y)
call BlzSetSpecialEffectScale(sfx,GetRandomReal(0.4,0.7))
call DestroyEffect(sfx)
endif
endif
set i = i + 1
exitwhen i > 6
endloop
else
set i = 7
loop
if Players[i].isPlaying then
if GetRandomInt(1,100) <= 35 then
call SetUnitAnimation(Players[i].hero.hero,Players[i].hero.WinAni)
call QueueUnitAnimation(Players[i].hero.hero,"stand")
endif
if GetRandomInt(1,100) <= 15 then
set x = GetUnitX(Players[i].hero.hero) + GetRandomReal(-100,100)
set y = GetUnitY(Players[i].hero.hero) + GetRandomReal(-100,100)
set sfx = AddSpecialEffect(Game.FireworksSfx,x,y)
call BlzSetSpecialEffectScale(sfx,GetRandomReal(0.4,0.7))
call DestroyEffect(sfx)
endif
endif
set i = i + 1
exitwhen i > 11
endloop
endif
set sfx = null
endfunction
private function GameOverVictory takes nothing returns nothing
local integer i = 2
local timer t = CreateTimer()
local texttag text = CreateTextTag()
local real x
local real y
local effect sfx
local Hero h
call TimerStart(t,1.0,true,function LoopSfx)
set t = null
call SetTextTagPermanent(text,true)
if Game.Winner == 1 then
call SetTextTagColor(text,255,0,0,255)
call SetTextTagText(text,"The Orcs WINS",TextTagSize2Height(20))
call SetTextTagPos(text,GetRectCenterX(gg_rct_ObeliskArea) - 140,GetRectCenterY(gg_rct_ObeliskArea),400)
call DisplayTimedTextToPlayer(Game.LocalPlayer,0,0,99999,"|cFF0063C6Victory: |r"+HORDE_COLOR+Game.Winner.name+"!!|r")
call StartSound(gg_snd_OrcVictory)
else
call SetTextTagColor(text,0,0,255,255)
call SetTextTagText(text,"The Humans WINS",TextTagSize2Height(20))
call SetTextTagPos(text,GetRectCenterX(gg_rct_ObeliskArea) - 200,GetRectCenterY(gg_rct_ObeliskArea),400)
call DisplayTimedTextToPlayer(Game.LocalPlayer,0,0,99999,"|cFF0063C6Victory: |r"+ALLIANCE_COLOR+Game.Winner.name+"!!|r")
call StartSound(gg_snd_HumanVictory)
endif
call SetTextTagVisibility(text,true)
set text = null
call DisplayTimedTextToPlayer(Game.LocalPlayer,0,0,99999,"Thanks for Playing!!")
call EndMultiboard_Setup.execute()
call SetMapFlag(MAP_FOG_ALWAYS_VISIBLE,true)
call UnitRemoveAbility(Game.LockCamera,'Aloc')
call ShowUnit(Game.LockCamera,true)
call UnitAddAbility(Game.LockCamera,'Aloc')
call CinematicFadeBJ( bj_CINEFADETYPE_FADEIN, 3.0, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
loop
if Players[i].isPlaying then
set x = GetRectCenterX(END_POSITIONS[i])
set y = GetRectCenterY(END_POSITIONS[i])
set h = Players[i].hero
call SetUnitPathing(h.hero,false)
call UnitRemoveAllBuffs(h.hero)
if not UnitAlive(h.hero) then
call ReviveHero(h.hero,x,y,false)
else
call SetUnitX(h.hero,x)
call SetUnitY(h.hero,y)
endif
set sfx = AddSpecialEffect("buildings\\other\\CircleOfPower\\CircleOfPower.mdl",x - 10,y - 20)
call BlzSetSpecialEffectColorByPlayer(sfx,Player(i))
call PauseUnit(h.hero,false)
call BlzPauseUnitEx(h.hero,true)
if i <= 6 then
call SetUnitFacing(h.hero,0.00)
else
call SetUnitFacing(h.hero,180.00)
endif
call SetUnitState(h.hero,UNIT_STATE_LIFE,999999)
call SetUnitState(h.hero,UNIT_STATE_MANA,999999)
call UnitAddAbility(h.hero,'Ane2')
call BlzUnitDisableAbility(h.hero,'Amov',true,false)
call BlzUnitDisableAbility(h.hero,'Aatk',true,false)
call SetCameraTargetControllerNoZForPlayer(Player(i),Game.LockCamera, 0, 0, false )
call SelectUnitForPlayer(h.hero,Player(i),true)
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
call DestroyTimer(GetExpiredTimer())
set t = null
endfunction
private function GameOverCinematicCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local real time = tb.real[1]
local real d
local real df
local real x
local real y
local real a
local string s
local integer i = -1
local Team losser = 2/Game.Winner
local effect sfx
if time == 1.0 then
call StartSound(gg_snd_GameVictory)
call SetCameraTargetController(Game.LockCamera, 0, 0, false)
if losser == 1 then
set sfx = AddSpecialEffect("Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl",AncientObelisk.x,AncientObelisk.y)
call BlzSetSpecialEffectScale(sfx,3.5)
else
set sfx = AddSpecialEffect("Abilities\\Weapons\\VengeanceMissile\\VengeanceMissile.mdl",AncientObelisk.x,AncientObelisk.y)
call BlzSetSpecialEffectScale(sfx,5.0)
endif
call BlzSetSpecialEffectHeight(sfx,500)
set tb.effect[0] = sfx
set sfx = null
endif
if time == 2.0 then
set d = Distance(AncientObelisk.x,AncientObelisk.y,GetUnitX(losser.commander.heroUnit),GetUnitY(losser.commander.heroUnit))
set a = Angle(AncientObelisk.x,AncientObelisk.y,GetUnitX(losser.commander.heroUnit),GetUnitY(losser.commander.heroUnit))
set x = AncientObelisk.x + 25 * Cos(a)
set y = AncientObelisk.y + 25 * Sin(a)
if losser == 1 then
set s = "war3mapImported\\blue Laser Ray.mdx"
else
set s = "war3mapImported\\Red Laser Ray.mdx"
endif
loop
exitwhen d <= 40
set i = i + 1
set LASER[i] = AddSpecialEffect(s,x,y)
call BlzSetSpecialEffectTimeScale(LASER[i],2.0)
call BlzSetSpecialEffectHeight(LASER[i],510)
call BlzSetSpecialEffectScale(LASER[i],0.50)
call BlzSetSpecialEffectYaw(LASER[i],a)
set x = x + 8 * Cos(a)
set y = y + 8 * Sin(a)
set d = d - 8
endloop
set tb.integer[2] = i
endif
if time == 4.0 then
call SetCameraTargetController(losser.commander.heroUnit, 0, 0, false)
endif
if time == 6.0 then
call KillUnit(losser.commander.heroUnit)
if losser == 1 then
set s = "Abilities\\Spells\\Orc\\LightningBolt\\LightningBoltMissile.mdl"
else
set s = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl"
endif
call DestroyEffect(AddSpecialEffectTarget(s,losser.commander.heroUnit,"overhead"))
call DestroyEffect(AddSpecialEffectTarget(s,losser.commander.heroUnit,"chest"))
call DestroyEffect(AddSpecialEffectTarget(s,losser.commander.heroUnit,"hand right"))
call DestroyEffect(AddSpecialEffectTarget(s,losser.commander.heroUnit,"hand left"))
call DestroyEffect(AddSpecialEffectTarget(s,losser.commander.heroUnit,"origin"))
set i = tb.integer[2]
loop
call DestroyEffect(LASER[i])
set i = i - 1
exitwhen i == -1
endloop
call DestroyEffect(tb.effect[0])
endif
if time == 8.0 then
call CinematicFadeBJ( bj_CINEFADETYPE_FADEOUT, 3.0, "ReplaceableTextures\\CameraMasks\\Black_mask.blp", 0, 0, 0, 0 )
call TimerStart(NewTimer(),3.0,false,function GameOverVictory)
call ReleaseTimer(t)
call tb.flush()
call tb.destroy()
endif
set time = time + 1.0
set tb.real[1] = time
set t = null
endfunction
public function RunGameOverCinematic takes nothing returns nothing
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
set tb.real[1] = 0.00
call TimerStart(t,1.0,true,function GameOverCinematicCallback)
set t = null
endfunction
public function RunGameOver takes Team t returns nothing
call PauseAllUnitsBJ(true)
call StopMusic(true)
//call CreateFogModifierRect(Game.LocalPlayer,FOG_OF_WAR_VISIBLE,GetPlayableMapRect(),false,false)
call FogModifierStart(CreateFogModifierRect(Game.LocalPlayer,FOG_OF_WAR_VISIBLE,GetPlayableMapRect(),false,false))
call PlayerLib_BuildMax.execute()
set Game.GameOver = true
set Game.Winner = t
call RunGameOverCinematic()
endfunction
public function CheckVictoryNormal takes Team t returns nothing
if Game.GameOver then
return
endif
if t.resources >= Game.ResourcesToWin and AncientObelisk.owner == t then
//call StartEndCinematic()
set t.resources = Game.ResourcesToWin
call RunGameOver(t)
call MultiboardUpdateTittle()
endif
endfunction
public function Init takes nothing returns nothing
set END_POSITIONS[2] = gg_rct_EndPos1
set END_POSITIONS[3] = gg_rct_EndPos2
set END_POSITIONS[4] = gg_rct_EndPos3
set END_POSITIONS[5] = gg_rct_EndPos4
set END_POSITIONS[6] = gg_rct_EndPos5
set END_POSITIONS[7] = gg_rct_EndPos6
set END_POSITIONS[8] = gg_rct_EndPos7
set END_POSITIONS[9] = gg_rct_EndPos8
set END_POSITIONS[10] = gg_rct_EndPos9
set END_POSITIONS[11] = gg_rct_EndPos10
endfunction
endscope
scope PathingHidder initializer init
globals
destructable array Walls1
integer count1 = 0
endglobals
function RemoveWalls takes integer op returns nothing
local integer i = 0
if op == 1 then
loop
call RemoveDestructable(Walls1[i])
set Walls1[i] = null
set i = i + 1
exitwhen i == count1
endloop
endif
endfunction
function Enum takes nothing returns nothing
local destructable d = GetEnumDestructable()
local integer id = GetDestructableTypeId(d)
if id == 'YTpb' or id == 'B009' or id == 'YTpc' then
call ShowDestructable(d,false)
else
if id == 'B00B' then
set Walls1[count1] = d
set count1 = count1 + 1
endif
endif
set d = null
endfunction
function PathingHidder takes nothing returns nothing
call EnumDestructablesInRect(bj_mapInitialPlayableArea,null,function Enum)
call DestroyTrigger(GetTriggeringTrigger())
endfunction
function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterTimerEvent(t,5.0,false)
call TriggerAddAction(t,function PathingHidder)
set t = null
endfunction
endscope
function Trig_Animation_Actions takes nothing returns nothing
local Hero h = GetPlayerHero(Player(2))
local integer i = S2I(SubString(GetEventPlayerChatString(),3,StringLength(GetEventPlayerChatString())))
call SetUnitAnimationByIndex(h.hero,i)
endfunction
//===========================================================================
function InitTrig_Animation takes nothing returns nothing
set gg_trg_Animation = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_Animation, Player(2), "-a", false )
call TriggerRegisterPlayerChatEvent( gg_trg_Animation, Player(7), "-a", false )
call TriggerAddAction( gg_trg_Animation, function Trig_Animation_Actions )
endfunction
function Trig_Message_Test_Actions takes nothing returns nothing
local Team t = GetPlayerTeamEx(GetTriggerPlayer())
call Team[2].addResource(3000)
endfunction
//===========================================================================
function InitTrig_Message_Test takes nothing returns nothing
set gg_trg_Message_Test = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_Message_Test, Player(2), "-ad", true )
call TriggerRegisterPlayerChatEvent( gg_trg_Message_Test, Player(7), "-ad", true )
call TriggerAddAction( gg_trg_Message_Test, function Trig_Message_Test_Actions )
endfunction
library PickHeroSystem uses HeroLibrary, AdvBook, GameConstants, NewGroup
globals
private constant integer PHS_VISION_DUMMY_ID = 'n00K'
private constant integer PHS_BACK_TO_BOOK_ID = 'nul2'
private constant integer PHS_SELECT_HERO_ID = 'nul1'
private constant integer PHS_RANDOM_HERO_ID = 'A01I'
private constant string CHOOSE_USED_MSG = "This Hero is already Picked"
private constant integer MENU_NEUTRAL_ID = 'AHCN'
private constant integer MENU_HUMAN_ID = 'AHCH'
private constant integer MENU_ORC_ID = 'AHCO'
private constant integer MENU_NIGHTELF_ID = 'AHCE'
private constant integer MENU_UNDEAD_ID = 'AHCU'
private constant string SELECT_HERO_SFX = "Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl"
private constant string SELECT_SFX = "Abilities\\Spells\\Other\\Aneu\\AneuCaster.mdl"
private AdvBookElement MainMenuHorde
private AdvBookElement MainMenuAlliance
private AdvBookElement MenuNeutral
private AdvBookElement MenuHuman
private AdvBookElement MenuOrc
private AdvBookElement MenuNightElf
private AdvBookElement MenuUndead
endglobals
private function DisableHeroPick takes integer id returns nothing
local integer i = 2
local PickHeroSystem phs
loop
set phs = PickHeroSystem[i]
call BlzUnitDisableAbility(phs.circleDummy,id,true,false)
set i = i + 1
exitwhen i > 11
endloop
endfunction
struct PickHeroSystem extends array
unit previewDummy
unit circleDummy
effect sfx
boolean active
HeroData heroData
public static unit VisionDummy1
public static unit VisionDummy2
static integer PicksCount = 0
public static trigger RT
public static unit lockcamera
public static method DestroyAll takes nothing returns nothing
local integer i = 2
call TriggerClearConditions(RT)
call DestroyTrigger(RT)
loop
if PickHeroSystem[i].active then
call RemoveUnit(PickHeroSystem[i].previewDummy)
set PickHeroSystem[i].previewDummy = null
call BookUnit[GetUnitUserData(PickHeroSystem[i].circleDummy)].destroy()
//set PickHeroSystem[i].circleDummy = null
call DestroyEffect(PickHeroSystem[i].sfx)
set PickHeroSystem[i].sfx = null
set PickHeroSystem[i].heroData = 0
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
call MainMenuHorde.destroy()
call MainMenuAlliance.destroy()
call ShowUnit(VisionDummy1,false)
call ShowUnit(VisionDummy2,false)
call ShowUnit(lockcamera,false)
set gg_unit_ddot_0113 = null
set RT = null
endmethod
public static method SelectHero takes player p returns boolean
local thistype phs = PickHeroSystem[GetPlayerId(p)]
if phs.previewDummy != null then
if phs.heroData.IsSelected then
call Message.ShowToPlayer(p,CHOOSE_USED_MSG,MESSAGE_STYLE_INFO)
else
set phs.heroData.IsSelected = true
call DisableHeroPick(phs.heroData.ChooseIconID)
call HeroData.RemoveRandomData(phs.heroData)
set PicksCount = PicksCount + 1
call CreateHeroForPlayer(p,phs.heroData)
call DestroyEffect(AddSpecialEffectTarget(SELECT_HERO_SFX,phs.previewDummy,"origin"))
call SetUnitAnimation(phs.previewDummy,"attack")
call QueueUnitAnimation(phs.previewDummy,"stand")
call PauseUnit(phs.previewDummy,true)
if Game.LocalPlayer == p then
call StartSound(gg_snd_HeroPick)
call EnablePreSelect( true, true )
endif
endif
if PicksCount == Players.PlayersActive then
call PickHeroSystem.DestroyAll()
if Game.GameStarted then
call LoadFunction.Destroy()
endif
endif
else
call Message.ShowToPlayer(p,"Before select a Preview Hero.",MESSAGE_STYLE_INFO)
endif
set p = null
return false
endmethod
public static method createHeroDummyByID takes integer iconid, HeroData d, player p returns boolean
local integer pid
local thistype phs
local real a
if d == 0 then
set d = HeroData.GetDataByChooseIconID(iconid)
endif
if d != 0 then
set pid = GetPlayerId(p)
set phs = thistype[pid]
if GetUnitTypeId(phs.previewDummy) != d.ChooseDummy then
call RemoveUnit(phs.previewDummy)
if pid > 6 then
set a = 225
else
set a = 45
endif
set phs.previewDummy = CreateUnit(p,d.ChooseDummy,GetUnitX(phs.circleDummy),GetUnitY(phs.circleDummy),a)
call SetUnitAbilityLevel(phs.previewDummy,d.HeroAbility1,4)
call BlzUnitDisableAbility(phs.previewDummy,d.HeroAbility1,true,false)
call SetUnitAbilityLevel(phs.previewDummy,d.HeroAbility2,4)
call BlzUnitDisableAbility(phs.previewDummy,d.HeroAbility2,true,false)
call SetUnitAbilityLevel(phs.previewDummy,d.HeroAbility3,4)
call BlzUnitDisableAbility(phs.previewDummy,d.HeroAbility3,true,false)
call SetUnitAbilityLevel(phs.previewDummy,d.HeroAbility4,3)
call BlzUnitDisableAbility(phs.previewDummy,d.HeroAbility4,true,false)
call SetUnitAbilityLevel(phs.previewDummy,d.HeroAbility5,1)
call BlzUnitDisableAbility(phs.previewDummy,d.HeroAbility5,true,false)
call SetUnitAbilityLevel(phs.previewDummy,d.HeroAbility6,1)
call BlzUnitDisableAbility(phs.previewDummy,d.HeroAbility6,true,false)
call BuildDescriptionByData(d.HeroUp1,phs.previewDummy)
call BuildDescriptionByData(d.HeroUp2,phs.previewDummy)
call BuildDescriptionByData(d.HeroUp3,phs.previewDummy)
call SetUnitAbilityLevel(phs.previewDummy,d.HeroUp4.UpId,2)
call SelectUnitForPlayer(phs.previewDummy,p,true)
set phs.heroData = d
if d.IsSelected then
call BlzUnitDisableAbility(phs.previewDummy,PHS_SELECT_HERO_ID,true,false)
endif
return true
else
call SelectUnitForPlayer(phs.previewDummy,p,true)
endif
endif
return false
endmethod
public static method onInit takes nothing returns nothing
set RT = CreateTrigger()
endmethod
endstruct
private function OnMenuClick takes nothing returns boolean
local integer id = AdvBookEvent.EventIconID
local unit u = AdvBookEvent.EventUnit
local player p = GetOwningPlayer(u)
if id == PHS_RANDOM_HERO_ID then
call PickHeroSystem.createHeroDummyByID(0,HeroData.GetRandomData(p),p)
else
call PickHeroSystem.createHeroDummyByID(id,0,p)
endif
set u = null
set p = null
return false
endfunction
private function AddHerosToMenu takes AdvBookElement b,integer faction returns nothing
local integer i = 1
loop
exitwhen i > HeroData.COUNT
if HeroData[i].HeroFaction == faction then
call b.addElement(AdvBookElement.create(HeroData[i].ChooseIconID,false,HeroData[i]))
endif
set i = i + 1
endloop
endfunction
private function onCast takes nothing returns boolean
local player p = GetTriggerPlayer()
if GetUnitAbilityLevel(GetTriggerUnit(),PHS_BACK_TO_BOOK_ID) > 0 then
if GetSpellAbilityId() == PHS_BACK_TO_BOOK_ID then
call SelectUnitForPlayer(PickHeroSystem[GetPlayerId(p)].circleDummy,p,true)
elseif GetSpellAbilityId() == PHS_SELECT_HERO_ID then
call PickHeroSystem.SelectHero(p)
endif
endif
set p = null
return false
endfunction
private function SetMenus takes nothing returns nothing
set MainMenuHorde = AdvBookElement.create('BRI3',true,0)
set MainMenuAlliance = AdvBookElement.create('BRI3',true,0)
set MenuNeutral = AdvBookElement.create(MENU_NEUTRAL_ID,true,0)
set MenuHuman = AdvBookElement.create(MENU_HUMAN_ID,true,0)
set MenuOrc = AdvBookElement.create(MENU_ORC_ID,true,0)
set MenuNightElf = AdvBookElement.create(MENU_NIGHTELF_ID,true,0)
set MenuUndead = AdvBookElement.create(MENU_UNDEAD_ID,true,0)
call MainMenuHorde.addElement(MenuNeutral)
call MainMenuHorde.addElement(MenuOrc)
call MainMenuHorde.addElement(MenuNightElf)
call MainMenuHorde.addElement(MenuUndead)
call MainMenuAlliance.addElement(MenuNeutral)
call MainMenuAlliance.addElement(MenuHuman)
call MainMenuAlliance.addElement(MenuNightElf)
call MainMenuAlliance.addElement(MenuUndead)
call AddHerosToMenu(MenuNeutral,Game.FACTION_NEUTRAL)
call AddHerosToMenu(MenuHuman,Game.FACTION_HUMAN)
call AddHerosToMenu(MenuOrc,Game.FACTION_ORC)
call AddHerosToMenu(MenuNightElf,Game.FACTION_NIGHTELF)
call AddHerosToMenu(MenuUndead,Game.FACTION_UNDEAD)
call MainMenuHorde.addElement(AdvBookElement.create(PHS_RANDOM_HERO_ID,false,0))
call MainMenuAlliance.addElement(AdvBookElement.create(PHS_RANDOM_HERO_ID,false,0))
endfunction
private function SetDummys takes nothing returns nothing
set PickHeroSystem[2].circleDummy = gg_unit_n00H_0078
set PickHeroSystem[3].circleDummy = gg_unit_n00H_0020
set PickHeroSystem[4].circleDummy = gg_unit_n00H_0073
set PickHeroSystem[5].circleDummy = gg_unit_n00H_0099
set PickHeroSystem[6].circleDummy = gg_unit_n00H_0076
set PickHeroSystem[7].circleDummy = gg_unit_n00H_0077
set PickHeroSystem[8].circleDummy = gg_unit_n00H_0084
set PickHeroSystem[9].circleDummy = gg_unit_n00H_0086
set PickHeroSystem[10].circleDummy = gg_unit_n00H_0087
set PickHeroSystem[11].circleDummy = gg_unit_n00H_0100
endfunction
public function LockCameraVision takes nothing returns nothing
local real x = GetRectCenterX(gg_rct_PickRegion)
local real y = GetRectCenterY(gg_rct_PickRegion)
//call EnablePreSelect( true, false )
set PickHeroSystem.lockcamera = gg_unit_ddot_0113
call SetCameraPosition(x,y)
//call SetCameraTargetController(PickHeroSystem.lockcamera, 0, 0, false)
set PickHeroSystem.VisionDummy1 = CreateUnit(Game.PLAYER_WARCHIEF_HORDE,PHS_VISION_DUMMY_ID,x,y,0)
set PickHeroSystem.VisionDummy2 = CreateUnit(Game.PLAYER_WARCHIEF_ALLIANCE,PHS_VISION_DUMMY_ID,x,y,0)
endfunction
public function Setup takes nothing returns nothing
local integer i = 2
local player tempPlayer
local real x = GetRectCenterX(gg_rct_PickRegion)
local real y = GetRectCenterY(gg_rct_PickRegion)
local real xc
local real yc
call SetDummys()
call SetMenus()
loop
set tempPlayer = Player(i)
if GetPlayerSlotState(tempPlayer) == PLAYER_SLOT_STATE_PLAYING then
set xc = GetUnitX(PickHeroSystem[i].circleDummy)
set yc = GetUnitY(PickHeroSystem[i].circleDummy)
set PickHeroSystem[i].sfx = AddSpecialEffect(SELECT_SFX,xc,yc)
set PickHeroSystem[i].active = true
call BlzSetSpecialEffectHeight(PickHeroSystem[i].sfx,200)
if Game.LocalPlayer != tempPlayer then
call BlzSetSpecialEffectScale(PickHeroSystem[i].sfx,0)
else
call EnablePreSelect( true, false )
call SetCameraTargetController(PickHeroSystem.lockcamera, 0, 0, false)
endif
call BookUnit.create(PickHeroSystem[i].circleDummy)
if i <= 6 then
call BookUnit[GetUnitUserData(PickHeroSystem[i].circleDummy)].open(MainMenuHorde)
else
call BookUnit[GetUnitUserData(PickHeroSystem[i].circleDummy)].open(MainMenuAlliance)
endif
call SelectUnitForPlayer(PickHeroSystem[i].circleDummy,tempPlayer,true)
call UnitGenerateAlarms(PickHeroSystem[i].circleDummy,false)
else
call SetUnitColor(PickHeroSystem[i].circleDummy,PLAYER_COLOR_LIGHT_GRAY)
set PickHeroSystem[i].previewDummy = null
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
call RegisterAdvBookClickEvent(function OnMenuClick,EVENT_ADVBOOK_CLICK)
call TriggerRegisterAnyUnitEventBJ(PickHeroSystem.RT,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(PickHeroSystem.RT,Condition(function onCast))
set tempPlayer = null
endfunction
endlibrary
library AdvBook initializer init uses LinkedList, Event, NewGroup
globals
private constant integer CANCEL_BUTTON = 'AHCC'
private constant integer NEXT_BUTTON = 'AHCP'
private constant integer PAGE_MAX_ELEM = 11
Event EVENT_ADVBOOK_CLICK
endglobals
struct AdvBookEvent extends array
static unit EventUnit
static integer EventIconID
static integer EventElement
private static method onInit takes nothing returns nothing
set EVENT_ADVBOOK_CLICK = Event.create()
endmethod
endstruct
struct AdvBookElement
LinkedList list
boolean isBook
integer iconID
integer data
boolean destroyed
private static integer count = 0
public static method GetElementByID takes integer id returns thistype
local integer i = 0
loop
set i = i + 1
if thistype(i).iconID == id then
return thistype(i)
endif
exitwhen i == count
endloop
return 0
endmethod
public method addElement takes AdvBookElement e returns nothing
call list.add(e)
endmethod
public method isEmpty takes nothing returns boolean
return list.size == 0
endmethod
public static method create takes integer id ,boolean b, integer d returns thistype
local thistype this = thistype.allocate()
set iconID = id
set list = LinkedList.create()
set isBook = b
set data = d
set destroyed = false
set count = count + 1
return this
endmethod
public method destroy takes nothing returns nothing
local Link temp = list.head
local thistype b
loop
exitwhen temp == 0
set b = temp.data
if not b.destroyed then
call b.destroy()
endif
set temp = temp.next
endloop
call list.destroy()
set count = count - 1
set list = 0
set isBook = false
set iconID = 0
set destroyed = true
call this.deallocate()
endmethod
endstruct
struct BookUnit extends array
AdvBookElement currentBook
LinkedList prevBooks
Link lastElement
integer count
static group RegisterGroup
static trigger OnClickTrigger
private static method IsValid takes unit u returns boolean
return GetUnitAbilityLevel(u,'aatk') == 0 and GetUnitAbilityLevel(u,'amov') == 0 and GetWidgetLife(u) > 0.405 and IsUnitInGroup(u,RegisterGroup)
endmethod
private static method OnClick takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer sid = GetSpellAbilityId()
local integer id = GetUnitUserData(u)
local AdvBookElement b
if IsUnitInGroup(u,RegisterGroup) then
if sid == CANCEL_BUTTON then
call BookUnit[id].cancel()
elseif sid == NEXT_BUTTON then
call BookUnit[id].next()
else
set b = AdvBookElement.GetElementByID(sid)
if b != 0 then
if b.isBook then
call BookUnit[id].open(b)
endif
set AdvBookEvent.EventUnit = u
set AdvBookEvent.EventIconID = sid
set AdvBookEvent.EventElement = b
call EVENT_ADVBOOK_CLICK.fire()
set AdvBookEvent.EventUnit = null
endif
endif
endif
set u = null
return false
endmethod
public method next takes nothing returns nothing
call close(false)
call open(currentBook)
endmethod
public method cancel takes nothing returns nothing
call close(true)
endmethod
public method open takes AdvBookElement book returns boolean
local Link temp
local AdvBookElement b
local integer limit
local HeroData hd
if IsValid(Index[this].u) and book.list.size != 0 then
if currentBook != book then
if currentBook == 0 then
set currentBook = book
else
call close(false)
call prevBooks.addLast(currentBook)
set currentBook = book
set lastElement = 0
endif
endif
if lastElement != 0 then
set temp = lastElement.next
if temp.next == 0 then
set temp = currentBook.list.head
endif
else
set temp = currentBook.list.head
endif
if currentBook.list.size > PAGE_MAX_ELEM then
set limit = PAGE_MAX_ELEM - 1
call UnitAddAbility(Index[this].u,NEXT_BUTTON)
else
set limit = PAGE_MAX_ELEM
endif
if prevBooks.size != 0 then
call UnitAddAbility(Index[this].u,CANCEL_BUTTON)
endif
call UnitRemoveAbility(Index[this].u,currentBook.iconID)
set count = 0
loop
exitwhen temp == 0 or count == limit
set b = temp.data
set hd = b.data
call UnitAddAbility(Index[this].u,b.iconID)
if hd.IsSelected and hd != 0 then
call BlzUnitDisableAbility(Index[this].u,b.iconID,true,false)
endif
set count = count + 1
set lastElement = temp
set temp = temp.next
endloop
return true
endif
return false
endmethod
public method close takes boolean openPrev returns boolean
local Link temp
local AdvBookElement b
if count != 0 and currentBook != 0 then
set temp = lastElement
else
return false
endif
call UnitRemoveAbility(Index[this].u,CANCEL_BUTTON)
call UnitRemoveAbility(Index[this].u,NEXT_BUTTON)
loop
exitwhen count == 0
set b = temp.data
call UnitRemoveAbility(Index[this].u,b.iconID)
set count = count - 1
set temp = temp.prev
endloop
if openPrev then
if prevBooks.size > 0 then
set b = prevBooks.last.data
call prevBooks.remove(prevBooks.last)
set currentBook = b
set lastElement = 0
call open(b)
else
call UnitAddAbility(Index[this].u,currentBook.iconID)
endif
endif
return true
endmethod
public static method create takes unit u returns thistype
local thistype this = GetUnitUserData(u)
set prevBooks = LinkedList.create()
set currentBook = 0
set lastElement = 0
call GroupAddUnit(RegisterGroup,u)
set count = 0
return this
endmethod
public method destroy takes nothing returns nothing
call close(false)
call GroupRemoveUnit(RegisterGroup,Index[this].u)
if FirstOfGroup(RegisterGroup) == null then
call ReleaseGroup(RegisterGroup)
set RegisterGroup = null
call DestroyTrigger(OnClickTrigger)
set OnClickTrigger = null
endif
call prevBooks.destroy()
endmethod
public static method onInit takes nothing returns nothing
set OnClickTrigger = CreateTrigger()
set RegisterGroup = NewGroup()
call TriggerRegisterAnyUnitEventBJ(OnClickTrigger,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(OnClickTrigger,Condition(function thistype.OnClick))
endmethod
endstruct
function RegisterAdvBookClickEvent takes code c, Event e returns nothing
call e.register(Filter(c))
endfunction
private function init takes nothing returns nothing
call PreloadGen.Add(CANCEL_BUTTON,PRELOAD_SECOND)
call PreloadGen.Add(NEXT_BUTTON,PRELOAD_SECOND)
endfunction
endlibrary
scope GameCommands initializer init
function WinResources takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
if p == Player(2) and not Game.GameStarted then
if s == "rtw" then
if v == "1" then
set Game.ResourcesToWin = 3000
call Message.Show("Resources to win the game set to 3000",MESSAGE_STYLE_COMMAND)
elseif v == "2" then
set Game.ResourcesToWin = 4000
call Message.Show("Resources to win the game set to 4000",MESSAGE_STYLE_COMMAND)
elseif v == "3" then
set Game.ResourcesToWin = 5000
call Message.Show("Resources to win the game set to 5000",MESSAGE_STYLE_COMMAND)
endif
endif
endif
set p = null
endfunction
function Movement takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local Hero h
if s == "ms" then
set h = GetPlayerHero(p)
if h != 0 then
call Message.ShowToPlayer(p,"Movement Speed: "+I2S(R2I(GetUnitMoveSpeed(h.hero))),MESSAGE_STYLE_COMMAND)
endif
endif
set p = null
endfunction
function CameraSmooth takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
if s == "camst" then
if Players[GetPlayerId(p)].camSmooth then
set Players[GetPlayerId(p)].camSmooth = false
call Message.ShowToPlayer(p,"Camera smothing turned OFF",MESSAGE_STYLE_COMMAND)
if Game.LocalPlayer == p then
call CameraSetSmoothingFactor(0.00)
endif
else
set Players[GetPlayerId(p)].camSmooth = true
call Message.ShowToPlayer(p,"Camera smothing turned ON",MESSAGE_STYLE_COMMAND)
if Game.LocalPlayer == p then
call CameraSetSmoothingFactor(Game.CAMERA_SMOTH_FACTOR)
endif
endif
endif
set p = null
endfunction
function Clear takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
if s == "clear" then
if Game.LocalPlayer == p then
call ClearTextMessages()
endif
endif
set p = null
endfunction
function Unstuck takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local integer vi
local Hero h
local player ps
if s == "unstuck" then
set vi = S2I(v)
set vi = vi + 1
set ps = Player(vi)
if GetPlayerController(ps) == MAP_CONTROL_COMPUTER and vi != 0 and vi != 1 then
set h = GetPlayerHero(ps)
if h != 0 then
call AICore.HeroOrderTP(h,null,h.heroAI.team.startX,h.heroAI.team.startY)
endif
endif
endif
set p = null
set ps = null
endfunction
function AoEX takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local real a
local AoE aoe
local Hero h
if s == "aoe" then
set a = S2R(v)
set h = GetPlayerHero(p)
if IsHeroInBase(p) and not IsUnitInCombat(h.hero) and (a > 0 and a < 2000) then
set aoe = AoE.create(0,0,h.hero,a)
call aoe.setTime(3.0)
endif
endif
set p = null
endfunction
function AoEShow takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
if s == "aoeshow" then
set Players[GetPlayerId(p)].aoeShow = not Players[GetPlayerId(p)].aoeShow
if Players[GetPlayerId(p)].aoeShow then
call Message.ShowToPlayer(p,"AoE sfx turn on",MESSAGE_STYLE_COMMAND)
else
call Message.ShowToPlayer(p,"AoE sfx turn off",MESSAGE_STYLE_COMMAND)
endif
endif
set p = null
endfunction
function DmgText takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local integer i
if s == "dmgtext" then
set i = S2I(v)
if i == 1 then
call Message.ShowToPlayer(p,"Damage Text Mode: Normal",MESSAGE_STYLE_COMMAND)
set Players[GetPlayerId(p)].damageTextMode = i
elseif i == 2 then
call Message.ShowToPlayer(p,"Damage Text Mode: Disabled",MESSAGE_STYLE_COMMAND)
set Players[GetPlayerId(p)].damageTextMode = i
elseif i == 3 then
call Message.ShowToPlayer(p,"Damage Text Mode: Critical",MESSAGE_STYLE_COMMAND)
set Players[GetPlayerId(p)].damageTextMode = i
else
call Message.ShowToPlayer(p,"Damage Text Mode: Invalid Mode",MESSAGE_STYLE_COMMAND)
endif
endif
set p = null
endfunction
private function init takes nothing returns nothing
call AddCommandListener("rtw",false,function WinResources)
call AddCommandListener("ms",true,function Movement)
call AddCommandListener("camst",true,function CameraSmooth)
call AddCommandListener("clear",true,function Clear)
call AddCommandListener("unstuck",false,function Unstuck)
call AddCommandListener("aoe",false,function AoEX)
call AddCommandListener("aoeshow",true,function AoEShow)
call AddCommandListener("dmgtext",false,function DmgText)
endfunction
endscope
scope TestCommands
globals
unit TEST_DUMMY = null
endglobals
private function levelx takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local integer lvl
local Hero h = GetPlayerHero(p)
if s == "level" and h != 0 then
set lvl = S2I(v)
if lvl > 0 and lvl < 20 then
loop
exitwhen lvl == 0
call SetHeroLevel(h.hero,GetHeroLevel(h.hero) + 1,false)
set lvl = lvl - 1
endloop
endif
endif
set p = null
endfunction
private function ailevel takes nothing returns nothing
local string s = EventChatCommand
local string v = EventChatValue
local player p = Player(S2I(v) + 1)
local Hero h = GetPlayerHero(p)
if s == "ailevel" then
if GetPlayerController(p) == MAP_CONTROL_COMPUTER and h != 0 then
call SetHeroLevel(h.hero,GetHeroLevel(h.hero) + 1,false)
endif
endif
set p = null
endfunction
private function goldhonor takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
if s == "g" then
call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,999999)
endif
set p = null
endfunction
private function dummy takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local Hero h = GetPlayerHero(p)
local Team t = 2/GetPlayerTeamEx(p)
if s == "dummy" and h != 0 then
if TEST_DUMMY == null then
set TEST_DUMMY = CreateUnit(t.captain,'Hmkg',GetUnitX(h.hero),GetUnitY(h.hero),0)
call SetHeroLevel(TEST_DUMMY,20,false)
else
call RemoveUnit(TEST_DUMMY)
set TEST_DUMMY = null
endif
endif
set p = null
endfunction
private function tp takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local Hero h = GetPlayerHero(p)
if s == "tp" and h != 0 then
if GetUnitAbilityLevel(h.hero,'AEbl') != 0 then
call UnitRemoveAbility(h.hero,'AEbl')
else
call UnitAddAbility(h.hero,'AEbl')
endif
endif
set p = null
endfunction
private function st takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local Hero h = GetPlayerHero(p)
if s == "status" and h != 0 then
call Status.Add(S2I(v),h.hero,4.00,Status_EFFECT[S2I(v)])
endif
set p = null
endfunction
function TowerLevel takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local Base b
local integer va
if s == "tlvl" then
set va = S2I(v)
call SetUnitData(Base[va].tower,"Upgrade",599)
endif
set p = null
endfunction
function GoldCapture takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local integer va
if s == "gcap" then
call GoldMine[S2I(v)].changeOwner(Game.PLAYER_WARCHIEF_HORDE)
endif
set p = null
endfunction
function Resources takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local integer r
local Hero h
if s == "resources" then
set r = S2I(v)
call GetPlayerTeamEx(p).addResource(r)
endif
set p = null
endfunction
function WarHall takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
if s == "wh" then
call IssuePointOrderById(Team[2].warHall,ORDER_rainoffire,AncientObelisk.x,AncientObelisk.y)
endif
set p = null
endfunction
function AIState takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local Base b
local AICore ai
local integer va
if s == "ais" then
set va = S2I(v) - 1
set ai = AICore[va]
call BJDebugMsg("AI Name"+GetUnitName(ai.playerHero.hero))
if ai.state == 2 then
call BJDebugMsg("To Tower - "+I2S(ai.targetBase))
elseif ai.state == 3 then
call BJDebugMsg("To Mine -"+I2S(ai.targetMine))
elseif ai.returnToBase then
call BJDebugMsg("To Fountain")
elseif ai.state == 6 then
call BJDebugMsg("To Final")
elseif ai.state == 7 then
call BJDebugMsg("To Obelisk")
endif
call PlayerPingMinimap(Player(2),ai.retreatX,ai.retreatY,1.0,255,255,255)
endif
set p = null
endfunction
function UITest takes nothing returns nothing
local player p = EventChatPlayer
local string s = EventChatCommand
local string v = EventChatValue
local framehandle fh
local framehandle fh2
local framehandle fh3
local integer index = S2I(v)
if s == "icon" then
set fh = BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON,index)
set fh2 = BlzCreateSimpleFrame("BoxedText",BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),0)
call BlzFrameSetPoint(fh2, FRAMEPOINT_BOTTOM, fh, FRAMEPOINT_BOTTOMRIGHT, -0.0085,0.001)
set fh3 = BlzGetFrameByName("BoxedTextText",0)
call BlzFrameSetTexture(BlzGetFrameByName("BoxedTextTexture",0), "UI\\Widgets\\Console\\Human\\human-transport-slot", 0, true)
call BlzFrameSetLevel(fh2,9)
//call BlzFrameSetTextAlignment(fh3, TEXT_JUSTIFY_MIDDLE, TEXT_JUSTIFY_CENTER)
call BlzFrameSetText(fh3, "3")
//call BlzFrameSetTextColor(fh3,16777215)
call BlzFrameSetVisible(fh2,true)
//call BlzFrameSetVisible(fh3,true)
endif
set p = null
endfunction
public function Setup takes nothing returns nothing
local string s
call AddCommandListener("level",false,function levelx)
call AddCommandListener("ailevel",false,function ailevel)
call AddCommandListener("g",true,function goldhonor)
call AddCommandListener("dummy",true,function dummy)
call AddCommandListener("tp",true,function tp)
call AddCommandListener("status",false,function st)
//For testing purposes
call AddCommandListener("tlvl",false,function TowerLevel)
call AddCommandListener("gcap",false,function GoldCapture)
call AddCommandListener("resources",false,function Resources)
call AddCommandListener("wh",true,function WarHall)
call AddCommandListener("ais",false,function AIState)
call AddCommandListener("icon",false,function UITest)
set s = "|c0000ffffSingle Player Commands:|r|n|n -level x: sets the level of your hero to +x|n -ailevel x: sets the level of the AI number x, to +1|n -g: gives 99999 gold.|n -dummy: summon/unsummon a Dummy hero at hero's position. |n -tp: gives global teleport ability.|n -status x: apply the status X to your hero for 4 seconds (1: Stun,2: Silence, etc)"
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Single Player Commands")
call QuestSetDescription(bj_lastCreatedQuest, s)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNBansheeAdept.blp")
call QuestSetRequired(bj_lastCreatedQuest, false)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
endscope
scope PlayerLeave initializer init
function PlayerLeave takes nothing returns nothing
local player p = GetTriggerPlayer()
local Players ps = Players[GetPlayerId(p)]
local Hero he = GetPlayerHero(p)
local Team t = GetPlayerTeamEx(p)
local integer g = GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)
local integer h = GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER)
set t.playerCount = t.playerCount - 1
if ps.traitUnit == null then
set Players.TraitCount = Players.TraitCount - 1
else
call RemoveUnit(ps.traitUnit)
set ps.traitUnit = null
endif
call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,0)
call SetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER,0)
set Players[GetPlayerId(p)].isPlaying = false
call DisplayTextToForce(GetPlayersAll(),(GetPlayerName(p)+ " has left the game" ))
call SetUnitX(he.hero,t.startX)
call SetUnitY(he.hero,t.startY)
call AddTeamGold(t,g/t.playerCount)
call MultiboardUpdatePlayerName(p,"|c00c0c0c0Leaver|r")
set p = null
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterPlayerEvent(t, Player(2), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(3), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(4), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(5), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(6), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(7), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(8), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(9), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(10), EVENT_PLAYER_LEAVE)
call TriggerRegisterPlayerEvent(t, Player(11), EVENT_PLAYER_LEAVE)
call TriggerAddAction(t, function PlayerLeave)
set t = null
endfunction
endscope
library MapInfo
private function CreateTowerDescription takes nothing returns nothing
local string s = "|c0000ffffThe Towers are defensive structures that can be controled and spawn units periodically.|r|n|n- The Towers can be captured by placing the hero inside the |c00ff8080circle of power|r, after 10 seconds and if the hero not die or leaves the circle, the Tower will be controlled and take less time if more heroes are controlling the Tower at once."
local string s2 = "|n- If the Tower is destroyed the will become |c00ff8080Neutral |rand will be able to get controlled again.|n- Every controlled Tower will |c00ff8080spawn units|r to attack the next enemy Tower or Gold Mine.|n- The Towers will be Upgraded every 10min (of constant controlled time), increasing the HP and Damage."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Towers")
call QuestSetDescription(bj_lastCreatedQuest, s+s2)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNHumanWatchTower.blp")
call QuestSetRequired(bj_lastCreatedQuest, true)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateGoldMineDescription takes nothing returns nothing
local string s = "|c0000ffffThe Gold mines are structures that generates the Resources required to win the game and gives 1 Gold income to the owner.|r|n|n - The Gold Mines generate |c00ff8080Resources |rperiodically, and are guarded by a group of units called |c00ff8080Guards|r.|n"
local string s2 = "|n- The |c00ff8080Guards |rare elite units that defend the Gold Mine, but if they are defeated the Gold Mine will pass in to enemy hands.|n-|c00ff0000 |rThe |c00ff8080Guards |rare improved (HP, Armor, Abilities) based on the corresponding Tower level."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Gold Mines")
call QuestSetDescription(bj_lastCreatedQuest, s+s2)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNGoldMine.blp")
call QuestSetRequired(bj_lastCreatedQuest, true)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateCommanderDescription takes nothing returns nothing
local string s = "|c0000ffffEach team has a Commander placed in the base.|r|n|n"
local string s2 = "- The Commander is a powerful Hero that can fight in the battlefield and has |c00ff8080Refine|r abilities that affects the Towers and Gold Mines."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Team Commander")
call QuestSetDescription(bj_lastCreatedQuest, s + s2)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNINV_helm_crown_C_01_silver.blp")
call QuestSetRequired(bj_lastCreatedQuest, true)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateWarHallDescription takes nothing returns nothing
local string s = "|c0000ffffThe War Hall is a structure that has powerful global abilities to use by players using the team resources.|r|n
- The abilities are enabled from |c00ff808010 minutes|r of game.|n- The Cooldown and cost of the abilities varies based on the difference of Resources with the enemy team."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"War Hall")
call QuestSetDescription(bj_lastCreatedQuest, s)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNFortress.blp")
call QuestSetRequired(bj_lastCreatedQuest, true)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateAncientObeliskDescription takes nothing returns nothing
local string s = "|c0000ffffThe Ancient Obelisk is a mystical structure that emanates power that recovers the energy of the heroes.|r|n
- Can be captured since |c00ff808010 minutes|r of game.|n- A hero need to |c00ff8080Canalize|r for 15 seconds to capture the Obelisk, upon captured lasts |c00ff80803 minutes|r. The hero will be totally disabled during capture.|n- When the capture time ends, the Obelisk will be able to get captured again.|n- Every 3 seconds the Obelisk emits a |c00ff8080ray of healing|r that recovers HP of a random hero in combat."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Ancient Obelisk")
call QuestSetDescription(bj_lastCreatedQuest, s)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNIceCrownObelisk.blp")
call QuestSetRequired(bj_lastCreatedQuest, true)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateEnchantDescription takes nothing returns nothing
local string s = "|c0000ffffThe Items can be Enchanted, adding effects or bonuses.|r|n|n- There are 2 types of Enchantments, (|c00ff8080Bonus and Effect|r).|n- The |c00ff8080Bonus Enchantments|r can be applied to any classified item and cost 500 gold.|n- The |c00ff8080Effect Enchantments|r can be applied to a |c00ff8080Tier 3|r |c00ff8080Weapon|r or |c00ff8080Armor|r item types and cost 1000 Gold.|n- An item can only have one enchantment at a time."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Enchant Items")
call QuestSetDescription(bj_lastCreatedQuest, s)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNSnazzyScrollGreen.blp")
call QuestSetRequired(bj_lastCreatedQuest, false)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateItemClassDescription takes nothing returns nothing
local string s = "|c0000ffffThe Items are classified by type and can be upgraded up to Tier 3.|r|n|n- There are 4 main types of items |c00ba55d3Weapon,|r|c0000bfff |r|c0066cdaaArmor, |r|c007759eeTrinket |rand|c007759ee |r|c0000bfffMagic Accessory|r.|c0000bfff |r|n- This types of items can be |c00ff8080upgraded|r and |c00ff8080enchanted|r, increasing the attributes and the power of the abilities."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Item Types and Tier System")
call QuestSetDescription(bj_lastCreatedQuest, s)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNINV_Sword_113.blp")
call QuestSetRequired(bj_lastCreatedQuest, false)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateSkillUpgradeDescription takes nothing returns nothing
local string s = "|c0000ffffEvery ability of the heros can be Upgraded, increasing his effects or adding new ones.|r|n|n- The hero will receive a |c00ff8080point|r to spent in a |c00ff8080Upgrade|r in the levels (4,6,8,10,12,14,16,18,20).|n- The first Upgrade that reach |c00ff8080level 3|r gives the (|c00ff8080Superior Upgrade|r) effect indicated in the tooltip."
local string s2 = "|n- When the hero reaches the level 14 will enable the |c00ff80804th Upgrade|r that improves the Ultimate ability and brings the possibility to choose a |c00ff8080Mastery|r.|n- The |c00ff8080Mastery |rcan be learned at the Altar, there are 3 Mastery types (|c00ff8080Combat,Dexterity,Wisdom|r) only one of them can be chosen and are different for each hero."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Skill Upgrade/Mastery")
call QuestSetDescription(bj_lastCreatedQuest, s+s2)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNEngineeringUpgrade.blp")
call QuestSetRequired(bj_lastCreatedQuest, false)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateInfoDescription takes nothing returns nothing
local string s3 = "eMe#8273"
local string s = "|c000ffffThe map has been developed by -ManueL-|r|n|n- Coded in vJass using Reforged Editor.|n- Hiveworkshop Account: -Manuel-.|n- Discord Account:"+s3
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Map Info")
call QuestSetDescription(bj_lastCreatedQuest, s)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn.blp")
call QuestSetRequired(bj_lastCreatedQuest, false)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
private function CreateGameCommandsDescription takes nothing returns nothing
local string s = "|c0000ffffMap Commands|nGame Commands:|r|n|c0000ffffPlayer Commands:|r
-ms = Shows hero movement speed.|n -clear = clear all messages.|n -dmgtext (1,2,3) = set the damage text mode.|n -aoeshow = show/hide the aoe indicator.|n -aoe = shows the aoe of X value around the hero.|n|c0000ffffAI Commands:|r
-unstuck #(1,10) = Order to the AI player # to use teleport to the base."
set bj_lastCreatedQuest = CreateQuest()
call QuestSetTitle(bj_lastCreatedQuest,"Game Commands")
call QuestSetDescription(bj_lastCreatedQuest, s)
call QuestSetIconPath(bj_lastCreatedQuest, "ReplaceableTextures\\CommandButtons\\BTNBansheeMaster.blp")
call QuestSetRequired(bj_lastCreatedQuest, false)
call QuestSetDiscovered(bj_lastCreatedQuest, true)
call QuestSetCompleted(bj_lastCreatedQuest, false)
endfunction
public function Setup takes nothing returns nothing
call CreateCommanderDescription()
call CreateGoldMineDescription()
call CreateTowerDescription()
call CreateAncientObeliskDescription()
call CreateWarHallDescription()
//-----------------------//
call CreateItemClassDescription()
call CreateEnchantDescription()
call CreateSkillUpgradeDescription()
call CreateGameCommandsDescription()
call CreateInfoDescription()
endfunction
endlibrary
scope LastManStanding
globals
rect array PlayerInitPos
rect array AI_Stands
rect array AI_Stands2
timer Timer
timerdialog TimerDialog
LinkedList Heroes
integer I = 0
constant integer GOLD_BONUS = 700
constant integer HONOR_BONUS = 10
Team Winner = 0
endglobals
private function EndRoundCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Link h = Heroes.head
local LoadingBar lb
local integer gt
local player ps
local Players p
local Team te
local integer lvl
local CobraK300 b
local integer um
loop
exitwhen h == 0
set p = h.data
set ps = Player(p)
set te = GetPlayerTeamEx(ps)
set lvl = GetHeroLevel(p.hero.hero)
set p.inArena = false
if not UnitAlive(p.hero.hero) then
if UnitHasBuff(p.hero.hero,DeadChecker.buff) then
call SetUnitX(p.hero.hero,te.startX)
call SetUnitY(p.hero.hero,te.startY)
else
call ReviveHero(p.hero.hero,te.startX,te.startY,false)
endif
set um = GetUnitData(p.hero.hero,"UnMorph")
if um != 0 then
call AddUnitAnimationProperties(p.hero.hero,"alternate",false)
call SetUnitData(p.hero.hero,"UnMorph",0)
call UnitAddAbility(p.hero.hero,um)
call UnitRemoveAbility(p.hero.hero,um)
endif
set lb = GetUnitData(p.hero.hero,"OHBar")
if lb != 0 then
call lb.show(true)
endif
else
call Status.Remove(STATUS_INVULNERABLE,p.hero.hero)
set b = GetUnitBuff(p.hero.hero,CobraK300.buff).buffAllocIndex
if b != 0 then
call UnitRemoveBuff(p.hero.hero,CobraK300.buff)
endif
call SetUnitX(p.hero.hero,te.startX)
call SetUnitY(p.hero.hero,te.startY)
endif
call IssueImmediateOrder(p.hero.hero,"stop")
if Game.LocalPlayer == ps then
call SetCameraPosition(te.startX,te.startY)
call SelectUnit(p.hero.hero,true)
endif
set gt = 75 * p.heroesKilledTemp
call AddPlayerGold(ps,GOLD_BONUS + gt)
call Message.ShowToPlayer(ps,"You receive "+GOLD_COLOR+"700(+"+I2S(gt)+") Gold|r from this round",MESSAGE_STYLE_LMS)
set p.heroesKilledTemp = 0
if Game.Round <= 9 then
call SetHeroLevel(p.hero.hero,lvl + 1,true)
else
call SetHeroLevel(p.hero.hero,lvl + 1,false)
call SetHeroLevel(p.hero.hero,lvl + 2,true)
endif
set h = h.next
endloop
set Game.RoundStarted = false
call Heroes.destroy()
set Heroes = LinkedList.create()
call ReleaseTimer(t)
call StartSound(gg_snd_RoundEnd)
set t = null
if Game.Round == 15 then
if Team[1].rounds > Team[2].rounds then
call VictoryConditions_RunGameOver.evaluate(1)
else
call VictoryConditions_RunGameOver.evaluate(2)
endif
else
call LastManStanding_Start.evaluate()
endif
endfunction
public function EndRound takes Team te returns nothing
local timer t = NewTimer()
local Link h = Heroes.head
local Players p
loop
exitwhen h == 0
set p = h.data
if UnitAlive(p.hero.hero) then
call Status.Add(STATUS_INVULNERABLE,p.hero.hero,0,0)
endif
set h = h.next
endloop
if te == 1 then
call Message.Show("The winner of this round: "+HORDE_COLOR+te.name+"|r",MESSAGE_STYLE_LMS)
else
call Message.Show("The winner of this round: "+ALLIANCE_COLOR+te.name+"|r",MESSAGE_STYLE_LMS)
endif
call StartSound(gg_snd_GameStart)
set te.rounds = te.rounds + 1
call BlzFrameSetText(OrcResourcesTextFrame, HORDE_COLOR+I2S(Team[1].rounds)+"|r")
call BlzFrameSetText(HumanResourcesTextFrame, HORDE_COLOR+I2S(Team[2].rounds)+"|r")
set Winner = te
call TimerStart(t,2.0,false,function EndRoundCallback)
set t = null
endfunction
private function Counter takes nothing returns nothing
local timer t = GetExpiredTimer()
local Link h = Heroes.head
local Players p
set I = I + 1
if I <= 3 then
call Message.Show("The fight will begin in "+I2S(I),MESSAGE_STYLE_LMS)
call StartSound(gg_snd_Clock)
endif
if I == 4 then
set Game.RoundStarted = true
call ReleaseTimer(t)
loop
exitwhen h == 0
set p = h.data
call Status.Remove(STATUS_PAUSE,p.hero.hero)
set h = h.next
endloop
call StartSound(gg_snd_GameStart)
endif
set t = null
endfunction
private function StartRound takes nothing returns nothing
local integer i = 2
local timer t = NewTimer()
local real x
local real y
local Players p
local Team te
set Team[1].heroesIn = 0
set Team[2].heroesIn = 0
loop
set p = Players[i]
if p.isPlaying and p.hero != 0 then
set p.inArena = true
set x = GetRectCenterX(PlayerInitPos[i])
set y = GetRectCenterY(PlayerInitPos[i])
set te = GetPlayerTeamEx(Player(i))
call SetUnitX(p.hero.hero,x)
call SetUnitY(p.hero.hero,y)
if te == 1 then
call SetUnitFacing(p.hero.hero,0)
else
call SetUnitFacing(p.hero.hero,180)
endif
if p.hero.heroAI != -1 then
set p.hero.heroAI.courageBase = 1.5
endif
call Status.Add(STATUS_PAUSE,p.hero.hero,0,0)
call Heroes.add(p)
set te.heroesIn = te.heroesIn + 1
if Game.LocalPlayer == Player(i) then
call SetCameraPosition(x,y)
call SelectUnit(p.hero.hero,true)
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
set I = 0
call TimerStart(t,1.0,true,function Counter)
endfunction
public function Start takes nothing returns nothing
set Game.Round = Game.Round + 1
set Winner = 0
if Game.Round <= Game.Rounds then
if Game.Round > 1 then
call Message.Show("The next round will begin in 70 seconds",MESSAGE_STYLE_LMS)
call TimerStart(Timer,70.00,false,function StartRound)
call TimerDialogDisplay(TimerDialog,true)
call TimerDialogSetTitle(TimerDialog,"Round: "+I2S(Game.Round))
else
call TimerStart(Timer,120.00,false,function StartRound)
call TimerDialogDisplay(TimerDialog,true)
call TimerDialogSetTitle(TimerDialog,"Round: "+I2S(Game.Round))
endif
endif
endfunction
public function Setup takes nothing returns nothing
set PlayerInitPos[2] = gg_rct_StartHero1
set PlayerInitPos[3] = gg_rct_StartHero2
set PlayerInitPos[4] = gg_rct_StartHero3
set PlayerInitPos[5] = gg_rct_StartHero4
set PlayerInitPos[6] = gg_rct_StartHero5
set PlayerInitPos[7] = gg_rct_StartHero6
set PlayerInitPos[8] = gg_rct_StartHero7
set PlayerInitPos[9] = gg_rct_StartHero8
set PlayerInitPos[10] = gg_rct_StartHero9
set PlayerInitPos[11] = gg_rct_StartHero10
set AI_Stands[0] = gg_rct_StartHero8
set AI_Stands[1] = gg_rct_Arena_Stand_1
set AI_Stands[2] = gg_rct_Arena_Stand_2
set AI_Stands[3] = gg_rct_Arena_Stand_3
set AI_Stands[4] = gg_rct_Arena_Stand_4
set AI_Stands[5] = gg_rct_Arena_Stand_5
set AI_Stands[6] = gg_rct_Arena_Stand_6
set AI_Stands[7] = gg_rct_StartHero3
set Heroes = LinkedList.create()
set Timer = CreateTimer()
set TimerDialog = CreateTimerDialog(Timer)
endfunction
endscope
scope ObeliskDefend
globals
private AoE Circle
integer ODWinner = 0
Team CurrentOwner = 0
endglobals
private function EndRoundCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Link h = Heroes.head
local LoadingBar lb
local player ps
local Players p
local integer gt
local Team te
local integer lvl
local CobraK300 b
local integer um
loop
exitwhen h == 0
set p = h.data
set ps = Player(p)
set te = GetPlayerTeamEx(ps)
set lvl = GetHeroLevel(p.hero.hero)
set p.inArena = false
if not UnitAlive(p.hero.hero) then
if UnitHasBuff(p.hero.hero,DeadChecker.buff) then
call SetUnitX(p.hero.hero,te.startX)
call SetUnitY(p.hero.hero,te.startY)
else
call ReviveHero(p.hero.hero,te.startX,te.startY,false)
endif
set um = GetUnitData(p.hero.hero,"UnMorph")
if um != 0 then
call AddUnitAnimationProperties(p.hero.hero,"alternate",false)
call SetUnitData(p.hero.hero,"UnMorph",0)
call UnitAddAbility(p.hero.hero,um)
call UnitRemoveAbility(p.hero.hero,um)
endif
set lb = GetUnitData(p.hero.hero,"OHBar")
if lb != 0 then
call lb.show(true)
endif
else
call Status.Remove(STATUS_INVULNERABLE,p.hero.hero)
set b = GetUnitBuff(p.hero.hero,CobraK300.buff).buffAllocIndex
if b != 0 then
call UnitRemoveBuff(p.hero.hero,CobraK300.buff)
endif
call SetUnitX(p.hero.hero,te.startX)
call SetUnitY(p.hero.hero,te.startY)
endif
if p.hero.heroAI != -1 then
set p.hero.heroAI.courageBase = 1.0
endif
call IssueImmediateOrder(p.hero.hero,"stop")
if Game.LocalPlayer == ps then
call SetCameraPosition(te.startX,te.startY)
call SelectUnit(p.hero.hero,true)
endif
set gt = 75 * p.heroesKilledTemp
call AddPlayerGold(ps,GOLD_BONUS + gt)
call Message.ShowToPlayer(ps,"You receive "+GOLD_COLOR+"700(+"+I2S(gt)+") Gold|r from this round",MESSAGE_STYLE_LMS)
set p.heroesKilledTemp = 0
if Game.Round <= 9 then
call SetHeroLevel(p.hero.hero,lvl + 1,true)
else
call SetHeroLevel(p.hero.hero,lvl + 1,false)
call SetHeroLevel(p.hero.hero,lvl + 2,true)
endif
set h = h.next
endloop
set Game.RoundStarted = false
call Heroes.destroy()
set Heroes = LinkedList.create()
call ReleaseTimer(t)
call StartSound(gg_snd_RoundEnd)
set t = null
if Game.Round == 15 then
if Team[1].rounds > Team[2].rounds then
call VictoryConditions_RunGameOver.evaluate(1)
else
call VictoryConditions_RunGameOver.evaluate(2)
endif
else
call ObeliskDefend_Start.evaluate()
endif
endfunction
public function EndRound takes Team te returns nothing
local timer t = NewTimer()
local Link h = Heroes.head
local Players p
set Game.RoundStarted = false
loop
exitwhen h == 0
set p = h.data
if UnitAlive(p.hero.hero) then
call Status.Add(STATUS_INVULNERABLE,p.hero.hero,0,0)
endif
set h = h.next
endloop
set AncientObelisk.owner = 0
call AncientObelisk.ChangeOwner(true)
call AncientObelisk.Enable(false)
call BlzSetSpecialEffectColor(Circle.sfx,255,255,255)
call SetUnitState(AncientObelisk.obelisk,UNIT_STATE_LIFE,99999)
if te == 1 then
call Message.Show("The winner of this round: "+HORDE_COLOR+te.name+"|r",MESSAGE_STYLE_LMS)
else
call Message.Show("The winner of this round: "+ALLIANCE_COLOR+te.name+"|r",MESSAGE_STYLE_LMS)
endif
set te.rounds = te.rounds + 1
set ODWinner = te
call TimerStart(t,2.0,false,function EndRoundCallback)
set t = null
endfunction
private function EndRoundTimer takes nothing returns nothing
if ODWinner == 0 then
if AncientObelisk.owner == CurrentOwner then
call EndRound(CurrentOwner)
endif
endif
call PauseTimer(Timer)
call TimerDialogDisplay(TimerDialog,false)
endfunction
private function Counter takes nothing returns nothing
local timer t = GetExpiredTimer()
local Link h = Heroes.head
local Players p
set I = I + 1
if I <= 3 then
call Message.Show("The fight will begin in "+I2S(I),MESSAGE_STYLE_LMS)
call StartSound(gg_snd_Clock)
endif
if I == 4 then
set Game.RoundStarted = true
call ReleaseTimer(t)
loop
exitwhen h == 0
set p = h.data
call Status.Remove(STATUS_PAUSE,p.hero.hero)
set h = h.next
endloop
call StartSound(gg_snd_GameStart)
if CurrentOwner == 1 then
call BlzSetSpecialEffectColor(Circle.sfx,255,0,0)
else
call BlzSetSpecialEffectColor(Circle.sfx,0,0,255)
endif
call AncientObelisk.Enable(true)
set AncientObelisk.owner = CurrentOwner
call AncientObelisk.ChangeOwner(false)
if CurrentOwner == 1 then
call Message.Show(HORDE_COLOR+CurrentOwner.name + "|r will have to defend the Obelisk for 90s min to win",MESSAGE_STYLE_LMS)
else
call Message.Show(ALLIANCE_COLOR+CurrentOwner.name + "|r will have to defend the Obelisk for 90s min to win",MESSAGE_STYLE_LMS)
endif
call TimerStart(Timer,90.00,false,function EndRoundTimer)
call TimerDialogSetTitle(TimerDialog,"Round End")
endif
set t = null
endfunction
private function StartRound takes nothing returns nothing
local integer i = 2
local integer r
local real a
local timer t = NewTimer()
local real x
local real y
local Players p
local Team te
local LinkedList l = LinkedList.create()
local Link link
set Team[1].heroesIn = 0
set Team[2].heroesIn = 0
if Game.Round == 1 then
set CurrentOwner = GetRandomInt(1,2)
else
set CurrentOwner = 2/CurrentOwner
endif
if CurrentOwner == 1 then
call l.add(1)
call l.add(2)
call l.add(3)
call l.add(4)
call l.add(5)
else
call l.add(0)
call l.add(1)
call l.add(2)
call l.add(3)
call l.add(4)
endif
loop
set p = Players[i]
if p.isPlaying and p.hero != 0 then
set te = GetPlayerTeamEx(Player(i))
if te == CurrentOwner then
set a = GetRandomReal(0,360) * bj_DEGTORAD
set x = AncientObelisk.x + GetRandomReal(50,500) * Cos(a)
set y = AncientObelisk.y + GetRandomReal(50,500) * Sin(a)
call SetUnitFacing(p.hero.hero,Angle(x,y,AncientObelisk.x,AncientObelisk.y) * bj_RADTODEG)
else
set r = GetRandomInt(1,l.size)
set link = l.getByIndex(r)
if p.hero.heroAI != -1 then
set p.hero.heroAI.iniPlace = link.data
set p.hero.heroAI.courageBase = 3.0
endif
set x = GetRectCenterX(AI_Stands2[link.data])
set y = GetRectCenterY(AI_Stands2[link.data])
call l.remove(link)
call SetUnitFacing(p.hero.hero,Angle(x,y,AncientObelisk.x,AncientObelisk.y) * bj_RADTODEG)
endif
call SetUnitX(p.hero.hero,x)
call SetUnitY(p.hero.hero,y)
call Status.Add(STATUS_PAUSE,p.hero.hero,0,0)
call Heroes.add(p)
set p.inArena = true
set te.heroesIn = te.heroesIn + 1
if Game.LocalPlayer == Player(i) then
call SetCameraPosition(x,y)
call SelectUnit(p.hero.hero,true)
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
set te.heroesTotal = te.heroesIn
set I = 0
call l.destroy()
call TimerStart(t,1.0,true,function Counter)
endfunction
public function Start takes nothing returns nothing
set Game.Round = Game.Round + 1
set ODWinner = 0
if Game.Round <= Game.Rounds then
if Game.Round > 1 then
call Message.Show("The next round will begin in 70 seconds",MESSAGE_STYLE_LMS)
call TimerStart(Timer,70.00,false,function StartRound)
call TimerDialogDisplay(TimerDialog,true)
call TimerDialogSetTitle(TimerDialog,"Round: "+I2S(Game.Round))
call TimerDialogDisplay(TimerDialog,true)
call BlzSetUnitMaxHP(AncientObelisk.obelisk,50)
call SetUnitState(AncientObelisk.obelisk,UNIT_STATE_LIFE,10000)
else
call TimerStart(Timer,120.00,false,function StartRound)
call TimerDialogDisplay(TimerDialog,true)
call TimerDialogSetTitle(TimerDialog,"Round: "+I2S(Game.Round))
call TimerDialogDisplay(TimerDialog,true)
endif
endif
endfunction
private function onPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Team t = GetUnitTeam(data.target)
if t == CurrentOwner then
if Distance(GetUnitX(data.target),GetUnitY(data.target),AncientObelisk.x,AncientObelisk.y) <= 650 then
if data.dmgType == udg_DamageTypeHeal or data.dmgType == udg_DamageTypeHealOverTime then
set data.mult = data.mult + 0.25
else
set data.mult = data.mult - 0.25
endif
endif
endif
endfunction
private function onPostDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
if data.target == AncientObelisk.obelisk and not data.isMiss and not data.isAbsorbed then
if IsUnitType(data.source,UNIT_TYPE_HERO) then
if AncientObelisk.owner == 0 then
set data.damageMod = 0
set data.isAbsorbed = true
else
set data.damageMod = 2
if GetUnitState(data.target,UNIT_STATE_LIFE) - data.damageMod <= 0.405 then
set data.damageMod = 0
set data.isAbsorbed = true
call EndRound(2/AncientObelisk.owner)
endif
endif
else
set data.damageMod = 1
if GetUnitState(data.target,UNIT_STATE_LIFE) - data.damageMod <= 0.405 then
set data.damageMod = 0
set data.isAbsorbed = true
call EndRound(2/AncientObelisk.owner)
endif
endif
endif
endfunction
public function Setup takes nothing returns nothing
set PlayerInitPos[2] = gg_rct_StartHero1
set PlayerInitPos[3] = gg_rct_StartHero2
set PlayerInitPos[4] = gg_rct_StartHero3
set PlayerInitPos[5] = gg_rct_StartHero4
set PlayerInitPos[6] = gg_rct_StartHero5
set PlayerInitPos[7] = gg_rct_StartHero6
set PlayerInitPos[8] = gg_rct_StartHero7
set PlayerInitPos[9] = gg_rct_StartHero8
set PlayerInitPos[10] = gg_rct_StartHero9
set PlayerInitPos[11] = gg_rct_StartHero10
set AI_Stands[0] = gg_rct_StartHero8
set AI_Stands[1] = gg_rct_Arena_Stand_1
set AI_Stands[2] = gg_rct_Arena_Stand_2
set AI_Stands[3] = gg_rct_Arena_Stand_3
set AI_Stands[4] = gg_rct_Arena_Stand_4
set AI_Stands[5] = gg_rct_Arena_Stand_5
set AI_Stands[6] = gg_rct_Arena_Stand_6
set AI_Stands[7] = gg_rct_StartHero3
set AI_Stands2[0] = gg_rct_StartHero3
set AI_Stands2[1] = gg_rct_Arena_Stand_1
set AI_Stands2[2] = gg_rct_Arena_Stand_3
set AI_Stands2[3] = gg_rct_Arena_Stand_4
set AI_Stands2[4] = gg_rct_Arena_Stand_6
set AI_Stands2[5] = gg_rct_StartHero8
set Heroes = LinkedList.create()
set Timer = CreateTimer()
set TimerDialog = CreateTimerDialog(Timer)
set Circle = AoE.create(AncientObelisk.x,AncientObelisk.y,null,600)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
call DamageEvent.RegisterPostCalculation(Filter(function onPostDamage))
endfunction
endscope
library GameModes uses SpellEffectEvent
globals
Poll GameMode
private constant integer MODE_1 = 'A0A8'
private constant integer MODE_2 = 'A0A9'
private constant integer MODE_3 = 'A0AA'
private constant integer MODE_4 = 'A0BI'
private constant integer MODE_5 = 'A0AA'
endglobals
private function onCast takes nothing returns nothing
local integer id = GetSpellAbilityId()
local player p = GetTriggerPlayer()
if id == MODE_1 then
call GameMode.vote(p,"Normal")
elseif id == MODE_2 then
call GameMode.vote(p,"Last Man Standing")
elseif id == MODE_3 then
call GameMode.vote(p,"Obelisk Defend")
elseif id == MODE_4 then
call GameMode.vote(p,"Survival")
endif
set p = null
endfunction
public function End takes nothing returns nothing
call GameMode.destroy()
call RemoveSpellEffectEvent(MODE_1)
call RemoveSpellEffectEvent(MODE_2)
call RemoveSpellEffectEvent(MODE_3)
call RemoveSpellEffectEvent(MODE_4)
endfunction
public function Setup takes nothing returns nothing
set GameMode = Poll.create("GameMode")
call GameMode.addOption("Normal")
call GameMode.addOption("Last Man Standing")
//call GameMode.addOption("Obelisk Defend")
//call GameMode.addOption("Survival")
call RegisterSpellEffectEvent(MODE_1, function onCast)
call RegisterSpellEffectEvent(MODE_2, function onCast)
//call RegisterSpellEffectEvent(MODE_3, function onCast)
//call RegisterSpellEffectEvent(MODE_4, function onCast)
endfunction
endlibrary
library VoteSystem
struct Option extends array
implement Alloc
string name
integer count
public static method create takes string n returns thistype
local thistype this = thistype.allocate()
set name = n
return this
endmethod
public method destroy takes nothing returns nothing
set name = ""
set count = 0
call this.deallocate()
endmethod
endstruct
struct Poll extends array
implement Alloc
LinkedList options
string name
Table tb
Option winner
public method verifyWinner takes nothing returns nothing
local integer totalVotes = 0
local integer max = 0
local integer i = 0
local integer array winners
local Link h = options.head
local Option o
loop
exitwhen h == 0
set o = h.data
set totalVotes = totalVotes + o.count
if o.count > max then
set max = o.count
endif
set h = h.next
endloop
if totalVotes != 0 then
set h = options.head
loop
exitwhen h == 0
set o = h.data
if o.count == max then
set winners[i] = o
set i = i + 1
endif
set h = h.next
endloop
if i > 1 then
set winner = winners[GetRandomInt(0,i - 1)]
else
set winner = winners[0]
endif
endif
endmethod
public method vote takes player p, string op returns nothing
local Link h = options.head
local integer id = GetPlayerId(p)
local Option o = tb.integer[id]
local integer sw = 0
if o != 0 then
if o.name != op then
set o.count = o.count - 1
set sw = 1
else
call Message.ShowToPlayer(p,"You already vote for "+HIGHLIGHT+op+"|r"+" mode",MESSAGE_STYLE_INFO)
return
endif
endif
loop
exitwhen h == 0
set o = h.data
if o.name == op then
set o.count = o.count + 1
set tb.integer[id] = o
exitwhen true
endif
set h = h.next
endloop
if h == 0 then
//no existe
else
if sw == 1 then
call Message.ShowToPlayer(p,"You has changed your vote for "+HIGHLIGHT+op+"|r"+" mode",MESSAGE_STYLE_INFO)
else
call Message.ShowToPlayer(p,"You has voted for "+HIGHLIGHT+op+"|r"+" mode",MESSAGE_STYLE_INFO)
endif
endif
endmethod
public method addOption takes string name returns nothing
call options.addLast(Option.create(name))
endmethod
public static method create takes string n returns thistype
local thistype this = thistype.allocate()
set options = LinkedList.create()
set name = n
set tb = Table.create()
set winner = 0
return this
endmethod
public method destroy takes nothing returns nothing
local Link h = options.head
local Option o
set name = ""
loop
exitwhen h == 0
set o = h.data
call o.destroy()
set h = h.next
endloop
call options.destroy()
call tb.flush()
call tb.destroy()
endmethod
endstruct
endlibrary
library PreloadGen uses TimerUtils
globals
constant integer PRELOAD_FIRST = 1
constant integer PRELOAD_SECOND = 2
constant integer PRELOAD_UNIT = 3
private unit PreloadDummy
endglobals
private function UnitPreload takes integer id returns nothing
call RemoveUnit(CreateUnit(Game.PLAYER_NEUTRAL_EXTRA,id,0,0,0))
endfunction
private function AbilityPreload takes integer id returns nothing
if UnitAddAbility(PreloadDummy, id) then
call UnitRemoveAbility(PreloadDummy,id)
endif
endfunction
private function CreatePreloader takes nothing returns nothing
set PreloadDummy = CreateUnit(Game.PLAYER_NEUTRAL_EXTRA,'u001', Game.HIDE_X, Game.HIDE_Y, 0.)
call UnitApplyTimedLife(PreloadDummy,'BTLF',Game.TIME_PRELOADING)
endfunction
struct PreloadGen extends array
private static integer array A
private static integer array B
private static integer array C
private static integer countF = 0
private static integer countS = 0
private static integer countU = 0
private static method CallbackF takes nothing returns nothing
if countF > 0 then
set countF = countF - 1
call AbilityPreload(A[countF])
else
call ReleaseTimer(GetExpiredTimer())
endif
endmethod
private static method CallbackS takes nothing returns nothing
if countS > 0 then
set countS = countS - 1
call AbilityPreload(B[countS])
else
call ReleaseTimer(GetExpiredTimer())
endif
endmethod
private static method CallbackU takes nothing returns nothing
if countU > 0 then
set countU = countU - 1
call UnitPreload(C[countU])
else
call ReleaseTimer(GetExpiredTimer())
endif
endmethod
public static method Start takes nothing returns nothing
call CreatePreloader()
call TimerStart(NewTimer(),0.05,true,function thistype.CallbackF)
call TimerStart(NewTimer(),0.05,true,function thistype.CallbackS)
call TimerStart(NewTimer(),0.05,true,function thistype.CallbackU)
endmethod
public static method Add takes integer id, integer t returns nothing
if t == PRELOAD_FIRST then
set A[countF] = id
set countF = countF + 1
elseif t == PRELOAD_SECOND then
set B[countS] = id
set countS = countS + 1
elseif t == PRELOAD_UNIT then
set C[countU] = id
set countU = countU + 1
endif
endmethod
endstruct
endlibrary
library IndexEvent uses MiscLibrary, GuardPath
private function onIndex takes nothing returns nothing
local Index index = INDEX_EVENT
call MakeFly(index.u)
call SetUnitGuardPath(index.u,0)
set InCombat_CombatTime[index] = 0
//call BJDebugMsg("indexado "+I2S(index)+"-"+GetUnitName(index.u))
if UnitAlive(index.u) and not IsUnitIllusion(index.u) and (IsUnitType(index.u,UNIT_TYPE_HERO) or GetUnitAbilityLevel(index.u,Game.FLAG_HERO_CREEP) != 0) then
call HeroRegenPeriod.AddUnit(index)
endif
if GetUnitAbilityLevel(index.u,'AInv') != 0 then
call SetUnitData(index.u,"UnitItems",LinkedList.create())
endif
call UnitAddAbility(index.u,Game.FLAG_DISABLED)
call UnitMakeAbilityPermanent(index.u,true,Game.FLAG_DISABLED)
set UB[index] = LinkedList.create()
endfunction
private function onDeIndex takes nothing returns nothing
local Index index = INDEX_EVENT
//call BJDebugMsg("deindexado "+I2S(index)+"-"+GetUnitName(index.u))
call Status.RemoveStrong(STATUS_FEAR,index.u)
call UnitRemoveAllBuffs(index.u)
call UB[index].destroy()
call flushUnitData(index.u)
call flushDummyData(index.u)
call BonusStruct.ResetAll(index.u,index)
endfunction
public function Setup takes nothing returns nothing
call RegisterOnIndexEvent(function onIndex)
call RegisterOnDeIndexEvent(function onDeIndex)
endfunction
endlibrary
library UnitIndex uses UnitData
globals
boolean ENABLE_INDEXER = true
Index INDEX_EVENT
Event ON_INDEX
Event ON_DEINDEX
endglobals
function RegisterOnIndexEvent takes code c returns nothing
call ON_INDEX.register(Filter(c))
endfunction
function RegisterOnDeIndexEvent takes code c returns nothing
call ON_DEINDEX.register(Filter(c))
endfunction
struct Index extends array
implement Alloc
unit u
boolean lock
integer listIndex
static LinkedList All
public static method create takes unit x returns thistype
local thistype this = thistype.allocate()
set u = x
set lock = false
call SetUnitUserData(u,this)
set listIndex = All.add(this)
set INDEX_EVENT = this
call ON_INDEX.fire()
return this
endmethod
public method destroy takes nothing returns nothing
set INDEX_EVENT = this
call ON_DEINDEX.fire()
call All.remove(listIndex)
set listIndex = 0
call SetUnitUserData(u,0)
set u = null
call this.deallocate()
endmethod
endstruct
function GetUnitIndexObj takes unit u returns Index
local integer id = GetUnitUserData(u)
if id != 0 then
return Index[id]
endif
return 0
endfunction
function GetUnitByIndex takes integer index returns unit
if index <= 0 then
return null
endif
return Index[index].u
endfunction
function DestroyUnitIndex takes unit u returns nothing
local integer id = GetUnitUserData(u)
if id != 0 then
call Index[id].destroy()
endif
endfunction
function LockIndex takes unit u, boolean flag returns nothing
local integer id = GetUnitUserData(u)
if id != 0 then
set Index[GetUnitUserData(u)].lock = flag
endif
endfunction
private function IsValidToIndex takes unit u returns boolean
return not IsUnitType(u,UNIT_TYPE_UNDEAD) and GetUnitUserData(u) == 0 and ENABLE_INDEXER
endfunction
private function OnEnterMap takes nothing returns nothing
local unit u = GetEnteringUnit()
if IsValidToIndex(u) then
call Index.create(u)
endif
set u = null
endfunction
private function FilterIni takes nothing returns boolean
local unit u = GetFilterUnit()
if IsValidToIndex(u) then
call Index.create(u)
endif
set u = null
return false
endfunction
private function onDeath takes nothing returns nothing
local unit u = GetTriggerUnit()
local Index i
if IsUnitType(u,UNIT_TYPE_SUMMONED) or IsUnitIllusion(u) then
set i = GetUnitIndexObj(u)
if i != 0 and not i.lock then
call i.destroy()
endif
endif
set u = null
endfunction
public function Setup takes nothing returns nothing
local integer i = 27
local boolexpr b = Filter(function FilterIni)
local region re = CreateRegion()
local rect r = GetWorldBounds()
local trigger t = CreateTrigger()
set Index.All = LinkedList.create()
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function onDeath)
call RegionAddRect(re, r)
call TriggerRegisterEnterRegion(t, re, b)
call TriggerAddAction(t, function OnEnterMap)
set bj_lastCreatedGroup = CreateGroup()
loop
set i = i - 1
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, Player(i), b)
call GroupClear(bj_lastCreatedGroup)
exitwhen i == 0
endloop
call RemoveRect(r)
call DestroyGroup(bj_lastCreatedGroup)
set re = null
set r = null
set t = null
set b = null
endfunction
endlibrary
library AoEMeter uses MiscLibrary
globals
private constant string SFX = "war3mapImported\\RangeCircleZ.mdl"
endglobals
struct AoEPeriodic extends array
static timer T = CreateTimer()
public static method Periodic takes nothing returns nothing
local AoE a
local Link h = AoE.list.head
local Link n
local real x
local real y
loop
exitwhen h == 0
set a = h.data
set n = h.next
if a.attach != null then
set x = GetUnitX(a.attach)
set y = GetUnitY(a.attach)
call BlzSetSpecialEffectX(a.sfx,x)
call BlzSetSpecialEffectY(a.sfx,y)
call BlzSetSpecialEffectHeight(a.sfx,GetLocZ(x,y) + 25.00)
endif
if a.expire then
set a.time = a.time - 0.03125
if a.time <= 0 then
call a.destroy()
endif
endif
set h = n
endloop
if AoE.list.size == 0 then
call PauseTimer(T)
endif
endmethod
public static method Start takes nothing returns nothing
call TimerStart(T,0.03125,true,function thistype.Periodic)
endmethod
endstruct
struct AoE extends array
implement Alloc
unit attach
real x
real y
real size
effect sfx
real time
boolean expire
integer index
static LinkedList list
public method setSize takes real s returns nothing
set size = s / 2
if s != 0 then
call BlzSetSpecialEffectScale(sfx,size/32*1.03)
endif
endmethod
public method setTime takes real t returns nothing
if t == 0 then
set expire = false
set time = 0
else
set expire = true
set time = t
endif
endmethod
public method move takes real x, real y returns nothing
set this.x = x
set this.y = y
call BlzSetSpecialEffectX(sfx,x)
call BlzSetSpecialEffectY(sfx,y)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 25.0)
endmethod
public static method create takes real xc, real yc, unit u, real s returns thistype
local thistype this = thistype.allocate()
set attach = u
set x = xc
set y = yc
set size = s / 2
if s != 0 then
if u != null then
set sfx = AddSpecialEffect(SFX,GetUnitX(u),GetUnitY(u))
else
set sfx = AddSpecialEffect(SFX,x,y)
endif
call BlzSetSpecialEffectScale(sfx,size/32*1.03)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 25.0)
call BlzSetSpecialEffectAlpha(sfx,0)
endif
if Players[GetPlayerId(Game.LocalPlayer)].aoeShow or IsPlayerObserver(Game.LocalPlayer) then
call BlzSetSpecialEffectAlpha(sfx,255)
endif
set index = list.add(this)
if list.size == 1 then
call AoEPeriodic.Start()
endif
return this
endmethod
public method destroy takes nothing returns nothing
call list.remove(index)
set index = 0
set attach = null
call DestroyEffect(sfx)
set sfx = null
set time = 0
set expire = false
call this.deallocate()
endmethod
public static method onInit takes nothing returns nothing
set list = LinkedList.create()
endmethod
endstruct
endlibrary
scope AbilityDescription
globals
private constant string HIGHLIGHT = "|c0087cefa"
endglobals
struct AbilityTag extends array
implement Alloc
string name
Table values
real add
integer stype
boolean single
public method setValue takes integer lvl, string v returns nothing
set values.string[lvl] = v
endmethod
public static method create takes string n, integer st returns thistype
local thistype this = thistype.allocate()
set name = n
set values = Table.create()
set stype = st
set single = false
return this
endmethod
endstruct
struct DescriptionData extends array
implement Alloc
string description
LinkedList tags
public method addTag takes string name, integer st returns AbilityTag
local AbilityTag t = AbilityTag.create(name,st)
call tags.addLast(t)
return t
endmethod
public static method create takes string d returns thistype
local thistype this = thistype.allocate()
set tags = LinkedList.create()
set description = d
return this
endmethod
endstruct
struct AbilityDesc extends array
implement Alloc
delegate DescriptionData data
Ability abi
public method build takes nothing returns nothing
local string d = description + "|n"
local Link h = tags.head
local AbilityTag = t
loop
exitwhen h == 0
set t = h.data
if t.single then
set d = d + "|n" + HIGHLIGHT + t.name + ":|r " + t.values.string[1]
else
set d = d + "|n" + HIGHLIGHT + t.name + ":|r " + t.values.string[abi.level]
endif
set h = h.next
endloop
call BlzSetAbilityExtendedTooltip(abi.objectID,d,abi.level - 1)
endmethod
public static method create takes Ability a, DescriptionData d returns thistype
local thistype this = thistype.allocate()
set abi = a
set data = d
return this
endmethod
endstruct
endscope
library AbilityLibrary uses RegisterPlayerUnitEvent, MiscLibrary, LinkedList
globals
Event EVENT_UNIT_SPELL_CD_END
private Ability TriggerAbility
constant integer ACTIVATION_TYPE_TARGET = 0
constant integer ACTIVATION_TYPE_INSTANT = 1
constant integer ACTIVATION_TYPE_POINT = 2
constant integer ACTIVATION_TYPE_NONE = 3
private constant string STR_ABILITY_NAME_COLOR = "|cffc0c0c0"
private constant string STR_ABILITY_SPECIAL_COLOR = "|cffffcc00"
endglobals
function GetEventAbilityCD takes nothing returns Ability
return TriggerAbility
endfunction
struct AbilityData extends array
integer objectID
boolean UseAuxDummy
boolean AuxDummyAttacker
boolean isCharged
string hotkey
integer activationType
DescriptionData desc
static integer ABILITY_COUNT = 0
public static method GetDataByID takes integer id returns AbilityData
local integer i = 1
loop
exitwhen i > ABILITY_COUNT
if thistype[i].objectID == id then
return thistype[i]
endif
set i = i + 1
endloop
return 0
endmethod
public static method create takes nothing returns thistype
set ABILITY_COUNT = ABILITY_COUNT + 1
return thistype(ABILITY_COUNT)
endmethod
endstruct
struct Ability extends array
implement Alloc
delegate AbilityData data
ability abilityObj
integer maxCharges
real castRangeBonus
integer manaCostBonus
integer manaCostPercent
boolean disabledManaCost
integer calcManaCost
real aoeBonus
unit owner
integer level
real cdTime
integer currentCharges
real originalCooldown
real originalCastRange
integer originalManaCost
real originalAoE
real finalCooldown
real cooldown
real flatCooldown
real percentCooldown
real tempFlatCooldown
real tempPercentCooldown
unit auxDummy
integer cdCountIndex
boolean nextReset
AbilityNumber abilityNumber
AbilityDesc adesc
Upgrade upID
static HashTable HT
static timer TIMER
static LinkedList ONCD
public static method HeroAbilitiesAddManaCostPercent takes unit u, integer mcp returns nothing
local Hero h = GetUnitData(u,"HeroIndex")
local integer i = 1
local Ability a
if h != 0 then
loop
set a = h.Abilities.integer[i]
if a != 0 then
call a.addManaCost(0,mcp)
endif
set i = i + 1
exitwhen a == 0
endloop
endif
endmethod
private static method periodic takes nothing returns nothing
local Link node = ONCD.head
local Link temp
local thistype a
local integer sw
loop
exitwhen node == 0
set sw = 0
set a = node.data
set temp = node.next
set a.cdTime = a.cdTime - 0.03125
if a.cdTime <= 0 then
if a.isCharged then
set a.currentCharges = a.currentCharges + 1
if a.currentCharges < a.maxCharges then
set a.cdTime = a.finalCooldown
else
set a.cdTime = 0
set sw = 1
endif
call BlzSetUnitAbilityCooldown(a.owner,a.objectID,a.level-1,0)
call a.abilityNumber.setValue(a.currentCharges)
else
set sw = 1
endif
endif
if sw == 1 then
call a.updateTooltip(true)
set TriggerAbility = a
call EVENT_UNIT_SPELL_CD_END.fire()
call ONCD.remove(a.cdCountIndex)
set a.cdCountIndex = 0
endif
set node = temp
endloop
if ONCD.size == 0 then
call PauseTimer(TIMER)
endif
endmethod
public method forceCooldown takes nothing returns nothing
call BlzStartUnitAbilityCooldown(owner,objectID,BlzGetUnitAbilityCooldown(owner,objectID,level - 1))
call CooldownProcess.evaluate(owner,objectID)
endmethod
public method addCooldownRemaining takes real cd returns nothing
if isOnCooldown() and not isCharged then
set cdTime = cdTime + cd
if cdTime <= 0 then
set cdTime = 0
call BlzEndUnitAbilityCooldown(owner,objectID)
call updateTooltip(true)
set TriggerAbility = this
call EVENT_UNIT_SPELL_CD_END.fire()
call ONCD.remove(cdCountIndex)
set cdCountIndex = 0
else
call BlzStartUnitAbilityCooldown(owner,objectID,cdTime)
endif
endif
endmethod
public method disableManaCost takes boolean flag returns nothing
set disabledManaCost = flag
if flag then
call BlzSetUnitAbilityManaCost(owner,objectID,level - 1,0)
else
call this.addManaCost(0,0)
endif
endmethod
public method addCastRange takes real cr returns nothing
set castRangeBonus = castRangeBonus + cr
call BlzSetAbilityRealLevelField(BlzGetUnitAbility(owner,objectID),ABILITY_RLF_CAST_RANGE,level - 1,originalCastRange + castRangeBonus)
endmethod
public method addManaCost takes integer mc, integer mcp returns nothing
local integer mc2
if disabledManaCost then
call BlzSetUnitAbilityManaCost(owner,objectID,level - 1,0)
return
endif
set manaCostPercent = manaCostPercent + mcp
set mc2 = R2I(manaCostPercent * originalManaCost / 100)
set manaCostBonus = manaCostBonus + mc
set calcManaCost = originalManaCost + manaCostBonus + mc2
call BlzSetUnitAbilityManaCost(owner,objectID,level - 1,calcManaCost)
endmethod
public method addAreaOfEffect takes real aoe returns nothing
set aoeBonus = aoeBonus + aoe
call BlzSetAbilityRealLevelField(BlzGetUnitAbility(owner,objectID),ABILITY_RLF_AREA_OF_EFFECT,level - 1,originalAoE + aoeBonus)
endmethod
public method updateTooltip takes boolean calc returns nothing
local real c
local string s = ""
local string up = ""
local integer lvl = GetUnitAbilityLevel(owner,objectID)
if lvl == 0 then
return
endif
if hotkey != "Passive" then
if calc then
call calculateCooldown()
if isCharged then
call BlzSetUnitAbilityCooldown(owner,objectID,level-1,0)
else
if objectID == 'A0BV' or objectID == 'A0BW' or objectID == 'A0BU' then
call BlzSetUnitAbilityCooldown(owner,objectID,0,finalCooldown)
else
call BlzSetUnitAbilityCooldown(owner,objectID,level-1,finalCooldown)
endif
endif
endif
set c = finalCooldown
if c < 0 then
set c = 0.00
endif
set s = STR_ABILITY_NAME_COLOR+GetObjectName(objectID)+"|r"+STR_ABILITY_SPECIAL_COLOR+" [|r"+"Lvl "+I2S(level)+STR_ABILITY_SPECIAL_COLOR+"] CD: |r"+R2SW(c,0,2)
call BlzSetAbilityTooltip(objectID,s,level-1)
else
set level = GetUnitAbilityLevel(owner,objectID)
set s = STR_ABILITY_NAME_COLOR+GetObjectName(objectID)+"|r"+STR_ABILITY_SPECIAL_COLOR+" [|r"+"Lvl "+I2S(level)+STR_ABILITY_SPECIAL_COLOR+"]"+"("+hotkey+")|r"
call BlzSetAbilityTooltip(objectID,s,level-1)
endif
endmethod
public method isOnCooldown takes nothing returns boolean
if isCharged then
return currentCharges == 0
endif
return cdCountIndex != 0
endmethod
public static method AddCooldownTimer takes thistype a, real r returns nothing
if a.cdCountIndex == 0 then
set a.cdCountIndex = ONCD.add(a)
set a.cdTime = r
endif
if ONCD.size == 1 then
call TimerStart(TIMER,0.03125,true,function thistype.periodic)
endif
endmethod
public method calculateCooldown takes nothing returns nothing
local integer lvl = GetUnitAbilityLevel(owner,objectID)
local real flat
local real percent
local real unitReduction
if lvl != level then
set originalCooldown = BlzGetUnitAbilityCooldown(owner,objectID,lvl - 1)
set originalCastRange = BlzGetAbilityRealLevelField(BlzGetUnitAbility(owner,objectID),ABILITY_RLF_CAST_RANGE,lvl - 1)
set originalManaCost = BlzGetUnitAbilityManaCost(owner,objectID,lvl - 1)
set calcManaCost = originalManaCost
set originalAoE = BlzGetAbilityRealLevelField(BlzGetUnitAbility(owner,objectID),ABILITY_RLF_AREA_OF_EFFECT,lvl - 1)
set level = lvl
call addCastRange(0)
call addManaCost(0,0)
call addAreaOfEffect(0)
endif
if isCharged then
set finalCooldown = originalCooldown
else
set unitReduction = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_CD_REDUCTION,owner)
set flat = flatCooldown + tempFlatCooldown
set percent = originalCooldown * (percentCooldown + tempPercentCooldown + unitReduction)
set cooldown = flat + percent
set finalCooldown = originalCooldown + cooldown
endif
endmethod
public method addTempFlatCooldown takes real cd returns nothing
set tempFlatCooldown = tempFlatCooldown + cd
call updateTooltip(true)
endmethod
public method addTempPercentCooldown takes real cd returns nothing
set tempPercentCooldown = tempPercentCooldown + cd
call updateTooltip(true)
endmethod
public method addFlatCooldown takes real cd returns nothing
set flatCooldown = flatCooldown + cd
call updateTooltip(true)
endmethod
public method addPercentCooldown takes real pcd returns nothing
set percentCooldown = percentCooldown + pcd
call updateTooltip(true)
endmethod
public method addCharges takes integer c returns nothing
set currentCharges = currentCharges + c
if currentCharges > maxCharges then
set currentCharges = maxCharges
endif
call BlzEndUnitAbilityCooldown(owner,objectID)
call abilityNumber.setValue(currentCharges)
endmethod
public method addMaxCharges takes integer mc returns nothing
set maxCharges = maxCharges + mc
call addCharges(mc)
endmethod
public method resetCooldown takes nothing returns nothing
if not isCharged then
if cdCountIndex != 0 then
call updateTooltip(true)
set TriggerAbility = this
call EVENT_UNIT_SPELL_CD_END.fire()
call ONCD.remove(cdCountIndex)
set cdCountIndex = 0
set cdTime = 0
if ONCD.size == 0 then
call PauseTimer(TIMER)
endif
call BlzEndUnitAbilityCooldown(owner,objectID)
//call UnitResetAbilityCooldown(owner,objectID)
endif
else
if cdCountIndex != 0 then
set currentCharges = maxCharges
call updateTooltip(true)
set TriggerAbility = this
call EVENT_UNIT_SPELL_CD_END.fire()
call ONCD.remove(cdCountIndex)
set cdCountIndex = 0
set cdTime = 0
if ONCD.size == 0 then
call PauseTimer(TIMER)
endif
call BlzSetUnitAbilityCooldown(owner,objectID,level-1,0)
call BlzEndUnitAbilityCooldown(owner,objectID)
call abilityNumber.setValue(currentCharges)
endif
endif
endmethod
public static method create takes AbilityData d, unit u returns thistype
local thistype this = thistype.allocate()
local framehandle fh
set data = d
set owner = u
set flatCooldown = 0
set percentCooldown = 0
set maxCharges = 0
set currentCharges = 0
set cooldown = 0
set tempFlatCooldown = 0
set tempPercentCooldown = 0
set cdCountIndex = 0
set castRangeBonus = 0
set manaCostBonus = 0
set manaCostPercent = 0
set aoeBonus = 0
set calcManaCost = 0
set level = 0
set disabledManaCost = false
if d.UseAuxDummy then
if AuxDummyAttacker then
set auxDummy = CreateUnit(GetOwningPlayer(u),'u000',GetUnitX(u),GetUnitY(u),0)
else
set auxDummy = CreateUnit(GetOwningPlayer(u),'u001',GetUnitX(u),GetUnitY(u),0)
endif
endif
if isCharged then
set abilityNumber = AbilityNumber.create(objectID,u)
endif
set adesc = 0
set HT[GetUnitUserData(u)][d.objectID] = this
set fh = null
return this
endmethod
public static method GetUnitAbilityByID takes integer id, unit u returns thistype
return HT[GetUnitUserData(u)][id]
endmethod
endstruct
function CooldownProcess takes unit u, integer id returns nothing
local Ability a = Ability.GetUnitAbilityByID(id,u)
if a != 0 then
if a.isCharged then
set a.currentCharges = a.currentCharges - 1
call a.abilityNumber.setValue(a.currentCharges)
//call BJDebugMsg(I2S(a.currentCharges))
call Ability.AddCooldownTimer(a,a.finalCooldown)
if a.currentCharges == 0 then
if a.cdCountIndex != 0 then
call BlzSetUnitAbilityCooldown(a.owner,a.objectID,a.level-1,a.cdTime)
else
call BlzSetUnitAbilityCooldown(a.owner,a.objectID,a.level-1,a.finalCooldown)
endif
else
endif
else
if not a.nextReset then
call a.calculateCooldown()
set a.tempPercentCooldown = 0
set a.tempFlatCooldown = 0
call BlzSetUnitAbilityCooldown(a.owner,a.objectID,a.level-1,a.finalCooldown)
call Ability.AddCooldownTimer(a,a.finalCooldown)
call a.updateTooltip(false)
else
set a.nextReset = false
//call UnitResetAbilityCooldown(u,id)
call BlzEndUnitAbilityCooldown(u,id)
endif
endif
endif
endfunction
public function Setup takes nothing returns nothing
set Ability.HT = HashTable.create()
set Ability.TIMER = CreateTimer()
set Ability.ONCD = LinkedList.create()
set EVENT_UNIT_SPELL_CD_END = Event.create()
endfunction
endlibrary
library HeroLibrary initializer init uses UnitStats, TeamLib, GameConstants, UpgradeSkill, AbilityLibrary, HeroRevive, LinkedList, UnitData
globals
private trigger ON_LEVEL_TRIGGER
boolean INIT_AI
Hero HERO_AI
endglobals
/*function CreateHeroForPlaye takes player p,HeroData d returns nothing
local integer pid = GetPlayerId(p)
local unit u = CreateUnit(p,d.TypeID,GetPlayerStartLocationX(p),GetPlayerStartLocationY(p),0)
local integer id = GetUnitUserData(u)
local string n = ""
call UnitAddAbility(u,'A02Y')
call UnitMakeAbilityPermanent(u,true,'A02Y')
set Index[id].lock = true
set Players[pid].hero = Hero.create(u,d)
call SelectUnitForPlayer(u,p,true)
call RegisterHeroRespawn(u)
if Team[1].isPlayerInTeam(p) then
call SetCameraPositionForPlayer(p,Team[1].startX,Team[1].startY)
call Message.ShowToForce(Team[2].forceP,GetPlayerName(p) + " has choosen "+GetUnitName(u),MESSAGE_STYLE_INFO)
elseif Team[2].isPlayerInTeam(p) then
call SetCameraPositionForPlayer(p,Team[2].startX,Team[2].startY)
call Message.ShowToForce(Team[1].forceP,GetPlayerName(p) + " has choosen "+GetUnitName(u),MESSAGE_STYLE_INFO)
endif
if p != Game.PLAYER_WARCHIEF_HORDE and p != Game.PLAYER_WARCHIEF_ALLIANCE then
if GetPlayerController(p) == MAP_CONTROL_COMPUTER then
set n = Players[pid].ai+I2S(pid-1)+" ("+d.Name+")"
call SetPlayerName(p,n)
set Players[pid].name = n
call MultiboardUpdatePlayerName(p,n)
call Players[pid].hero.heroAI.itemBuild.purchaseStartingItems()
else
set n = GetPlayerName(p)+" ("+d.Name+")"
call SetPlayerName(p,n)
endif
endif
set u = null
endfunction*/
function GetHeroAbilityById takes unit u, integer id returns Ability
local Hero h = GetUnitData(u,"HeroIndex")
if h != 0 then
return h.GetAbiltyByID(id)
endif
return 0
endfunction
function GetHeroPrimaryAttribute takes unit u, boolean all returns integer
local Hero h = GetUnitData(u,"HeroIndex")
if h != 0 then
if h.PrimaryAttribute == 1 then
return GetHeroAgi(h.hero,all)
elseif h.PrimaryAttribute == 2 then
return GetHeroInt(h.hero,all)
elseif h.PrimaryAttribute == 3 then
return GetHeroStr(h.hero,all)
endif
endif
return 0
endfunction
function GetHeroMainAttribute takes unit u returns integer
local Hero h = GetUnitData(u,"HeroIndex")
if h != 0 then
return h.PrimaryAttribute
endif
return 0
endfunction
struct HeroData extends array
static integer COUNT = 0
integer TypeID
string IconID
string WinAni
string Name
real Evasion
real Block
real Resistance
real LifeRegen
real ManaRegen
integer Armor
integer AttackRange
integer PrimaryAttribute
UpgradeData HeroUp1
UpgradeData HeroUp2
UpgradeData HeroUp3
UpgradeData HeroUp4
integer HeroAbility1
integer HeroAbility2
integer HeroAbility3
integer HeroAbility4
integer HeroAbility5
integer HeroAbility6
integer ChooseIconID
integer ChooseDummy
integer HeroFaction
integer InfoID
//HeroQualityMeter
integer spellDamageLevel
integer attackDamageLevel
integer healingLevel
integer survivavilityLevel
integer movementLevel
integer crowdControlLevel
boolean IsSelected
Link randomIDH
Link randomIDA
static LinkedList RandomListHorde
static LinkedList RandomListAlliance
public static method GetDataByHeroID takes integer id returns thistype
local integer i = 0
loop
set i = i + 1
if thistype[i].TypeID == id then
return thistype[i]
endif
exitwhen i == COUNT
endloop
return 0
endmethod
public static method GetDataByChooseIconID takes integer id returns thistype
local integer i = 0
loop
set i = i + 1
if thistype[i].ChooseIconID == id then
return thistype[i]
endif
exitwhen i == COUNT
endloop
return 0
endmethod
public static method RemoveRandomData takes thistype d returns nothing
if d.HeroFaction == Game.FACTION_ORC then
call RandomListHorde.remove(d.randomIDH)
elseif d.HeroFaction == Game.FACTION_HUMAN then
call RandomListAlliance.remove(d.randomIDA)
else
call RandomListHorde.remove(d.randomIDH)
call RandomListAlliance.remove(d.randomIDA)
endif
endmethod
public static method GetRandomData takes player p returns thistype
local Team t = GetPlayerTeamEx(p)
local thistype d
local integer r = 0
if t == 1 then
set r = GetRandomInt(1,RandomListHorde.size)
set d = RandomListHorde.getByIndex(r).data
else
set r = GetRandomInt(1,RandomListAlliance.size)
set d = RandomListAlliance.getByIndex(r).data
endif
return d
endmethod
public static method AddRandomData takes thistype d returns nothing
if d.HeroFaction == Game.FACTION_ORC then
set d.randomIDH = RandomListHorde.add(d)
elseif d.HeroFaction == Game.FACTION_HUMAN then
set d.randomIDA = RandomListAlliance.add(d)
else
set d.randomIDH = RandomListHorde.add(d)
set d.randomIDA = RandomListAlliance.add(d)
endif
endmethod
public static method create takes nothing returns thistype
set COUNT = COUNT + 1
return COUNT
endmethod
endstruct
struct Hero extends array
implement Alloc
delegate HeroData data
unit hero
integer masteryType
integer traitAbility
integer supUp
Upgrade up1
Upgrade up2
Upgrade up3
Upgrade up4
boolean supUpgrade
integer upgradePoints
integer upgradeLvl
HeroAtt heroAtt
Perks perks
Table Abilities
AICore heroAI
public method updateAbilityTooltip takes integer i returns nothing
local Ability a = Abilities.integer[i]
if a != 0 then
call a.updateTooltip(true)
endif
endmethod
public method updateTooltips takes nothing returns nothing
local integer i = 1
local Ability a
loop
set a = Abilities.integer[i]
if a != 0 then
call a.updateTooltip(true)
endif
set i = i + 1
exitwhen a == 0
endloop
endmethod
public method GetUpgradeByID takes integer id returns Upgrade
if up1.UpId == id then
return up1
endif
if up2.UpId == id then
return up2
endif
if up3.UpId == id then
return up3
endif
if up4.UpId == id then
return up4
endif
return 0
endmethod
public method GetAbiltyByID takes integer id returns Ability
local integer i = 1
local Ability a
loop
set a = Abilities.integer[i]
if a != 0 then
if a.objectID == id then
return a
endif
else
exitwhen true
endif
set i = i + 1
endloop
return 0
endmethod
public method GetUpgradeLevel takes integer upkey returns integer
if upkey == 1 then
return up1.level
elseif upkey == 2 then
return up2.level
elseif upkey == 3 then
return up3.level
elseif upkey == 4 then
return up4.level
endif
return 0
endmethod
public method HeroAddAbility takes integer abilityid, integer pos returns nothing
local AbilityData d
local Ability a
if abilityid == 0 then
return
endif
set d = AbilityData.GetDataByID(abilityid)
if d != 0 then
set a = Ability.create(d,hero)
set Abilities.integer[pos] = a
if pos == 1 then
set a.upID = up1
elseif pos == 2 then
set a.upID = up2
elseif pos == 3 then
set a.upID = up3
elseif pos == 4 then
set a.upID = up4
endif
if abilityid == 'A011' then
call BlzUnitDisableAbility(hero,abilityid,true,false)
endif
else
set Abilities.integer[pos] = 0
endif
endmethod
public static method create takes unit hero,HeroData data returns thistype
local thistype this = thistype.allocate()
local integer id = GetUnitUserData(hero)
local player p = GetOwningPlayer(hero)
local integer pid = GetPlayerId(p)
set .hero = hero
set .data = data
set .heroAI = -1
call SetUnitData(hero,"HeroIndex",this)
set heroAtt = HeroAtt.create(this)
call Item_RegisterHeroOrder(hero)
set INIT_AI = GetPlayerController(p) == MAP_CONTROL_COMPUTER
if not INIT_AI then
set perks = Perks.create(hero)
call UnitMakeAbilityPermanent(hero,true,UPGRADE1_ID)
call UnitMakeAbilityPermanent(hero,true,UPGRADE2_ID)
call UnitMakeAbilityPermanent(hero,true,UPGRADE3_ID)
call UnitMakeAbilityPermanent(hero,true,data.HeroUp4.UpId)
call UnitMakeAbilityPermanent(hero,true,'A01M')
call UnitMakeAbilityPermanent(hero,true,'A04C')
call UnitMakeAbilityPermanent(hero,true,'A01N')
call UnitMakeAbilityPermanent(hero,true,'A07D')
call UnitMakeAbilityPermanent(hero,true,'A08A')
call UnitMakeAbilityPermanent(hero,true,'A02X')
call UnitMakeAbilityPermanent(hero,true,'A08C')
else
//call RemoveGuardPosition(hero)
endif
if Game.Mode == GAME_MODE_NORMAL then
call AncientObelisk.RegisterHero(hero)
endif
call BlzUnitDisableAbility(hero,data.HeroUp4.UpId,true,false)
call TriggerRegisterUnitEvent(ON_LEVEL_TRIGGER,hero,EVENT_UNIT_HERO_LEVEL)
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,hero,data.Block,0)
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,hero,data.Evasion,0)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,hero,data.Resistance,0)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,hero,data.LifeRegen,0)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,hero,data.ManaRegen,0)
set HERO_AI = this
set Abilities = Table.create()
call LoadFunction.RunFunction(data.TypeID)
call HeroAddAbility(HeroAbility1,1)
call HeroAddAbility(HeroAbility2,2)
call HeroAddAbility(HeroAbility3,3)
call HeroAddAbility(HeroAbility4,4)
call HeroAddAbility(HeroAbility5,5)
call HeroAddAbility(HeroAbility6,6)
if pid != 0 and pid != 1 then
set up1 = Upgrade.create(data.HeroUp1,this)
set up2 = Upgrade.create(data.HeroUp2,this)
set up3 = Upgrade.create(data.HeroUp3,this)
set up4 = Upgrade.create(data.HeroUp4,this)
else
set up1 = 0
set up2 = 0
set up3 = 0
set up4 = 0
endif
set upgradePoints = 0
set upgradeLvl = 3
call MultiboardUpdateHeroIcon(p,data.IconID)
if heroAI != -1 then
call heroAI.abilityBuild.learnNextSkill()
endif
if p != Game.PLAYER_WARCHIEF_HORDE and p != Game.PLAYER_WARCHIEF_ALLIANCE then
if Game.Mode == GAME_MODE_NORMAL then
call AIRegion.RegisterHero(hero)
call AncientObelisk.RegisterHero(hero)
endif
if Game.Mode == GAME_MODE_LMS or Game.Mode == GAME_MODE_OD then
call SetHeroLevel(hero,2,true)
call SetHeroLevel(hero,3,true)
endif
endif
call BlzFrameSetTexture(HeroesIcon[pid - 2],BlzGetAbilityIcon(GetUnitTypeId(hero)),0,true)
call BlzFrameSetAlpha(HeroesIcon[pid - 2],255)
call BlzFrameSetVisible(HeroesLevelIconText[pid - 2],true)
call BlzFrameSetText(HeroesLevelIconText[pid - 2],I2S(GetHeroLevel(hero)))
set p = null
return this
endmethod
public static method onLevel takes nothing returns nothing
local Hero h = GetUnitData(GetTriggerUnit(),"HeroIndex")
local integer lvl = GetHeroLevel(h.hero)
local player p = GetTriggerPlayer()
if h != 0 then
call MultiboardUpdateLevel(p,GetHeroLevel(GetTriggerUnit()))
call h.heroAtt.recalculate()
if lvl == h.upgradeLvl then
set h.upgradeLvl = h.upgradeLvl + 2
call Upgrade.AddUpgradePoints(h)
if h.heroAI != -1 then
call h.heroAI.upgradeBuild.learnUpgrade()
endif
endif
if h.heroAI != -1 then
call h.heroAI.abilityBuild.learnNextSkill()
if lvl == 14 then
call SetPlayerTechResearched(GetOwningPlayer(h.hero),'R005',1)
call Upgrade.ActiveFourthUp(h)
call h.heroAI.upgradeBuild.selectMastery()
endif
else
if lvl == 6 or lvl == 11 or lvl == 16 or lvl == 19 then
call UnitModifySkillPoints(h.hero, -1)
call h.perks.addPerkBook(lvl)
call BlzUnitDisableAbility(h.hero,'AHer',true,true)
endif
if lvl == 14 then
call SetPlayerTechResearched(GetOwningPlayer(h.hero),'R005',1)
call Upgrade.ActiveFourthUp(h)
endif
endif
endif
call BlzFrameSetText(HeroesLevelIconText[GetPlayerId(p) - 2],I2S(GetHeroLevel(h.hero)))
set p = null
endmethod
endstruct
private function init takes nothing returns nothing
set ON_LEVEL_TRIGGER = CreateTrigger()
call TriggerAddCondition(ON_LEVEL_TRIGGER,Condition(function Hero.onLevel))
set HeroData.RandomListHorde = LinkedList.create()
set HeroData.RandomListAlliance = LinkedList.create()
call PreloadGen.Add('A04C',PRELOAD_SECOND)
call PreloadGen.Add('A01M',PRELOAD_SECOND)
call PreloadGen.Add('A01N',PRELOAD_SECOND)
endfunction
endlibrary
library Multiboard uses Table
struct Element
string name
string icon
string text
real width
integer row
integer col
public method destroy takes nothing returns nothing
call this.deallocate()
endmethod
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set name = ""
set icon = ""
set text = ""
set width = 0.0001
set row = 0
set col = 0
return this
endmethod
endstruct
struct Multiboard
multiboard mul
string tittle
integer rows
integer cols
HashTable T
public method showMultiboard takes boolean b returns nothing
call MultiboardDisplay(mul,b)
endmethod
public method setTitle takes string t returns nothing
set tittle = t
endmethod
public method setRowsCount takes integer r returns nothing
call MultiboardSetRowCount(mul,r)
endmethod
public method getElementByName takes string name returns Element
local integer i = 0
local integer j = 0
local Element temp
local integer sw = 0
loop
set i = i + 1
loop
set j = j + 1
set temp = T[i][j]
if temp.name == name then
set sw = 1
endif
exitwhen j == cols or sw == 1
endloop
set j = 0
exitwhen i == rows or sw == 1
endloop
return temp
endmethod
public method customizeElement takes integer row, integer col, string name, string icon, string text, real width returns nothing
local Element em = T[row][col]
if em != 0 then
set em.name = name
set em.icon = icon
set em.text = text
set em.width = width
endif
endmethod
public method updateElement takes integer row, integer col returns nothing
local Element e = T[row][col]
local multiboarditem it
if e != 0 then
set it = MultiboardGetItem(mul,row - 1,col - 1)
call MultiboardSetItemStyle(it,e.text != "",e.icon != "")
call MultiboardSetItemWidth(it,e.width)
call MultiboardSetItemValue(it,e.text)
call MultiboardSetItemIcon(it,e.icon)
call MultiboardReleaseItem(it)
set it = null
endif
endmethod
public method updateMultiboard takes nothing returns nothing
local integer i = 0
local integer j = 0
local Element e
local multiboarditem it
loop
set i = i + 1
loop
set j = j + 1
set e = T[i][j]
set it = MultiboardGetItem(mul,i - 1,j - 1)
call MultiboardSetItemStyle(it,e.text != "",e.icon != "")
call MultiboardSetItemWidth(it,e.width)
call MultiboardSetItemIcon(it,e.icon)
call MultiboardSetItemValue(it,e.text)
call MultiboardReleaseItem(it)
set e.row = i
set e.col = j
exitwhen j == cols
endloop
set j = 0
exitwhen i == rows
endloop
set it = null
endmethod
private method createElements takes nothing returns nothing
local integer i = 0
local integer j = 0
call MultiboardSetTitleText(mul,tittle)
call MultiboardSetItemsStyle(mul,true,false)
call MultiboardSetItemsWidth(mul,0.00)
loop
set i = i + 1
loop
set j = j + 1
set T[i][j] = Element.create()
exitwhen j == cols
endloop
set j = 0
exitwhen i == rows
endloop
endmethod
public static method create takes string t, integer r, integer c returns thistype
local thistype this = thistype.allocate()
set rows = r
set cols = c
set tittle = t
set mul = CreateMultiboard()
call MultiboardSetRowCount(mul,rows)
call MultiboardSetColumnCount(mul,cols)
call MultiboardDisplay(mul,false)
set T = HashTable.create()
call createElements()
return this
endmethod
public method destroy takes nothing returns nothing
local integer i = 0
local integer j = 0
local Element e
loop
set i = i + 1
loop
set j = j + 1
set e = T[i][j]
call e.destroy()
exitwhen j == cols
endloop
set j = 0
exitwhen i == rows
endloop
set rows = 0
set cols = 0
call T.destroy()
call DestroyMultiboard(mul)
set mul = null
endmethod
endstruct
endlibrary
library GameMultiboard uses Multiboard, PlayerLib
globals
Multiboard array TEAM_MULTIBOARD[3]
framehandle mult1 = null
framehandle mult2 = null
private constant string GOLD_COLOR = "|cffffd700"
private constant string HONOR_COLOR = "|cff9acd32"
private constant string TEAM_COLOR = "|cfffff8dc"
private constant string BASES_COLOR = "|cfff0e68c"
private constant string MINES_COLOR = "|cffffff00"
private constant string RESOURCES_COLOR = "|cffff6347"
private constant string INCOMING_COLOR = "|cff9acd32"
constant string HORDE_COLOR = "|cffdc143c"
constant string ALLIANCE_COLOR = "|cff0000cd"
private constant string PLAYER_COLOR = "|cfffff8dc"
constant string CLOCK_COLOR = "|cffababab"
constant string WHITE_COLOR = "|cfff0f0f0"
private constant string MULTIBOARD_TITTLE = "|cfff05b02Golden Lands|r"
endglobals
function GetPlayerKills takes player p returns integer
local Team t = GetPlayerTeamEx(p)
local Multiboard m = TEAM_MULTIBOARD[t]
local Element e = m.getElementByName("Kills"+I2S(GetPlayerId(p)))
return S2I(e.text)
endfunction
function MultiboardUpdateDeath takes player killed returns nothing
local Multiboard m
local Element e
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName("Deaths"+I2S(GetPlayerId(killed)))
if e != 0 then
set e.text = " "+I2S(S2I(e.text) + 1)
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName("Deaths"+I2S(GetPlayerId(killed)))
if e != 0 then
set e.text = " "+I2S(S2I(e.text) + 1)
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdateKill takes player killer returns nothing
local Multiboard m
local Element e
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName("Kills"+I2S(GetPlayerId(killer)))
if e != 0 then
set e.text = " "+I2S(S2I(e.text) + 1)
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName("Kills"+I2S(GetPlayerId(killer)))
if e != 0 then
set e.text = " "+I2S(S2I(e.text) + 1)
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdateLevel takes player levelp, integer level returns nothing
local Multiboard m
local Element e
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName("Level"+I2S(GetPlayerId(levelp)))
if e != 0 then
set e.text = I2S(level)
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName("Level"+I2S(GetPlayerId(levelp)))
if e != 0 then
set e.text = I2S(level)
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdateGold takes nothing returns nothing
local integer i = 2
local Multiboard m
local Element e
local Team t
local player pa
loop
set pa = Player(i)
set t = GetPlayerTeamEx(pa)
if t != 0 then
set m = TEAM_MULTIBOARD[t]
if Players[i].isPlaying then
set e = m.getElementByName("Gold"+I2S(i))
if e != 0 then
set e.text = GOLD_COLOR+I2S(GetPlayerState(pa,PLAYER_STATE_RESOURCE_GOLD))+"|r"
call m.updateElement(e.row,e.col)
endif
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
set pa = null
endfunction
function MultiboardUpdateTrait takes player p, string str returns nothing
local Multiboard m
local Element e
local Team t = GetPlayerTeamEx(p)
local integer i = GetPlayerId(p)
if t != 0 then
set m = TEAM_MULTIBOARD[t]
if Players[i].isPlaying then
set e = m.getElementByName("Trait"+I2S(i))
if e != 0 then
set e.icon = str
call m.updateElement(e.row,e.col)
endif
endif
endif
endfunction
function MultiboardUpdateHeroIcon takes player p, string ic returns nothing
local Multiboard m
local Element e
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName("Level"+I2S(GetPlayerId(p)))
if e != 0 then
set e.icon = ic
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName("Level"+I2S(GetPlayerId(p)))
if e != 0 then
set e.icon = ic
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdateRespawn takes player p, real r returns nothing
local Multiboard m
local Element e
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName("Respawn"+I2S(GetPlayerId(p)))
if e != 0 then
if r <= 0 then
set e.text = " "+I2S(R2I(r))
else
set e.text = " "+"|c00ff0000"+I2S(R2I(r))+"|r"
endif
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName("Respawn"+I2S(GetPlayerId(p)))
if e != 0 then
if r <= 0 then
set e.text = " "+I2S(R2I(r))
else
set e.text = " "+"|c00ff0000"+I2S(R2I(r))+"|r"
endif
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdatePlayerName takes player p, string n returns nothing
local Multiboard m
local Element e
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName("Player"+I2S(GetPlayerId(p)))
if e != 0 then
set e.text = ARGB.fromPlayer(p).str(n)
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName("Player"+I2S(GetPlayerId(p)))
if e != 0 then
set e.text = ARGB.fromPlayer(p).str(n)
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdateTeamBases takes Team t returns nothing
local Multiboard m
local Element e
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName(t.name+"Bases")
if e != 0 then
set e.text = " "+I2S(t.bases)
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName(t.name+"Bases")
if e != 0 then
set e.text = " "+I2S(t.bases)
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdateTeamMines takes Team t returns nothing
local Multiboard m
local Element e
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName(t.name+"Mines")
if e != 0 then
set e.text = " "+I2S(t.goldmines)
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName(t.name+"Mines")
if e != 0 then
set e.text = " "+I2S(t.goldmines)
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdateTeamResources takes Team t returns nothing
local Multiboard m
local Element e
if t == 0 then
return
endif
set m = TEAM_MULTIBOARD[1]
set e = m.getElementByName(t.name+"Resources")
if e != 0 then
set e.text = " "+I2S(t.resources)
call m.updateElement(e.row,e.col)
endif
set m = TEAM_MULTIBOARD[2]
set e = m.getElementByName(t.name+"Resources")
if e != 0 then
set e.text = " "+I2S(t.resources)
call m.updateElement(e.row,e.col)
endif
endfunction
function MultiboardUpdateTittle takes nothing returns nothing
local Multiboard m
local string t
local string kills
set kills = "Kills: "+HORDE_COLOR+I2S(Team[1].kills)+"|r/"+ALLIANCE_COLOR+I2S(Team[2].kills)+"|r "
set m = TEAM_MULTIBOARD[1]
set t = CLOCK_COLOR+"(|r"+WHITE_COLOR+I2S(GameLoop.Minutes)+":"+I2S(GameLoop.Seconds)+"|r"+CLOCK_COLOR+") |r"
set t = t + kills + MULTIBOARD_TITTLE
call MultiboardSetTitleText(m.mul,t)
set m = TEAM_MULTIBOARD[2]
set t = CLOCK_COLOR+"(|r"+WHITE_COLOR+I2S(GameLoop.Minutes)+":"+I2S(GameLoop.Seconds)+"|r"+CLOCK_COLOR+") |r"
set t = t + kills + MULTIBOARD_TITTLE
call MultiboardSetTitleText(m.mul,t)
endfunction
private function Config takes Multiboard m, Team team returns nothing
local integer i = 2
local player p
local integer j
local integer g
call m.customizeElement(1,1,"Teams","",TEAM_COLOR+"Teams",0.10)
call m.customizeElement(1,2,"Bases","",BASES_COLOR+"Towers",0.05)
call m.customizeElement(1,3,"Mines","",MINES_COLOR+"Mines",0.05)
call m.customizeElement(1,4,"Resources","",RESOURCES_COLOR+" Resources",0.10)
call m.customizeElement(2,1,"The Horde","",HORDE_COLOR+"The Orcs",0.10)
call m.customizeElement(2,2,"The HordeBases",""," 0",0.05)
call m.customizeElement(2,3,"The HordeMines",""," 0",0.05)
call m.customizeElement(2,4,"The HordeResources",""," 0",0.10)
call m.customizeElement(3,1,"The Alliance","",ALLIANCE_COLOR+"The Humans",0.10)
call m.customizeElement(3,2,"The AllianceBases",""," 0",0.05)
call m.customizeElement(3,3,"The AllianceMines",""," 0",0.05)
call m.customizeElement(3,4,"The AllianceResources",""," 0",0.10)
call m.customizeElement(4,1,"","","------------------------------------------------------------------------------------------------------------------------------",0.30)
call m.customizeElement(5,1,"Level","ReplaceableTextures\\CommandButtons\\BTNSkillz.tga",PLAYER_COLOR+"lvl",0.03)
call m.customizeElement(5,2,"Player","",PLAYER_COLOR+"Player",0.10)
call m.customizeElement(5,3,"Kills","ReplaceableTextures\\CommandButtons\\BTNSacrifice.blp","",0.03)
call m.customizeElement(5,4,"Deaths","ReplaceableTextures\\CommandButtons\\BTNOrbOfCorruption.blp","",0.03)
call m.customizeElement(5,5,"Respawn","ReplaceableTextures\\CommandButtons\\BTNWinged-Clock.blp","",0.03)
call m.customizeElement(5,6,"Gold","ReplaceableTextures\\CommandButtons\\BTNMGexchange.tga","",0.04)
call m.customizeElement(5,7,"Trait","ReplaceableTextures\\CommandButtons\\BTNSorceressAdept.blp","",0.04)
set j = 5
loop
set p = Player(i)
if Players[i].isPlaying then
set j = j + 1
call m.customizeElement(j,1,"Level"+I2S(i),"ReplaceableTextures\\WorldEditUI\\Editor-Random-Unit.blp","1",0.03)
call m.customizeElement(j,2,"Player"+I2S(i),"",ARGB.fromPlayer(p).str(GetPlayerName(p)),0.10)
call m.customizeElement(j,3,"Kills"+I2S(i),""," 0",0.03)
call m.customizeElement(j,4,"Deaths"+I2S(i),""," 0",0.03)
call m.customizeElement(j,5,"Respawn"+I2S(i),""," 0",0.03)
if team.isPlayerInTeam(p) then
set g = GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)
call m.customizeElement(j,6,"Gold"+I2S(i),"",GOLD_COLOR+I2S(g)+"|r",0.04)
call m.customizeElement(j,7,"Trait"+I2S(i),"ReplaceableTextures\\WorldEditUI\\Editor-Random-Unit.blp","",0.04)
else
call m.customizeElement(j,6,"Gold"+I2S(i),"","",0.04)
call m.customizeElement(j,7,"Trait"+I2S(i),"ReplaceableTextures\\WorldEditUI\\Editor-Random-Unit.blp","",0.04)
endif
endif
set i = i + 1
exitwhen i > 6
endloop
set j = j + 1
call m.customizeElement(j,1,"","","------------------------------------------------------------------------------------------------------------------------------",0.30)
set i = 7
loop
set p = Player(i)
if Players[i].isPlaying then
set j = j + 1
call m.customizeElement(j,1,"Level"+I2S(i),"ReplaceableTextures\\WorldEditUI\\Editor-Random-Unit.blp","1",0.03)
call m.customizeElement(j,2,"Player"+I2S(i),"",ARGB.fromPlayer(p).str(GetPlayerName(p)),0.10)
call m.customizeElement(j,3,"Kills"+I2S(i),""," 0",0.03)
call m.customizeElement(j,4,"Deaths"+I2S(i),""," 0",0.03)
call m.customizeElement(j,5,"Respawn"+I2S(i),""," 0",0.03)
if team.isPlayerInTeam(p) then
set g = GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)
call m.customizeElement(j,6,"Gold"+I2S(i),"",GOLD_COLOR+I2S(g)+"|r",0.04)
call m.customizeElement(j,7,"Trait"+I2S(i),"ReplaceableTextures\\WorldEditUI\\Editor-Random-Unit.blp","",0.04)
else
call m.customizeElement(j,6,"Gold"+I2S(i),"","",0.04)
call m.customizeElement(j,7,"Trait"+I2S(i),"ReplaceableTextures\\WorldEditUI\\Editor-Random-Unit.blp","",0.04)
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
set j = j + 1
call m.customizeElement(j,1,"","","------------------------------------------------------------------------------------------------------------------------------",0.30)
call m.setRowsCount(j)
set p = null
endfunction
public function ShowForPlayer takes player p, boolean flag returns nothing
local Team t = GetPlayerTeamEx(p)
if t != 0 then
if Game.LocalPlayer == p then
call TEAM_MULTIBOARD[t].showMultiboard(flag)
endif
endif
endfunction
public function Setup takes nothing returns nothing
set TEAM_MULTIBOARD[1] = Multiboard.create(MULTIBOARD_TITTLE,21,7)
set mult1 = BlzGetFrameByName("Multiboard",0)
call Config(TEAM_MULTIBOARD[1],1)
call TEAM_MULTIBOARD[1].updateMultiboard()
set TEAM_MULTIBOARD[2] = Multiboard.create(MULTIBOARD_TITTLE,21,7)
set mult2 = BlzGetFrameByName("Multiboard",0)
call Config(TEAM_MULTIBOARD[2],2)
call TEAM_MULTIBOARD[2].updateMultiboard()
endfunction
endlibrary
library EndMultiboard uses PlayerLib
globals
private constant string TITTLE_COLOR = "|c000061c1"
private constant string HIGH_COLOR = "|c00ff4040"
private Multiboard em
private integer PC
endglobals
private function ConfigMultiboard takes player p returns nothing
local string pid = I2S(GetPlayerId(p))
local Players ps = Players[GetPlayerId(p)]
local Hero h = GetPlayerHero(p)
local Team t = GetPlayerTeamEx(p)
local item it
local Item ite = 0
local string ip
local integer i = 0
local integer j = 0
call em.customizeElement(1,PC,"","",ARGB.fromPlayer(p).str(ps.name),0.07)
call em.customizeElement(2,PC,"IconHero"+pid,h.IconID,I2S(GetHeroLevel(h.hero)),0.07)
call em.customizeElement(3,PC,"",""," ",0.07)
set i = 0
loop
set it = UnitItemInSlot(h.hero,i)
if it != null then
set ite = GetItemUserData(it)
set ip = BlzGetItemIconPath(it)
else
set ite = 0
set ip = "UI\\Widgets\\Console\\Orc\\orc-inventory-slotfiller.blp"
endif
if ite != 0 then
if ite.itemType >= 2 then
call em.customizeElement(i+4,PC,"Item"+I2S(i)+pid,ip,I2S(ite.tier),0.07)
else
call em.customizeElement(i+4,PC,"Item"+I2S(i)+pid,ip,"",0.07)
endif
else
call em.customizeElement(i+4,PC,"Item"+I2S(i)+pid,ip,"",0.07)
endif
set i = i + 1
exitwhen i == bj_MAX_INVENTORY
endloop
call em.customizeElement(10,PC,"","","",0.07)
set i = ps.totalGold
set ip = ""
if i == MAX_GOLD and MAX_GOLD != 0 then
set ip = HIGH_COLOR + I2S(MAX_GOLD) + "|r"
else
set ip = I2S(i)
endif
call em.customizeElement(11,PC,"Gold Earned","",ip,0.07)
set i = ps.kills
set j = ps.deaths
set ip = ""
if i == MAX_KILLS and MAX_KILLS != 0 then
set ip = HIGH_COLOR + I2S(MAX_KILLS) + "|r"
else
set ip = I2S(i)
endif
if j == MAX_DEATHS and MAX_DEATHS != 0 then
set ip = ip + "/" + HIGH_COLOR + I2S(MAX_DEATHS) + "|r"
else
set ip = ip + "/" + I2S(j)
endif
call em.customizeElement(12,PC,"Kills/Deaths","",ip,0.07)
if ps.basesT == MAX_BASES_T and MAX_BASES_T != 0 then
call em.customizeElement(14,PC,"Towers","",HIGH_COLOR+I2S(MAX_BASES_T),0.07)
else
call em.customizeElement(14,PC,"Towers","",I2S(ps.basesT),0.07)
endif
if ps.minesT == MAX_MINES_T and MAX_MINES_T != 0 then
call em.customizeElement(15,PC,"Gold Mines","",HIGH_COLOR+I2S(MAX_MINES_T),0.07)
else
call em.customizeElement(15,PC,"Gold Mines","",I2S(ps.minesT),0.07)
endif
if ps.obeliskT == MAX_OBELISK_T and MAX_OBELISK_T != 0 then
call em.customizeElement(16,PC,"Obelisks","",HIGH_COLOR+I2S(MAX_OBELISK_T),0.07)
else
call em.customizeElement(16,PC,"Obelisks","",I2S(ps.obeliskT),0.07)
endif
call em.customizeElement(17,PC,"Creeps","",I2S(ps.creepsE)+"/"+I2S(ps.creepsN),0.07)
call em.customizeElement(18,PC,"","","",0.07)
set i = ps.spellDmgD
if i == MAX_SP_D and MAX_SP_D != 0 then
call em.customizeElement(19,PC,"SpellDamageD"+pid,"",HIGH_COLOR+I2S(MAX_SP_D),0.07)
else
call em.customizeElement(19,PC,"SpellDamageD"+pid,"",I2S(i),0.07)
endif
set i = ps.attDmgD
if i == MAX_AT_D and MAX_AT_D != 0 then
call em.customizeElement(20,PC,"AttackDamageD"+pid,"",HIGH_COLOR+I2S(MAX_AT_D),0.07)
else
call em.customizeElement(20,PC,"AttackDamageD"+pid,"",I2S(i),0.07)
endif
set i = ps.healD
if i == MAX_H_D and MAX_H_D != 0 then
call em.customizeElement(21,PC,"HealD"+pid,"",HIGH_COLOR+I2S(MAX_H_D),0.07)
else
call em.customizeElement(21,PC,"HealD"+pid,"",I2S(i),0.07)
endif
set i = ps.maxCritD
if i == MAX_CRIT_D and MAX_CRIT_D != 0 then
call em.customizeElement(22,PC,"MaxCriticalD"+pid,Players[ps.maxCritDTarget].hero.IconID,HIGH_COLOR+"[|r"+DamageMod_COLOR[ps.maxCritDType]+I2S(MAX_CRIT_D)+HIGH_COLOR+"]|r",0.07)
else
if ps.maxCritDTarget != 0 then
call em.customizeElement(22,PC,"MaxCriticalD"+pid,Players[ps.maxCritDTarget].hero.IconID,DamageMod_COLOR[ps.maxCritDType]+I2S(i),0.07)
else
call em.customizeElement(22,PC,"MaxCriticalD"+pid,"UI\\Widgets\\Console\\Orc\\orc-inventory-slotfiller.blp",DamageMod_COLOR[ps.maxCritDType]+I2S(i),0.07)
endif
endif
set i = ps.spellDmgT
if i == MAX_SP_T and MAX_SP_T != 0 then
call em.customizeElement(23,PC,"SpellDamageT"+pid,"",HIGH_COLOR+I2S(MAX_SP_T),0.07)
else
call em.customizeElement(23,PC,"SpellDamageT"+pid,"",I2S(i),0.07)
endif
set i = ps.attDmgT
if i == MAX_AT_T and MAX_AT_T != 0 then
call em.customizeElement(24,PC,"AttackDamageT"+pid,"",HIGH_COLOR+I2S(MAX_AT_T),0.07)
else
call em.customizeElement(24,PC,"AttackDamageT"+pid,"",I2S(i),0.07)
endif
set i = ps.maxCritT
if i == MAX_CRIT_T and MAX_CRIT_T != 0 then
call em.customizeElement(25,PC,"MaxCriticalT"+pid,Players[ps.maxCritTSource].hero.IconID,HIGH_COLOR+"[|r"+DamageMod_COLOR[ps.maxCritTType]+I2S(MAX_CRIT_T)+HIGH_COLOR+"]|r",0.07)
else
if ps.maxCritTSource != 0 then
call em.customizeElement(25,PC,"MaxCriticalT"+pid,Players[ps.maxCritTSource].hero.IconID,DamageMod_COLOR[ps.maxCritTType]+I2S(i),0.07)
else
call em.customizeElement(25,PC,"MaxCriticalT"+pid,"UI\\Widgets\\Console\\Orc\\orc-inventory-slotfiller.blp",DamageMod_COLOR[ps.maxCritTType]+I2S(i),0.07)
endif
endif
set i = ps.totalDmgD
if i == MAX_DMG_D and MAX_DMG_D != 0 then
call em.customizeElement(26,PC,"TotalDamageD"+pid,"",HIGH_COLOR+I2S(MAX_DMG_D),0.07)
else
call em.customizeElement(26,PC,"TotalDamageD"+pid,"",I2S(i),0.07)
endif
set i = ps.totalDmgT
if i == MAX_DMG_T and MAX_DMG_T != 0 then
call em.customizeElement(27,PC,"TotalDamageT"+pid,"",HIGH_COLOR+I2S(MAX_DMG_T),0.07)
else
call em.customizeElement(27,PC,"TotalDamageT"+pid,"",I2S(i),0.07)
endif
if t == 1 then
set i = 7
loop
if Players[i].isPlaying then
call em.customizeElement(28 + (i - 7),PC,"Kills"+pid,Players[i].hero.IconID,"x"+I2S(ps.tb.integer[i]),0.07)
else
call em.customizeElement(28 + (i - 7),PC,"Kills"+pid,"UI\\Widgets\\Console\\Orc\\orc-inventory-slotfiller.blp","",0.07)
endif
set i = i + 1
exitwhen i > 11
endloop
else
set i = 2
loop
if Players[i].isPlaying then
call em.customizeElement(28 + (i - 2),PC,"Kills"+pid,Players[i].hero.IconID,"x"+I2S(ps.tb.integer[i]),0.07)
else
call em.customizeElement(28 + (i - 2),PC,"Kills"+pid,"UI\\Widgets\\Console\\Orc\\orc-inventory-slotfiller.blp","",0.07)
endif
set i = i + 1
exitwhen i > 6
endloop
endif
set it = null
endfunction
public function Setup takes nothing returns nothing
local integer i = 2
local player p
local string tittle
if Game.Mode == GAME_MODE_LMS or Game.Mode == GAME_MODE_OD then
set tittle = "Results: " + HORDE_COLOR+I2S(Team[1].rounds)+"|r"+"/"+ALLIANCE_COLOR+I2S(Team[2].rounds)+"|r "
else
set tittle = "Results: " + HORDE_COLOR+I2S(Team[1].resources)+"|r"+"/"+ALLIANCE_COLOR+I2S(Team[2].resources)+"|r "
endif
set tittle = tittle + CLOCK_COLOR+"Game Time: (|r"+WHITE_COLOR+I2S(GameLoop.Minutes)+":"+I2S(GameLoop.Seconds)+"|r"+CLOCK_COLOR+") |r" + "Kills: ("+HORDE_COLOR+I2S(Team[1].kills)+"|r/"+ALLIANCE_COLOR+I2S(Team[2].kills)+"|r) "
set tittle = tittle + "Winner: " + Game.Winner.name
call TEAM_MULTIBOARD[1].showMultiboard(false)
call TEAM_MULTIBOARD[2].showMultiboard(false)
//call TEAM_MULTIBOARD[1].destroy()
//call TEAM_MULTIBOARD[2].destroy()
set em = Multiboard.create(tittle,32,1 + Players.PlayersTotal)
set PC = 2
call em.customizeElement(1,1,"Player","",TITTLE_COLOR+"Player",0.15)
call em.customizeElement(2,1,"HeroLvl","",TITTLE_COLOR+"Hero/Lvl",0.15)
call em.customizeElement(3,1,"","","",0.15)
call em.customizeElement(4,1,"Items","",TITTLE_COLOR+"Items|r",0.15)
call em.customizeElement(5,1,"","","",0.15)
call em.customizeElement(6,1,"","","",0.15)
call em.customizeElement(7,1,"","","",0.15)
call em.customizeElement(8,1,"","","",0.15)
call em.customizeElement(9,1,"","","",0.15)
call em.customizeElement(10,1,"","","",0.15)
call em.customizeElement(11,1,"Gold Earned","",TITTLE_COLOR+"Gold Earned|r",0.15)
call em.customizeElement(12,1,"Kills/Deaths","",TITTLE_COLOR+"Kills/Deaths|r",0.15)
call em.customizeElement(13,1,"","",TITTLE_COLOR+"|r",0.15)
call em.customizeElement(14,1,"Towers","",TITTLE_COLOR+"Bases|r",0.15)
call em.customizeElement(15,1,"Gold Mines","",TITTLE_COLOR+"Gold Mines|r",0.15)
call em.customizeElement(16,1,"Obelisks","",TITTLE_COLOR+"Obelisks|r",0.15)
call em.customizeElement(17,1,"Creeps","",TITTLE_COLOR+"Creeps E/N|r",0.15)
call em.customizeElement(18,1,"","","",0.15)
call em.customizeElement(19,1,"SpellDamageD","",TITTLE_COLOR+"Spell Damage Dealt|r",0.15)
call em.customizeElement(20,1,"AttackDamageD","",TITTLE_COLOR+"Attack Damage Dealt|r",0.15)
call em.customizeElement(21,1,"HealD","",TITTLE_COLOR+"Healing Done|r",0.15)
call em.customizeElement(22,1,"MaxCriticalD","",TITTLE_COLOR+"Max Critical Dealt|r",0.15)
call em.customizeElement(23,1,"SpellDamageT","",TITTLE_COLOR+"Spell Damage Taken|r",0.15)
call em.customizeElement(24,1,"AttackDamageT","",TITTLE_COLOR+"Attack Damage Taken|r",0.15)
call em.customizeElement(25,1,"MaxCriticalT","",TITTLE_COLOR+"Max Critical Taken|r",0.15)
call em.customizeElement(26,1,"TotalDamageD","",TITTLE_COLOR+"Total Damage Dealt|r",0.15)
call em.customizeElement(27,1,"TotalDamageT","",TITTLE_COLOR+"Total Damage Taken|r",0.15)
call em.customizeElement(28,1,"Kill Details","",TITTLE_COLOR+"Kill Details|r",0.15)
call em.customizeElement(29,1,"","","",0.15)
call em.customizeElement(30,1,"","","",0.15)
call em.customizeElement(31,1,"","","",0.15)
call em.customizeElement(32,1,"","","",0.15)
loop
set p = Player(i)
if Players[i].isPlaying then
call ConfigMultiboard(p)
set PC = PC + 1
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
call em.updateMultiboard()
call em.showMultiboard(true)
call MultiboardMinimize(em.mul,false)
set p = null
endfunction
endlibrary
library Illusion initializer init uses Table, Item
globals
private constant integer ILLUSION_SPELL = 'AILS'
private constant integer DUMMY_ID = 'u001'
endglobals
struct Illusion extends array
implement Alloc
readonly unit unit
real damageTaken
real damageDealt
static Table tb = 0
static group g = null
static unit dummy = null
static unit illu = null
static method get takes unit u returns thistype
return thistype.tb[GetHandleId(u)]
endmethod
public static method onDeath takes nothing returns boolean
if IsUnitIllusion(GetTriggerUnit()) and IsUnitInGroup(GetTriggerUnit(),thistype.g) then
call thistype(thistype.get(GetTriggerUnit())).destroy()
endif
return false
endmethod
public static method onPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Illusion i
if IsUnitIllusion(data.source) or IsUnitIllusion(data.target) then
if IsUnitInGroup(data.source, thistype.g) then
set i = thistype.get(data.source)
set data.mult = data.mult + (i.damageDealt - 1)
endif
if IsUnitInGroup(data.target, thistype.g) then
set i = thistype.get(data.target)
set data.mult = data.mult + (i.damageTaken - 1)
endif
endif
endmethod
public static method entered takes nothing returns nothing
local unit u = GetSummoningUnit()
local Item it
if u == thistype.dummy then
set thistype.illu = GetSummonedUnit()
else
if IsUnitIllusion(GetSummonedUnit()) then
set it = GetUnitItemOfType(u,'pgma')
if it != 0 then
call Illusion.createEx(u,GetSummonedUnit(),3.0,0.10 + 0.10 * it.tier)
endif
endif
endif
set u = null
endmethod
method operator duration= takes real time returns nothing
call UnitApplyTimedLife(this.unit, 'BTLF', time)
endmethod
static method createEx takes unit source, unit illu, real dt, real dd returns thistype
local thistype this = thistype.allocate()
set this.unit = illu
set this.damageTaken = dt
set this.damageDealt = dd
call SetUnitAnimation(illu, "stand")
call GroupAddUnit(thistype.g, this.unit)
set thistype.tb[GetHandleId(this.unit)] = this
call BonusStruct.CopyBonusIllusion(source,this.unit)
return this
endmethod
static method create takes player owner, unit source, real x, real y returns thistype
local thistype this
set thistype.illu = null
//Create the Illusion Unit
if source != null and UnitAlive(source) then
call SetUnitPosition(thistype.dummy,GetUnitX(source),GetUnitY(source))
call SetUnitOwner(thistype.dummy, GetOwningPlayer(source), false)
if IssueTargetOrderById(thistype.dummy, 852274, source) then
if thistype.illu != null then
call SetUnitOwner(thistype.illu, owner, true)
if IsUnitType(source, UNIT_TYPE_STRUCTURE) then
call SetUnitPosition(thistype.illu, x, y)
else
call SetUnitX(thistype.illu, x)
call SetUnitY(thistype.illu, y)
endif
else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 3600, "[Illusion] No illusion created")
return 0
endif
else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 3600, "[Illusion] Issued illusion create order failed")
return 0
endif
else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 3600, "[Illusion] Source unit dead or non-existing")
return 0
endif
//Initialize struct
call SetUnitOwner(thistype.dummy,Game.PLAYER_NEUTRAL_EXTRA,false)
set this = thistype.allocate()
set this.unit = thistype.illu
set this.damageTaken = 1.0
set this.damageDealt = 1.0
call SetUnitAnimation(thistype.illu, "stand")
call GroupAddUnit(thistype.g, this.unit)
set thistype.tb[GetHandleId(this.unit)] = this
call BonusStruct.CopyBonusIllusion(source,this.unit)
set thistype.illu = null
return this
endmethod
method destroy takes nothing returns nothing
call GroupRemoveUnit(thistype.g, this.unit)
if UnitAlive(this.unit) then
call KillUnit(this.unit)
endif
call thistype.tb.remove(GetHandleId(this.unit))
set this.unit = null
call this.deallocate()
endmethod
endstruct
private function init takes nothing returns nothing
set Illusion.dummy = CreateUnit(Game.PLAYER_NEUTRAL_EXTRA, DUMMY_ID, 0, 0, 0)
call UnitAddAbility(Illusion.dummy, ILLUSION_SPELL)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function Illusion.onDeath)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SUMMON,function Illusion.entered)
call DamageEvent.RegisterPreCalculation(Filter(function Illusion.onPreDamage))
set Illusion.tb = Table.create()
set Illusion.g = CreateGroup()
endfunction
endlibrary
library Lightning uses TimerUtils, MiscLibrary
globals
private constant real PERIODIC = 0.06
endglobals
struct Lightning extends array
implement Alloc
lightning light
real timeLeft
real xSource
real ySource
real zSource
unit unitSource
real xTarget
real yTarget
real zTarget
unit unitTarget
real colorRed
real colorGreen
real colorBlue
real colorAlpha
real fadeTime
real fadeFactor
Link link
private static LinkedList AllInstances
private static timer Timer
private static method Loop takes nothing returns nothing
local Link h = AllInstances.head
local Lightning x
local Link temp
local integer sw
loop
exitwhen h == 0
set x = h.data
set sw = 0
call x.update()
if x.timeLeft > 0 then
set x.timeLeft = x.timeLeft - PERIODIC
if x.timeLeft <= 0 then
set sw = 1
endif
endif
if x.fadeTime != 0 then
if x.timeLeft <= x.fadeTime then
set x.colorAlpha = x.colorAlpha - x.fadeFactor
call SetLightningColor(x.light,x.colorRed,x.colorGreen,x.colorBlue,x.colorAlpha)
endif
endif
if sw == 1 then
set temp = h.next
call x.destroy()
set h = temp
else
set h = h.next
endif
endloop
if AllInstances.size == 0 then
call PauseTimer(Timer)
endif
endmethod
private static method Remove takes Lightning l returns nothing
call AllInstances.remove(l.link)
if AllInstances.size == 0 then
call PauseTimer(Timer)
endif
endmethod
private static method Add takes Lightning l returns nothing
set l.link = AllInstances.add(l)
if AllInstances.size == 1 then
call TimerStart(Timer,PERIODIC,true,function thistype.Loop)
endif
endmethod
private method update takes nothing returns nothing
local real xs
local real ys
local real zs
local real xt
local real yt
local real zt
if unitSource == null then
set xs = xSource
set ys = ySource
set zs = GetLocZ(xs,ys) + zSource
else
set xs = GetUnitX(unitSource)
set ys = GetUnitY(unitSource)
set xSource = xs
set ySource = ys
set zs = GetLocZ(xs,ys) + zSource + GetUnitFlyHeight(unitSource)
endif
if unitTarget == null then
set xt = xTarget
set yt = yTarget
set zt = GetLocZ(xt,yt) + zTarget + GetUnitFlyHeight(unitTarget)
else
set xt = GetUnitX(unitTarget)
set yt = GetUnitY(unitTarget)
set xTarget = xt
set yTarget = yt
set zt = GetLocZ(xt,yt) + zTarget
endif
call MoveLightningEx(light,true,xs,ys,zs,xt,yt,zt)
endmethod
public method setDuration takes real d, real f returns nothing
set timeLeft = d
set fadeTime = f
endmethod
public method setLightColor takes integer r, integer g, integer b, integer a returns nothing
set colorRed = r/255.
set colorGreen = g/255.
set colorBlue = b/255.
if fadeTime == 0 then
set colorAlpha = a/255.
endif
call SetLightningColor(light,colorRed,colorGreen,colorBlue,colorAlpha)
endmethod
public method attachToXYZSource takes real x, real y, real z returns nothing
set unitSource = null
set xSource = x
set ySource = y
set zSource = z
call update()
endmethod
public method attachToUnitSource takes unit u returns nothing
set unitSource = u
set xSource = 0
set ySource = 0
call update()
endmethod
public method attachToXYZTarget takes real x, real y, real z returns nothing
set unitTarget = null
set xTarget = x
set yTarget = y
set zTarget = z
call update()
endmethod
public method attachToUnitTarget takes unit u returns nothing
set unitTarget = u
set xTarget = 0
set yTarget = 0
call update()
endmethod
public static method create takes string id, unit source, unit target, real time, real fade, real z, real zt returns thistype
local thistype this = thistype.allocate()
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real xt = GetUnitX(target)
local real yt = GetUnitY(target)
set this.allocName = "Lightning"
set light = AddLightningEx(id,true,xs,ys,GetLocZ(xs,ys) + z,xt,yt,GetLocZ(xt,yt) + zt)
set timeLeft = time
set fadeTime = fade
set unitSource = source
set unitTarget = target
set zSource = z
set zTarget = zt
set colorRed = 1.00
set colorGreen = 1.00
set colorBlue = 1.00
set colorAlpha = 1.0
call update()
if fadeTime > 0.00 then
if time < fadeTime then
set time = fadeTime
endif
set fadeFactor = 1.0 / (fadeTime/PERIODIC)
endif
call Add(this)
return this
endmethod
public static method createEx takes string id, real x, real y, real z, real xt, real yt, real zt, real time, real fade returns thistype
local thistype this = thistype.allocate()
set light = AddLightningEx(id,true,x,y,GetLocZ(x,y) + z,xt,yt,GetLocZ(xt,yt) + zt)
set timeLeft = time
set fadeTime = fade
set xSource = x
set ySource = y
set zSource = z
set xTarget = xt
set yTarget = yt
set zTarget = zt
set colorRed = 1.00
set colorGreen = 1.00
set colorBlue = 1.00
set colorAlpha = 1.0
if fade > 0.00 then
if time < fadeTime then
set time = fadeTime
endif
set fadeFactor = 1.0 / (fadeTime/PERIODIC)
endif
if time > 0.00 then
call Add(this)
endif
return this
endmethod
public method destroy takes nothing returns nothing
call Remove(this)
call DestroyLightning(light)
set light = null
set unitTarget = null
set unitSource = null
set xTarget = 0
set yTarget = 0
set xSource = 0
set ySource = 0
set fadeTime = 0
set timeLeft = 0
set link = 0
call this.deallocate()
endmethod
public static method onInit takes nothing returns nothing
set AllInstances = LinkedList.create()
set Timer = CreateTimer()
endmethod
endstruct
endlibrary
library AttackRange uses UnitData
globals
private constant integer UPGRADE_ID = 'R001'
endglobals
function AddHeroAttackRange takes unit u, integer levels returns nothing
local integer ar = GetUnitData(u,"AttackRangeLevel")
if IsUnitType(u,UNIT_TYPE_HERO) and IsUnitType(u,UNIT_TYPE_RANGED_ATTACKER) then
if levels > 0 then
set ar = ar + levels
call SetUnitData(u,"AttackRangeLevel",ar)
call SetPlayerTechResearched(GetOwningPlayer(u),UPGRADE_ID,ar)
else
set ar = ar + levels
call SetUnitData(u,"AttackRangeLevel",ar)
call BlzDecPlayerTechResearched(GetOwningPlayer(u),UPGRADE_ID,levels * -1)
endif
call SetUnitAcquireRange(u,GetUnitDefaultAcquireRange(u) + ar * 25)
endif
endfunction
endlibrary
scope GameMusic
globals
public string HUMAN_MUSIC_LIST = "Sound\\Music\\Internal\\Human1.flac;Sound\\Music\\Internal\\Human2.flac;Sound\\Music\\Internal\\Human3.flac;Sound\\Music\\Internal\\HumanX1.flac"
public string ORC_MUSIC_LIST = "Sound\\Music\\Internal\\Orc1.flac;Sound\\Music\\Internal\\Orc2.flac;Sound\\Music\\Internal\\Orc3.flac;Sound\\Music\\Internal\\OrcX1.flac"
public string NIGHTELF_MUSIC_LIST = "Sound\\Music\\Internal\\NightElf1.flac;Sound\\Music\\Internal\\NightElf2.flac;Sound\\Music\\Internal\\NightElf3.flac;Sound\\Music\\Internal\\NightElfX1.flac"
public string UNDEAD_MUSIC_LIST = "Sound\\Music\\Internal\\Undead1.flac;Sound\\Music\\Internal\\NightElf2.flac;Sound\\Music\\Internal\\Undead3.flac;Sound\\Music\\Internal\\UndeadX1.flac"
public string BOSS_MUSIC = "Sound\\Music\\Internal\\War2IntroMusic.flac"
public string LAST_OBELISK_MUSIC = "Sound\\Music\\Internal\\Doom.flac"
endglobals
struct PlayerMusic extends array
string music
endstruct
endscope
scope Point
struct Point extends array
implement Alloc
real x
real y
integer data
public static method create takes real xc, real yc returns thistype
local thistype this = thistype.allocate()
set x = xc
set y = yc
return this
endmethod
public method destroy takes nothing returns nothing
set data = 0
call this.deallocate()
endmethod
endstruct
endscope
library HeroicTraits initializer init uses SpellEffectEvent, Status
globals
public constant integer TRAIT_UNIT_ID = 'n00V'
public constant integer TRAIT_SELECT_ID = 'A02Y'
public constant integer S_AVATAR_ID = 'A04L'
public constant integer S_BERSERK_ID = 'A04V'
public constant integer S_DISPEL_ID = 'A07H'
public constant integer S_FLASH_ID = 'A02Z'
public constant integer S_HEAVEN_ID = 'A04M'
public constant integer S_MURDERER_ID = 'A04P'
public constant integer S_RECKLESS_ID = 'A04O'
public constant integer S_REPLENISH_ID = 'A07I'
public constant integer S_SAVIOR_ID = 'A07J'
public constant integer S_SPRINT_ID = 'A038'
public constant integer S_TITAN_ID = 'A04N'
public constant integer S_MIND_ID = 'A07G'
public constant integer AVATAR_ID = 'A07L'
public constant integer BERSERK_ID = 'A07R'
public constant integer DISPEL_ID = 'A07V'
public constant integer FLASH_ID = 'A07K'
public constant integer HEAVEN_ID = 'A07N'
public constant integer MURDERER_ID = 'A07Q'
public constant integer RECKLESS_ID = 'A07P'
public constant integer REPLENISH_ID = 'A07U'
public constant integer SAVIOR_ID = 'A07T'
public constant integer SPRINT_ID = 'A07M'
public constant integer TITAN_ID = 'A07O'
public constant integer MIND_ID = 'A07S'
private trigger SELECT_TRIGGER
private trigger AVATAR_KEY_TRIGGER
private constant string AVATAR_SFX = "Abilities\\Spells\\Human\\Avatar\\AvatarCaster.mdl"
endglobals
function GivesTraitAbility takes integer id, Hero h returns nothing
local Team t = GetPlayerTeamEx(GetOwningPlayer(h.hero))
if id == S_AVATAR_ID then
call UnitAddAbility(h.hero,AVATAR_ID)
set h.traitAbility = AVATAR_ID
call UnitMakeAbilityPermanent(h.hero,true,AVATAR_ID)
call BlzTriggerRegisterPlayerKeyEvent(AVATAR_KEY_TRIGGER,GetOwningPlayer(h.hero),OSKEY_X,0,true)
call TeamComposition.AddHeroicAbilityInfo(t,0,0,0,5,0,0)
elseif id == S_BERSERK_ID then
call UnitAddAbility(h.hero,BERSERK_ID)
call UnitMakeAbilityPermanent(h.hero,true,BERSERK_ID)
set h.traitAbility = BERSERK_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,5,3,0,0)
elseif id == S_DISPEL_ID then
call UnitAddAbility(h.hero,DISPEL_ID)
call UnitMakeAbilityPermanent(h.hero,true,DISPEL_ID)
set h.traitAbility = DISPEL_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,0,0,0,4)
elseif id == S_FLASH_ID then
call UnitAddAbility(h.hero,FLASH_ID)
call UnitMakeAbilityPermanent(h.hero,true,FLASH_ID)
set h.traitAbility = FLASH_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,4,2,2,0)
elseif id == S_HEAVEN_ID then
call UnitAddAbility(h.hero,HEAVEN_ID)
call UnitMakeAbilityPermanent(h.hero,true,HEAVEN_ID)
set h.traitAbility = HEAVEN_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,2,4,0,0)
elseif id == S_MURDERER_ID then
call UnitAddAbility(h.hero,MURDERER_ID)
call UnitMakeAbilityPermanent(h.hero,true,MURDERER_ID)
set h.traitAbility = MURDERER_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,5,0,0,0,0)
elseif id == S_RECKLESS_ID then
call UnitAddAbility(h.hero,RECKLESS_ID)
call UnitMakeAbilityPermanent(h.hero,true,RECKLESS_ID)
set h.traitAbility = RECKLESS_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,0,5,0,0)
elseif id == S_REPLENISH_ID then
call UnitAddAbility(h.hero,REPLENISH_ID)
call UnitMakeAbilityPermanent(h.hero,true,REPLENISH_ID)
set h.traitAbility = REPLENISH_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,5,2,0,0)
elseif id == S_SAVIOR_ID then
call UnitAddAbility(h.hero,SAVIOR_ID)
call UnitMakeAbilityPermanent(h.hero,true,SAVIOR_ID)
set h.traitAbility = SAVIOR_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,0,5,2,0)
elseif id == S_SPRINT_ID then
call UnitAddAbility(h.hero,SPRINT_ID)
call UnitMakeAbilityPermanent(h.hero,true,SPRINT_ID)
set h.traitAbility = SPRINT_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,0,2,5,0)
elseif id == S_TITAN_ID then
call UnitAddAbility(h.hero,TITAN_ID)
call UnitMakeAbilityPermanent(h.hero,true,TITAN_ID)
set h.traitAbility = TITAN_ID
call TeamComposition.AddHeroicAbilityInfo(t,0,0,0,5,0,0)
elseif id == S_MIND_ID then
call UnitAddAbility(h.hero,MIND_ID)
call UnitMakeAbilityPermanent(h.hero,true,MIND_ID)
set h.traitAbility = MIND_ID
call TeamComposition.AddHeroicAbilityInfo(t,2,0,2,0,0,0)
endif
set Players.TraitCount = Players.TraitCount + 1
if Players.TraitCount == Players.PlayersActive then
call DestroyTrigger(SELECT_TRIGGER)
set SELECT_TRIGGER = null
endif
call MultiboardUpdateTrait(GetOwningPlayer(h.hero),BlzGetAbilityIcon(id))
endfunction
private function OnSelect takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id = GetSpellAbilityId()
local player p = GetOwningPlayer(u)
local Hero h
if GetUnitTypeId(u) == TRAIT_UNIT_ID then
set h = GetPlayerHero(p)
call UnitRemoveAbility(h.hero,TRAIT_SELECT_ID)
call RemoveUnit(u)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(id,h)
call SelectUnitForPlayer(h.hero,p,true)
endif
set u = null
set p = null
endfunction
private function TraitSelect takes nothing returns nothing
local player pt = GetTriggerPlayer()
local Players p = Players[GetPlayerId(pt)]
if p.hero != 0 then
call SelectUnitForPlayer(p.traitUnit,pt,true)
endif
set pt = null
endfunction
private function Avatar takes nothing returns nothing
call Status.Add(STATUS_SPELL_IMMUNITY,GetTriggerUnit(),3.0 + 0.20 * GetHeroLevel(GetTriggerUnit()),Status_EFFECT[STATUS_SPELL_IMMUNITY])
endfunction
private function Berserker takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,7.00,Berserk.buff,0,0)
set u = null
endfunction
private function DispelPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local group g = tb.group[2]
local integer c = tb.integer[1]
local player p = tb.player[0]
local unit temp
local group g2 = NewGroup()
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
call GroupAddUnit(g2,temp)
if IsUnitAlly(temp,p) then
call UnitDispelAllBuffs(temp,BUFF_TYPE_NEGATIVE)
call DispelNegativeStatus(temp)
else
call UnitDispelAllBuffs(temp,BUFF_TYPE_POSITIVE)
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\DispelMagic\\DispelMagicTarget.mdl",temp,"overhead"))
endloop
call ReleaseGroup(g)
set tb.group[2] = g2
set c = c + 1
set tb.integer[1] = c
if c == 5 then
call ReleaseTimer(t)
call ReleaseGroup(g2)
call tb.flush()
call tb.destroy()
endif
set p = null
set g = null
set g2 = null
set t = null
endfunction
private function Dispel takes nothing returns nothing
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local group g = NewGroup()
local player p = GetTriggerPlayer()
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local unit temp
local group g2 = NewGroup()
set tb.player[0] = p
set tb.integer[1] = 0
set tb.group[2] = g2
call GroupEnumUnitsInRange(g,x,y,200,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if IsUnitType(temp,UNIT_TYPE_HERO) then
call GroupAddUnit(g2,temp)
if IsUnitAlly(temp,p) then
call UnitDispelAllBuffs(temp,BUFF_TYPE_NEGATIVE)
call DispelNegativeStatus(temp)
else
call UnitDispelAllBuffs(temp,BUFF_TYPE_POSITIVE)
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\DispelMagic\\DispelMagicTarget.mdl",temp,"overhead"))
endif
endloop
call ReleaseGroup(g)
call TimerStart(t,0.5,true,function DispelPeriodic)
set p = null
set g = null
set g2 = null
set t = null
endfunction
private function Flash takes nothing returns nothing
local unit u = GetTriggerUnit()
local real xt = GetSpellTargetX()
local real yt = GetSpellTargetY()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real a = Angle(x,y,xt,yt)
local real d = Distance(x,y,xt,yt)
local real t = 0.35 * (d/400.00)
call KPJUnit.create(u,d,a,t,0,KPJDefaultConfig,KPJ_TYPE_KNOCKBACK)
if t > 0.00 then
call UnitAddBuff(u,u,t,FlashRecovery.buff,0,0)
else
call UnitAddBuff(u,u,0.01,FlashRecovery.buff,0,0)
endif
set u = null
endfunction
private function Heaven takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,15,HeavenlyGrace.buff,0,0)
set u = null
endfunction
private function MurdererS takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,99999.00,Murderer.buff,0,0)
set u = null
endfunction
private function RecklessS takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,4 + 0.20 * GetHeroLevel(u),Reckless.buff,0,0)
set Respawn[GetUnitUserData(u)].RSReduction = true
set u = null
endfunction
private function ReplenishS takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(GetSpellTargetUnit(),u,2.25,Replenish.buff,0,0)
set u = null
endfunction
private function Savior takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
if u == t then
call KPJUnit.create(u,600,GetUnitFacing(u) * bj_DEGTORAD,0.50,0,KPJDefaultConfig,KPJ_TYPE_KNOCKBACK)
else
call Lightning.create("HLFX",t,u,0.6,0.25,150,150).setLightColor(255,180,0,255)
call KPJUnit.create(t,600,AngleBetweenUnits(t,u),0.55,150,KPJDefaultConfig,KPJ_TYPE_JUMP)
endif
call DispelMovilityStatus(t)
call UnitDispelAllBuffsType(t,EFFECT_TYPE_SLOW)
call UnitAddBuff(u,u,15.00,SaviorHand.buff,0,0)
set u = null
endfunction
private function SprintSCB takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetUnitByIndex(GetTimerData(t))
//call UnitRemoveAbility(u,'BOwk')
call UnitAddBuff(u,u,8.0,Sprint.buff,0,0)
call DispelMovilityStatus(u)
call UnitDispelAllBuffsType(u,EFFECT_TYPE_SLOW)
set u = null
endfunction
private function SprintS takes nothing returns nothing
local unit u = GetTriggerUnit()
call TimerStart(NewTimerEx(GetUnitUserData(u)),0,false,function SprintSCB)
set u = null
endfunction
private function Titan takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,15.0,TitanWall.buff,0,0)
set u = null
endfunction
private function Mind takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,15.0,PresenceOfMind.buff,0,0)
set u = null
endfunction
private function onPreDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
local Berserk be
if d.damageMod > 0 and d.dmgType != 0 and d.codeDmg.codeName != "Lifesteal" then
set be = GetUnitBuff(d.source,Berserk.buff).buffAllocIndex
if be != 0 then
set d.lifestealAdd = d.lifestealAdd + be.ls
set d.slifestealAdd = d.slifestealAdd + be.sls
set d.criticalChanceAdd = d.criticalChanceAdd + 25
endif
endif
endfunction
private function onPostDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local TitanWall shield
local Buff b
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime and data.damageMod > 0 then
set shield = GetUnitBuff(data.target,TitanWall.buff).buffAllocIndex
if shield != 0 then
set shield.life = shield.life - data.damageMod
if shield.life < 0 then
if shield.life <= -1 then
set data.damageMod = shield.life * -1
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
set shield.life = 0
call UnitRemoveBuff(data.target,TitanWall.buff)
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
endif
if UnitHasBuff(data.target,Reckless.buff) and not data.isAbsorbed then
if GetWidgetLife(data.target) - data.damageMod <= 0.405 then
call SetUnitState(data.target,UNIT_STATE_LIFE,1.00)
set data.damageMod = 0
set data.isAbsorbed = true
endif
endif
endif
if data.dmgType == udg_DamageTypeAttack and data.mainAttack then
if IsUnitType(data.source,UNIT_TYPE_HERO) then
set b = GetUnitBuff(data.source,Murderer.buff)
if b != 0 then
if Murderer[b.buffAllocIndex].count != 0 then
set Murderer[b.buffAllocIndex].count = Murderer[b.buffAllocIndex].count - 1
if Murderer[b.buffAllocIndex].count == 0 then
call UnitRemoveBuff(data.source,Murderer.buff)
endif
endif
endif
endif
endif
endfunction
public function AvatarDisabledActivation takes nothing returns nothing
local player p = GetTriggerPlayer()
local Hero h = GetPlayerHero(p)
call SyncSelections()
if IsUnitSelected(h.hero,p) then
if BlzGetUnitAbilityCooldownRemaining(h.hero,'A07L') == 0 then
if Status.UnitHasStatus(STATUS_STUN,h.hero) or Status.UnitHasStatus(STATUS_SILENCE,h.hero) or Status.UnitHasStatus(STATUS_HEX,h.hero) or Status.UnitHasStatus(STATUS_CYCLONE,h.hero) or Status.UnitHasStatus(STATUS_FEAR,h.hero) or Status.UnitHasStatus(STATUS_SLEEP,h.hero) then
call BlzStartUnitAbilityCooldown(h.hero,'A07L',120.00)
call Status.Add(STATUS_SPELL_IMMUNITY,h.hero,3.0 + 0.20 * GetHeroLevel(h.hero),Status_EFFECT[STATUS_SPELL_IMMUNITY])
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Avatar\\AvatarCaster.mdl",h.hero,"chest"))
endif
endif
endif
set p = null
endfunction
public function CreateHeroicAbilitySelectorForPlayer takes player p returns nothing
endfunction
private function init takes nothing returns nothing
set SELECT_TRIGGER = CreateTrigger()
set AVATAR_KEY_TRIGGER = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(SELECT_TRIGGER,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(SELECT_TRIGGER,function OnSelect)
call RegisterSpellEffectEvent(TRAIT_SELECT_ID, function TraitSelect)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
call DamageEvent.RegisterPostCalculation(Filter(function onPostDamage))
call TriggerAddAction(AVATAR_KEY_TRIGGER,function AvatarDisabledActivation)
call RegisterSpellEffectEvent(AVATAR_ID, function Avatar)
call RegisterSpellEffectEvent(BERSERK_ID, function Berserker)
call RegisterSpellEffectEvent(DISPEL_ID, function Dispel)
call RegisterSpellEffectEvent(FLASH_ID, function Flash)
call RegisterSpellEffectEvent(HEAVEN_ID, function Heaven)
call RegisterSpellEffectEvent(MURDERER_ID, function MurdererS)
call RegisterSpellEffectEvent(RECKLESS_ID, function RecklessS)
call RegisterSpellEffectEvent(REPLENISH_ID, function ReplenishS)
call RegisterSpellEffectEvent(SAVIOR_ID, function Savior)
call RegisterSpellEffectEvent(SPRINT_ID, function SprintS)
call RegisterSpellEffectEvent(TITAN_ID, function Titan)
call RegisterSpellEffectEvent(MIND_ID, function Mind)
call PreloadGen.Add(TRAIT_UNIT_ID,PRELOAD_UNIT)
endfunction
endlibrary
scope TraitBuffs initializer init
struct SaviorHand extends array
real value
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call AddUnitNegativeStatusReduction(b.target,-value,false)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set value = 0.50 + 0.02 * GetHeroLevel(b.target)
call AddUnitNegativeStatusReduction(b.target,value,false)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0A1'
set BUFF_DATA.BuffID = 'B04Y'
set BUFF_DATA.Name = "Savior Hand"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct PresenceOfMind extends array
boolean done
real sstr
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,-sstr,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set sstr = 20 + 4 * GetHeroLevel(b.target)
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,sstr,0)
set done = false
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A080'
set BUFF_DATA.BuffID = 'B02S'
set BUFF_DATA.Name = "Presence of Mind"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct TitanWall extends array
real life
integer statChoosed
real rv
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(statChoosed,b.target,-rv,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real bc = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_BLOCK,b.target)
local real e = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_EVASION,b.target)
local real r = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,b.target)
set life = 400.00 + 20.00 * GetHeroLevel(b.target)
if bc > e and bc > r then
set statChoosed = BONUS_TYPE_BLOCK
elseif e > bc and e > r then
set statChoosed = BONUS_TYPE_EVASION
else
set statChoosed = BONUS_TYPE_RESISTANCE
endif
set rv = 10 * GetHeroLevel(b.target)
call BonusStruct.AddSpecial(statChoosed,b.target,rv,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID ='A07Z'
set BUFF_DATA.BuffID = 'B02R'
set BUFF_DATA.Name = "TitanWall"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Sprint extends array
Movespeed ms
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,0.25,0)
call Status.Add(STATUS_PHASE,b.target,0,0)
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call Status.Remove(STATUS_PHASE,b.target)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if IsUnitMoving(b.target) then
set b.elapsedTime = b.elapsedTime - 0.03125
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A082'
set BUFF_DATA.BuffID = 'B02U'
set BUFF_DATA.Name = "Sprint"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Replenish extends array
real heal
real mana
unit t
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Lightning.create("HLFX",b.target,b.owner,0.5,0.25,150,150)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl",b.target,"overhead"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl",b.owner,"overhead"))
call UnitAddMp(b.target,mana)
call UnitAddMp(b.owner,mana)
call CodeDamage.Damage(b.target,b.target,heal,udg_DamageTypeHeal,"",0,0)
call CodeDamage.Damage(b.target,b.owner,heal,udg_DamageTypeHeal,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set heal = (150 + 20 * GetHeroLevel(b.target)) / 3
set mana = (75 + 10 * GetHeroLevel(b.target)) / 3
call Lightning.create("HLFX",b.target,b.owner,0.5,0.25,150,150)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl",b.target,"overhead"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl",b.owner,"overhead"))
call UnitAddMp(b.target,mana)
call UnitAddMp(b.owner,mana)
call CodeDamage.Damage(b.target,b.target,heal,udg_DamageTypeHeal,"",0,0)
call CodeDamage.Damage(b.target,b.owner,heal,udg_DamageTypeHeal,"",0,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Replenish"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.75
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Murderer extends array
integer dmg
integer as
real astr
integer count
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 15 + 2 * GetHeroLevel(b.target)
set as = 10 + 2 * GetHeroLevel(b.target)
set astr = 20 + 4 * GetHeroLevel(b.target)
set count = 20
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,astr,0)
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,-astr,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A07Y'
set BUFF_DATA.BuffID = 'B02Q'
set BUFF_DATA.Name = "Murderer"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct HeavenlyGrace extends array
integer armor
integer regen
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-armor,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,-regen)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,-regen)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set armor = 10 + 2 * GetHeroLevel(b.target)
set regen = 150 + 5 * GetHeroLevel(b.target)
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,regen)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,regen)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A07X'
set BUFF_DATA.BuffID = 'B02P'
set BUFF_DATA.Name = "Heavenly Grace"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct FlashRecovery extends array
private static method onFinish takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.target,b.target,100 + 20 * GetHeroLevel(b.target),udg_DamageTypeHeal,"",0,0)
call UnitAddMp(b.target,50 + 20 * GetHeroLevel(b.target))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl",b.target,"chest"))
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Flash Recovery"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Berserk extends array
real ls
real sls
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ls = 0.80 + 0.05 * GetHeroLevel(b.target)
set sls = 0.50 + 0.02 * GetHeroLevel(b.target)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A07W'
set BUFF_DATA.BuffID = 'B02O'
set BUFF_DATA.Name = "Berserk"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Reckless extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A081'
set BUFF_DATA.BuffID = 'B02T'
set BUFF_DATA.Name = "Reckless"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function init takes nothing returns nothing
call Berserk.Initialize()
call FlashRecovery.Initialize()
call HeavenlyGrace.Initialize()
call Murderer.Initialize()
call Reckless.Initialize()
call Replenish.Initialize()
call Sprint.Initialize()
call TitanWall.Initialize()
call PresenceOfMind.Initialize()
call SaviorHand.Initialize()
call PreloadGen.Add('A07W',PRELOAD_SECOND)
call PreloadGen.Add('A07X',PRELOAD_SECOND)
call PreloadGen.Add('A07Y',PRELOAD_SECOND)
call PreloadGen.Add('A07Z',PRELOAD_SECOND)
call PreloadGen.Add('A080',PRELOAD_SECOND)
call PreloadGen.Add('A081',PRELOAD_SECOND)
call PreloadGen.Add('A082',PRELOAD_SECOND)
endfunction
endscope
scope GateTower
private function GateDead takes nothing returns nothing
local unit u = GetTriggerUnit()
local Team t = GetUnitTeam(u)
if u == t.gateTower1 then
set t.gateTower1 = null
elseif u == t.gateTower2 then
set t.gateTower2 = null
endif
if t.gateTower1 == null and t.gateTower2 == null then
call Game.RunGameOver(2/t)
endif
set u = null
endfunction
public function Setup takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterDeathEvent(t,Team[1].gateTower1)
call TriggerRegisterDeathEvent(t,Team[1].gateTower2)
call TriggerRegisterDeathEvent(t,Team[2].gateTower1)
call TriggerRegisterDeathEvent(t,Team[2].gateTower2)
call TriggerAddCondition(t,function GateDead)
set t = null
endfunction
endscope
library Perks initializer init uses LinkedList, MiscLibrary
globals
private constant integer array PERKS_ID
endglobals
struct Perks extends array
LinkedList list
integer current
public method removePerkBook takes nothing returns nothing
local unit u = Index[this].u
local integer lvl
if current != 0 then
call UnitRemoveAbility(u,current)
if current == PERKS_ID[19] then
call list.destroy()
set list = 0
set current = 0
else
set current = 0
if list.head != 0 then
set lvl = list.head.data
call list.remove(list.head)
call addPerkBook(lvl)
endif
endif
endif
set u = null
endmethod
public method addPerkBook takes integer lvl returns nothing
local unit u = Index[this].u
if current == 0 then
call UnitAddAbility(u,PERKS_ID[lvl])
call UnitMakeAbilityPermanent(u,true,PERKS_ID[lvl])
if lvl == 6 then
call UnitMakeAbilityPermanent(u,true,'A034')
call UnitMakeAbilityPermanent(u,true,'A032')
call UnitMakeAbilityPermanent(u,true,'A033')
call UnitMakeAbilityPermanent(u,true,'A041')
call UnitMakeAbilityPermanent(u,true,'A042')
call UnitMakeAbilityPermanent(u,true,'A043')
call UnitMakeAbilityPermanent(u,true,'A03A')
call UnitMakeAbilityPermanent(u,true,'A03B')
elseif lvl == 11 then
call UnitMakeAbilityPermanent(u,true,'A03J')
call UnitMakeAbilityPermanent(u,true,'A03K')
call UnitMakeAbilityPermanent(u,true,'A03L')
call UnitMakeAbilityPermanent(u,true,'A03M')
call UnitMakeAbilityPermanent(u,true,'A0AW')
call UnitMakeAbilityPermanent(u,true,'A03N')
elseif lvl == 16 then
call UnitMakeAbilityPermanent(u,true,'A03R')
call UnitMakeAbilityPermanent(u,true,'A03S')
call UnitMakeAbilityPermanent(u,true,'A03T')
call UnitMakeAbilityPermanent(u,true,'A03U')
call UnitMakeAbilityPermanent(u,true,'A007')
call UnitMakeAbilityPermanent(u,true,'A03X')
elseif lvl == 19 then
call UnitMakeAbilityPermanent(u,true,'A0AC')
call UnitMakeAbilityPermanent(u,true,'A0AD')
call UnitMakeAbilityPermanent(u,true,'A0AE')
call UnitMakeAbilityPermanent(u,true,'A0AG')
call UnitMakeAbilityPermanent(u,true,'A0CH')
call UnitMakeAbilityPermanent(u,true,'A0CI')
call UnitMakeAbilityPermanent(u,true,'A0CJ')
call UnitMakeAbilityPermanent(u,true,'A0CK')
endif
set current = PERKS_ID[lvl]
else
call list.addLast(lvl)
endif
set u = null
endmethod
public static method create takes unit u returns thistype
local thistype this = thistype(GetUnitUserData(u))
set list = LinkedList.create()
set current = 0
return this
endmethod
endstruct
function SetPerkBonus takes integer id, unit u, integer level returns string
local Hero h
if level == 6 then
if id == 'A034' then
call BonusStruct.Add(BONUS_TYPE_AGILITY,u,8,0,false)
return "+8 Agility"
elseif id == 'A032' then
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,u,8,0,false)
return "+8 Intelligence"
elseif id == 'A033' then
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,8,0,false)
return "+8 Strength"
elseif id == 'A041' then
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,u,40,0)
return "+40(6.2%) Evasion"
elseif id == 'A042' then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,40,0)
return "+40(6.2%) Resistance"
elseif id == 'A043' then
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,u,40,0)
return "+40(6.2%) Block"
elseif id == 'A03A' then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,u,3,0)
return "+3 Health Regen"
elseif id == 'A03B' then
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,u,3,0)
return "+3 Mana Regen"
endif
endif
if level == 11 then
if id == 'A03J' then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,u,15,0,false)
return "+15 Damage"
elseif id == 'A03K' then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,u,15,0,false)
return "+15 Attack Speed"
elseif id == 'A03L' then
call BonusStruct.Add(BONUS_TYPE_ARMOR,u,3,0,false)
return "+3 Armor"
elseif id == 'A03M' then
call BonusStruct.Add(BONUS_TYPE_HP,u,150,0,false)
return "+150 Health"
elseif id == 'A0AW' then
call BonusStruct.Add(BONUS_TYPE_MP,u,150,0,false)
return "+150 Mana"
elseif id == 'A03N' then
call BonusStruct.Add(BONUS_TYPE_AGILITY,u,5,0,false)
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,u,5,0,false)
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,5,0,false)
return "+5 All Stats"
endif
endif
if level == 16 then
if id == 'A03R' then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,u,60,0)
return "+60(9.3%) Spell Strength"
elseif id == 'A03S' then
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,u,60,0)
return "+60(9.3%) Attack Strength"
elseif id == 'A03T' then
call BonusStruct.AddSpecial(BONUS_TYPE_CD_REDUCTION,u,-0.10,0)
return "+10% Cooldown Reduction"
elseif id == 'A03U' then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,u,0.15,0)
return "+15% Lifesteal"
elseif id == 'A007' then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,u,0.15,0)
return "+15% Spell Lifesteal"
elseif id == 'A03X' then
call AddUnitNegativeStatusReduction(u,0.10,false)
return "+10% Status Reduction"
endif
endif
if level == 19 then
if id == 'A0AC' then
call EnchantEffect.Add(EFFECT_CORRUPTION,u,2.0)
return "+2 Corruption"
elseif id == 'A0AD' then
call EnchantEffect.Add(EFFECT_FROST,u,1.0)
return "+1s Frost"
elseif id == 'A0AE' then
call EnchantEffect.Add(EFFECT_FEEDBACK,u,25.0)
return "+25 Feedback"
elseif id == 'A0AG' then
call EnchantEffect.Add(EFFECT_CLEAVE,u,0.25)
return "+25% Cleave"
elseif id == 'A0CH' then
call EnchantEffect.Add(EFFECT_BRUTE,u,10.0)
call EnchantEffect.Add(EFFECT_BASH,u,10.0)
call EnchantEffect.Add(EFFECT_ARCANE,u,10.0)
call EnchantEffect.Add(EFFECT_HUNTER,u,10.0)
call EnchantEffect.Add(EFFECT_METEOR,u,10.0)
return "+10% Chance to Weapon Enchantments"
elseif id == 'A0CI' then
call EnchantEffect.Add(EFFECT_MAGIC_THORNS,u,0.10)
call EnchantEffect.Add(EFFECT_IRON_THORNS,u,0.10)
return "+10% Damage Returned"
elseif id == 'A0CJ' then
call EnchantEffect.Add(EFFECT_PERSEVERANCE,u,10)
call EnchantEffect.Add(EFFECT_MANA_SHIELD,u,10)
call EnchantEffect.Add(EFFECT_CREST,u,10)
return "+10% Chance to Armor Enchantments"
elseif id == 'A0CK' then
call EnchantEffect.Add(EFFECT_FIRE_GUARD,u,-5)
call EnchantEffect.Add(EFFECT_DIAMOND,u,-5)
return "-5s Cooldown to Guard Enchantments"
elseif id == 'A03H' then
call EnchantEffect.Add(EFFECT_FOCUS,u,10)
return "+10% Mana Cost Reduction"
elseif id == 'A03I' then
call EnchantEffect.Add(EFFECT_BLEED,u,0.03)
return "+1% Bleed Attack Damage Amplification"
elseif id == 'A03O' then
call EnchantEffect.Add(EFFECT_DEFILER,u,1)
call SetUnitAbilityLevel(u,'A0BT',R2I(EnchantEffect.Get(EFFECT_DEFILER,u)))
call EnchantEffect.Add(EFFECT_ARCTIC,u,1)
call SetUnitAbilityLevel(u,'A0BS',R2I(EnchantEffect.Get(EFFECT_ARCTIC,u)))
call EnchantEffect.Add(EFFECT_RESILIENCE,u,1)
call SetUnitAbilityLevel(u,'A09I',R2I(EnchantEffect.Get(EFFECT_RESILIENCE,u)))
call EnchantEffect.Add(EFFECT_MAGIC_BREAK,u,1)
call SetUnitAbilityLevel(u,'A045',R2I(EnchantEffect.Get(EFFECT_MAGIC_BREAK,u)))
call MagicBreak.UpdateAuraLevel(u,'A045',2)
call EnchantEffect.Add(EFFECT_IMMOLATION,u,1)
if UnitHasBuff(u,Immolation.buff) then
call UnitAddBuff(u,u,9999,Immolation.buff,R2I(EnchantEffect.Get(EFFECT_IMMOLATION,u)),0)
endif
return "Aura enchantments level 2"
endif
endif
return ""
endfunction
function SelectPerk takes integer id, unit u returns nothing
local Perks p = Perks[GetUnitUserData(u)]
local string sw = ""
local integer level
if p.current == PERKS_ID[6] then
set sw = SetPerkBonus(id,u,6)
set level = 6
endif
if p.current == PERKS_ID[11] then
set sw = SetPerkBonus(id,u,11)
set level = 11
endif
if p.current == PERKS_ID[16] then
set sw = SetPerkBonus(id,u,16)
set level = 16
endif
if p.current == PERKS_ID[19] then
set sw = SetPerkBonus(id,u,19)
set level = 19
endif
if sw != "" then
call p.removePerkBook()
call BlzUnitDisableAbility(u,'AHer',false,false)
call UpdatePerkIcon(u,level,sw)
endif
endfunction
private function OnPerkSelect takes nothing returns nothing
call SelectPerk(GetSpellAbilityId(),GetTriggerUnit())
endfunction
public function Setup takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT,function OnPerkSelect)
set PERKS_ID[6] = 'A031'
set PERKS_ID[11] = 'A036'
set PERKS_ID[16] = 'A037'
set PERKS_ID[19] = 'A0AF'
endfunction
private function init takes nothing returns nothing
call PreloadGen.Add('A031',PRELOAD_SECOND)
call PreloadGen.Add('A036',PRELOAD_SECOND)
call PreloadGen.Add('A037',PRELOAD_SECOND)
call PreloadGen.Add('A0AF',PRELOAD_SECOND)
endfunction
endlibrary
library StandardBuffs initializer init uses MiscLibrary
struct Shield extends array
real life
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set life = I2R(b.int)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02H'
set BUFF_DATA.BuffID = 'B01A'
set BUFF_DATA.Name = "Shield"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SHIELD
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Restoration extends array
real hpRestore
real mpRestore
real time
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set time = time + 0.03125
if time == 1 then
set time = 0
if hpRestore != 0 then
call CodeDamage.Damage(b.target,b.target,hpRestore,udg_DamageTypeHeal,"",0,0)
endif
if mpRestore != 0 then
call UnitAddMp(b.target,mpRestore)
endif
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A026'
set BUFF_DATA.BuffID = 'B015'
set BUFF_DATA.Name = "Restoration"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
function AddUnitShield takes unit u, real hp, real duration, integer data returns nothing
local Shield b = UnitAddBuff(u,u,duration,Shield.buff,0,data).buffAllocIndex
set b.life = hp
endfunction
function AddUnitRestoration takes unit u, real hp, real mp, real duration returns nothing
local Restoration b = UnitAddBuff(u,u,duration,Restoration.buff,0,0).buffAllocIndex
set b.hpRestore = hp
set b.mpRestore = mp
set b.time = 0
endfunction
private function onPostDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Shield shield
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set shield = GetUnitBuff(data.target,Shield.buff).buffAllocIndex
if shield != 0 and not data.isAbsorbed then
set shield.life = shield.life - data.damageMod
if shield.life < 0 then
if shield.life <= -1 then
set data.damageMod = shield.life * -1
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
set shield.life = 0
call UnitRemoveBuff(data.target,Shield.buff)
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
endif
endif
endfunction
private function init takes nothing returns nothing
call Restoration.Initialize()
call Shield.Initialize()
call DamageEvent.RegisterPostCalculation(Filter(function onPostDmg))
call PreloadGen.Add('A026',PRELOAD_SECOND)
call PreloadGen.Add('A02H',PRELOAD_SECOND)
call PreloadGen.Add('A02W',PRELOAD_SECOND)
endfunction
endlibrary
library ChainSystem uses MiscLibrary
globals
private timer Timer = CreateTimer()
private trigger Core = CreateTrigger()
private group Group = CreateGroup()
private triggercondition array Cond
private LinkedList array Instances
private boolexpr array LoopCode
private integer Count = 0
endglobals
struct ChainCore extends array
private static method Loop takes nothing returns nothing
call TriggerEvaluate(Core)
endmethod
public static method Start takes integer id returns nothing
if Count == 0 then
call TimerStart(Timer,0.03125,true,function thistype.Loop)
endif
set Count = Count + 1
if Cond[id] == null then
set Cond[id] = TriggerAddCondition(Core,LoopCode[id])
endif
endmethod
public static method Stop takes integer id returns nothing
local LinkedList list = Instances[id]
set Count = Count - 1
if Count == 0 then
call PauseTimer(Timer)
endif
if list.size == 0 then
call TriggerRemoveCondition(Core,Cond[id])
set Cond[id] = null
endif
endmethod
public static method CreateLoopFunction takes integer id, code c returns nothing
set LoopCode[id] = Condition(c)
endmethod
endstruct
module ChainManager
private static method Loop takes nothing returns nothing
local LinkedList list = Instances[thistype.typeid]
local Link h = list.head
local Chain c
local Link next
local unit temp
local integer rc = 0
local player p
local real x
local real y
local unit random = null
loop
exitwhen h == 0
set c = h.data
set next = h.next
if c.update() then
if not c.isLight then
static if thistype.onHit.exists then
call thistype.onHit(c)
endif
endif
if c.isLight and c.bounces == 1 then
static if thistype.ConfigLightning.exists then
call thistype.ConfigLightning(c,c.caster)
endif
static if thistype.onHit.exists then
call thistype.onHit(c)
endif
else
set p = GetOwningPlayer(c.caster)
set c.lastHit = c.target
if c.jumpOnce then
call GroupAddUnit(c.units,c.target)
endif
call GroupClear(Group)
call GroupEnumUnitsInRange(Group,GetUnitX(c.target),GetUnitY(c.target),c.area,null)
loop
set temp = FirstOfGroup(Group)
exitwhen temp == null
call GroupRemoveUnit(Group,temp)
if thistype.FilterUnits(temp,p,c) and temp != c.target then
if c.jumpOnce then
if not IsUnitInGroup(temp,c.units) then
set rc = rc + 1
if GetRandomInt(1,rc) == 1 then
set random = temp
endif
endif
else
set rc = rc + 1
if GetRandomInt(1,rc) == 1 then
set random = temp
endif
endif
endif
endloop
set p = null
set c.target = random
set random = null
set rc = 0
if c.target != null then
if c.isLight then
static if thistype.ConfigLightning.exists then
call thistype.ConfigLightning(c,c.lastHit)
endif
static if thistype.onHit.exists then
call thistype.onHit(c)
endif
else
call c.dummy.destroy()
static if thistype.ConfigMissile.exists then
call thistype.ConfigMissile(c,c.lastHit)
endif
endif
endif
if c.bounces >= c.maxBounces or c.target == null then
static if thistype.onEnd.exists then
call thistype.onEnd(c)
endif
call list.remove(c.index)
call ChainCore.Stop(c.typeID)
call c.destroy()
endif
endif
else
static if thistype.onPeriod.exists then
call thistype.onPeriod(c)
endif
endif
set h = next
endloop
endmethod
public static method Fire takes Chain c returns nothing
local LinkedList list = Instances[thistype.typeid]
if c.jumpOnce then
set c.units = NewGroup()
endif
if c.isLight then
if c.delay < 0.25 then
set c.delay = 0.25
endif
set c.time = c.delay
else
static if thistype.ConfigMissile.exists then
call thistype.ConfigMissile(c,c.caster)
else
return
endif
endif
set c.index = list.add(c)
set c.typeID = thistype.typeid
call ChainCore.Start(thistype.typeid)
endmethod
private static method onInit takes nothing returns nothing
set Instances[thistype.typeid] = LinkedList.create()
call ChainCore.CreateLoopFunction(thistype.typeid,function thistype.Loop)
endmethod
endmodule
struct Chain extends array
implement Alloc
unit caster
unit target
real speed //si es missil
real delay //si es lightning
real area
real damage
integer data
integer maxBounces
boolean jumpOnce
boolean isLight
DummySFX dummy
Lightning light
integer bounces
unit lastHit
integer typeID
integer index
group units
real time //Contador para el lightning
LinkedList lightnings
real lightDuration
real lightFadeTime
public method update takes nothing returns boolean
local real angle
local real xm
local real ym
if isLight then
set time = time + 0.03125
if time >= delay then
set time = 0.00
set bounces = bounces + 1
return true
endif
else
set angle = AngleBetweenUnits(dummy.dummy,target)
set xm = GetUnitX(dummy.dummy) + speed * Cos(angle)
set ym = GetUnitY(dummy.dummy) + speed * Sin(angle)
call SetUnitX(dummy.dummy,xm)
call SetUnitY(dummy.dummy,ym)
call SetUnitFacing(dummy.dummy,angle * bj_RADTODEG)
if DistanceBetweenUnits(dummy.dummy,target) <= 15.0 then
set bounces = bounces + 1
return true
endif
endif
return false
endmethod
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set dummy = 0
set light = 0
set maxBounces = 0
set bounces = 0
set area = 0
set data = 0
set speed = 0
set isLight = false
set jumpOnce = false
set time = 0
return this
endmethod
public method destroy takes nothing returns nothing
local Link h
local Lightning l
if not isLight then
call dummy.destroy()
else
set h = lightnings.head
loop
exitwhen h == 0
set l = h.data
call l.setDuration(lightDuration,lightFadeTime)
set h = h.next
endloop
call lightnings.destroy()
endif
if jumpOnce then
call ReleaseGroup(units)
set units = null
endif
set target = null
set caster = null
set lastHit = null
call deallocate()
endmethod
endstruct
endlibrary
/*private static method ConfigLightning takes Chain c, unit origin returns nothing
//set c.light = Lightning.create("CLPB",origin,c.target,c.delay * (c.maxBounces - c.bounces),1.00)
endmethod*/
library HeroRevive initializer init uses TimerUtils, GameMultiboard
globals
private constant real REVIVE_BASE_TIME = 5.00
private constant real REVIVE_TIME_PER_100 = 0.35
private constant integer HERO_GOLD_BASE = 25
private constant integer HERO_GOLD_LEVEL = 5
private constant integer HERO_GOLD_KILL = 2
private trigger DeathTrigger
private timer Timer
MessageStyle MESSAGE_STYLE_KILL_HERO
Event EVENT_PLAYER_HERO_RESPAWN_END
Event EVENT_PLAYER_HERO_RESPAWN_START
RSound HeroKillSound = 0
unit RespawnedHero
endglobals
function IsHeroOnRespawn takes unit u returns boolean
return Respawn[GetUnitUserData(u)].timeLeft > 0
endfunction
function RegisterHeroRespawn takes unit hero returns nothing
call TriggerRegisterUnitEvent(DeathTrigger,hero,EVENT_UNIT_DEATH)
endfunction
function RegisterHeroRespawnEvent takes boolexpr b, Event e returns nothing
call e.register(b)
endfunction
struct Respawn extends array
real timeLeft
integer playerId
real xRespawn
real yRespawn
boolean RSReduction
integer multiboardInt
static thistype array INS
static integer COUNT = 0
private static method Loop takes nothing returns nothing
local integer i = 0
local unit u
local integer um
local thistype r
local LoadingBar lb
local Team t
loop
set r = INS[i]
set r.timeLeft = r.timeLeft - 1.00
set u = Index[r].u
call BlzFrameSetText(HeroesIconText[r.playerId - 2],I2S(R2I(r.timeLeft)))
if R2I(r.timeLeft) != r.multiboardInt then
set r.multiboardInt = R2I(r.timeLeft)
call MultiboardUpdateRespawn(GetOwningPlayer(u),r.multiboardInt)
endif
if r.timeLeft <= 0 then
if ReviveHero(u,r.xRespawn,r.yRespawn,true) then
call SetUnitFlyHeight(u,GetUnitDefaultFlyHeight(u),99999)
call SetCameraPositionForPlayer(GetOwningPlayer(u),r.xRespawn,r.yRespawn)
call SelectUnitForPlayer(u,GetOwningPlayer(u),true)
call BlzEndUnitAbilityCooldown(u,'A00A')
call SetUnitState(u,UNIT_STATE_MANA,GetUnitState(u,UNIT_STATE_MAX_MANA))
set RespawnedHero = u
call EVENT_PLAYER_HERO_RESPAWN_END.fire()
set t = GetUnitTeam(u)
set t.heroesDeath = t.heroesDeath - 1
set um = GetUnitData(u,"UnMorph")
if um != 0 then
call AddUnitAnimationProperties(u,"alternate",false)
call SetUnitData(u,"UnMorph",0)
call UnitAddAbility(u,um)
call UnitRemoveAbility(u,um)
call Upgrade.SetHeroTittle(u,GetHeroMasteryType(u))
endif
set lb = GetUnitData(u,"OHBar")
if lb != 0 then
call lb.show(true)
endif
endif
set INS[i] = INS[COUNT - 1]
set COUNT = COUNT - 1
set i = i - 1
call BlzFrameSetVisible(HeroesIconText[r.playerId - 2],false)
call BlzFrameSetTexture(HeroesIcon[r.playerId - 2],BlzGetAbilityIcon(GetUnitTypeId(u)),0,true)
endif
set i = i + 1
exitwhen i == COUNT
endloop
if COUNT == 0 then
call PauseTimer(Timer)
endif
set u = null
endmethod
public static method Add takes unit h, real t, real xr, real yr returns nothing
local thistype this = GetUnitUserData(h)
local Team te = GetUnitTeam(h)
local LoadingBar lb
local integer gcc = GetUnitData(h,"GrimCloackCounter")
if RSReduction then
set timeLeft = t + t * 0.25
else
set timeLeft = t
endif
set timeLeft = timeLeft - 2 * gcc
if timeLeft < 0 then
set timeLeft = 0
endif
set RSReduction = false
set xRespawn = xr
set yRespawn = yr
set playerId = GetPlayerId(GetOwningPlayer(h))
set multiboardInt = R2I(t)
set RespawnedHero = h
call EVENT_PLAYER_HERO_RESPAWN_START.fire()
call BlzFrameSetVisible(HeroesIconText[playerId - 2],true)
call BlzFrameSetText(HeroesIconText[playerId - 2],I2S(R2I(timeLeft)))
call BlzFrameSetTexture(HeroesIcon[playerId - 2],GetIconDisabledPath(BlzGetAbilityIcon(GetUnitTypeId(h))),0,true)
set INS[COUNT] = this
set COUNT = COUNT + 1
if COUNT == 1 then
call TimerStart(Timer,1.0,true,function thistype.Loop)
endif
set lb = GetUnitData(h,"OHBar")
if lb != 0 then
call lb.show(false)
endif
endmethod
endstruct
private function OnHeroDead takes nothing returns boolean
local unit u = GetTriggerUnit()
local player pd = GetTriggerPlayer()
local integer gt = GetPlayerState(pd,PLAYER_STATE_RESOURCE_GOLD)
local player pk = GetOwningPlayer(GetKillingUnit())
local integer lvl = GetHeroLevel(u)
local Players psk = Players[GetPlayerId(pk)]
local Players psd = Players[GetPlayerId(pd)]
local Team te = GetPlayerTeamEx(pd)
local Team tk = GetPlayerTeamEx(pk)
local LoadingBar lb
local integer g = 0
local integer g2 = 0
local integer sw = 0
local integer gz
local integer hz
local real x
local real y
local real t
call HeroKillSound.playForPlayer(0,0,0,150,pk)
if Game.Mode == GAME_MODE_LMS or Game.Mode == GAME_MODE_OD then
call CreateTextTagForPlayer(pk,GetUnitX(u),GetUnitY(u),"|c00ff0000Kill!|r",14)
set te.heroesIn = te.heroesIn - 1
call MultiboardUpdateKill(pk)
if pk != Game.PLAYER_NEUTRAL_HOSTILE then
if pk != pd then
set tk.kills = tk.kills + 1
set psk.kills = psk.kills + 1
set psk.tb.integer[GetPlayerId(pd)] = psk.tb.integer[GetPlayerId(pd)] + 1
set psk.heroesKilledTemp = psk.heroesKilledTemp + 1
call Message.Show(ARGB.fromPlayer(pk).str(GetPlayerName(pk))+" <kill> "+ARGB.fromPlayer(pd).str(GetPlayerName(pd)),MESSAGE_STYLE_KILL_HERO)
else
call Message.Show(ARGB.fromPlayer(pd).str(GetPlayerName(pd))+" has committed suicide",MESSAGE_STYLE_KILL_HERO)
endif
endif
set te.deaths = te.deaths + 1
set psd.deaths = psd.deaths + 1
set lb = GetUnitData(u,"OHBar")
if lb != 0 then
call lb.show(false)
endif
set u = null
set pk = null
set pd = null
return false
endif
set x = Distance(GetUnitX(u),GetUnitY(u),te.startX,te.startY)
set t = I2R(R2I(REVIVE_BASE_TIME + x / 100 * REVIVE_TIME_PER_100))
call Respawn.Add(u,t,te.startX,te.startY)
set te.heroesDeath = te.heroesDeath + 1
if pk == Game.PLAYER_NEUTRAL_HOSTILE then
call Message.Show("Neutral Hostile has slayed "+ARGB.fromPlayer(pd).str(GetPlayerName(pd)),MESSAGE_STYLE_KILL_HERO)
else
if pk != pd then
if tk.resources < te.resources then
set g2 = 100 + 10 * GetHeroLevel(GetPlayerHero(pd).hero)
else
set g2 = 50 + 5 * GetHeroLevel(GetPlayerHero(pd).hero)
endif
set g2 = g2 + 5 * psd.kills
set tk.kills = tk.kills + 1
call CreateTextTagForPlayer(pk,GetUnitX(u),GetUnitY(u),"|c00ff0000Kill|r(+"+GOLD_COLOR+I2S(g2)+"|r)",14)
call PlayerBounty[GetPlayerId(pk)].ExpBounty(u)
if pk != Game.PLAYER_WARCHIEF_HORDE and pk != Game.PLAYER_WARCHIEF_ALLIANCE then
call AddPlayersGold(tk,g2/2,false,pk)
call AddPlayerGold(pk,g2)
set psk.kills = psk.kills + 1
set psk.tb.integer[GetPlayerId(pd)] = psk.tb.integer[GetPlayerId(pd)] + 1
call MultiboardUpdateKill(pk)
call Message.Show(ARGB.fromPlayer(pk).str(GetPlayerName(pk))+" <kill> "+ARGB.fromPlayer(pd).str(GetPlayerName(pd))+" ["+GOLD_COLOR+I2S(g2)+"G|r]",MESSAGE_STYLE_KILL_HERO)
else
set g2 = g2 / 2
call AddPlayersGold(tk,g2,false,null)
call Message.Show(ARGB.fromPlayer(pk).str(GetPlayerName(pk))+" <kill> "+ARGB.fromPlayer(pd).str(GetPlayerName(pd))+" all team gets ["+GOLD_COLOR+I2S(g2)+"G|r]",MESSAGE_STYLE_KILL_HERO)
endif
else
call Message.Show(ARGB.fromPlayer(pd).str(GetPlayerName(pd))+" has committed suicide",MESSAGE_STYLE_KILL_HERO)
endif
endif
set te.deaths = te.deaths + 1
set psd.deaths = psd.deaths + 1
call MultiboardUpdateDeath(pd)
set u = null
set pk = null
set pd = null
return false
endfunction
private function init takes nothing returns nothing
set DeathTrigger = CreateTrigger()
set Timer = NewTimer()
call TriggerAddCondition(DeathTrigger,Condition(function OnHeroDead))
set EVENT_PLAYER_HERO_RESPAWN_START = Event.create()
set EVENT_PLAYER_HERO_RESPAWN_END = Event.create()
set MESSAGE_STYLE_KILL_HERO = MessageStyle.create("",0,0,8,null,"","")
set HeroKillSound = RSound.create("Sound\\Interface\\GoodJob.flac", false, true, 12700, 12700)
endfunction
endlibrary
library BountyExp uses Event, MiscLibrary, PlayerLib
globals
private constant integer EXP_BASE_UNITS = 30
private constant integer EXP_LVL_UNITS = 5
private constant integer GOLD_BASE_CREEPS = 12
private constant integer GOLD_LVL_CREEPS = 2
private constant integer GOLD_VAR_CREEPS = 2
private constant integer GOLD_BASE_NEUTRAL = 20
private constant integer GOLD_LVL_NEUTRAL = 10
private constant integer GOLD_VAR_NEUTRAL = 10
private constant real SHARE_AREA = 1500
private constant real SHARE_AREA_N = 750
constant string GOLD_COLOR = "|cffffd700"
constant string EXP_COLOR = "|c0080a3e3"
constant string HONOR_COLOR = "|cff9acd32"
constant string RESOURCE_COLOR = "|c00ff8000"
private constant integer FIXED_EXP_ABI = 'A000'
endglobals
function AddPlayerExpPercentCreeps takes player p, integer pe returns nothing
set PlayerBounty[GetPlayerId(p)].expPercentCreeps = PlayerBounty[GetPlayerId(p)].expPercentCreeps + pe
endfunction
function AddPlayerBountyPercentCreeps takes player p, integer pe returns nothing
set PlayerBounty[GetPlayerId(p)].bountyPercentCreeps = PlayerBounty[GetPlayerId(p)].bountyPercentCreeps + pe
endfunction
function AddPlayerBountyPercent takes player p, integer pe returns nothing
set PlayerBounty[GetPlayerId(p)].bountyPercent = PlayerBounty[GetPlayerId(p)].bountyPercent + pe
endfunction
function AddPlayerExpPercent takes player p, integer pe returns nothing
set PlayerBounty[GetPlayerId(p)].expPercent = PlayerBounty[GetPlayerId(p)].expPercent + pe
endfunction
function PauseBounty takes player p, boolean flag returns nothing
set PlayerBounty[GetPlayerId(p)].bountyOn = flag
endfunction
function PauseExp takes player p, boolean flag returns nothing
set PlayerBounty[GetPlayerId(p)].expOn = flag
endfunction
struct PlayerBounty extends array
integer bountyPercent
integer expPercent
integer bountyPercentCreeps
integer expPercentCreeps
boolean expOn
boolean bountyOn
public method ExpBounty takes unit kill returns integer
local integer pexp = 0
local integer exp = 0
local integer i
local integer j
local player p = Player(this)
local Team t = GetPlayerTeamEx(p)
local real shareRange
local Hero th
local real x = GetUnitX(kill)
local real y = GetUnitY(kill)
if t == 1 then
set i = 2
set j = 6
elseif t == 2 then
set i = 7
set j = 11
endif
if IsUnitType(kill,UNIT_TYPE_HERO) then
set th = Players[this].hero
if GetHeroLevel(th.hero) < GetHeroLevel(kill) then
set exp = 50 + 20 * GetHeroLevel(kill)
else
set exp = 50 + 10 * GetHeroLevel(kill)
endif
set pexp = exp * expPercent / 100
else
set exp = EXP_BASE_UNITS + EXP_LVL_UNITS * GetUnitLevel(kill)
set Players[this].creepsE = Players[this].creepsE + 1
set pexp = exp * expPercentCreeps / 100
endif
if GetOwningPlayer(kill) == Game.PLAYER_NEUTRAL_HOSTILE then
set shareRange = SHARE_AREA_N
set Players[this].creepsN = Players[this].creepsN + 1
else
set shareRange = SHARE_AREA
endif
loop
if i != this and Players[i].isPlaying then
set th = GetPlayerHero(Player(i))
if Distance(GetUnitX(th.hero),GetUnitY(th.hero),x,y) <= shareRange then
call PlayerBounty[i].ExpBountyFixed(exp)
endif
endif
set i = i + 1
exitwhen i > j
endloop
set p = null
return ExpBountyFixed(pexp)
endmethod
public method ExpBountyFixed takes integer amount returns integer
local Hero h = GetPlayerHero(Player(this))
if UnitAlive(h.hero) and expOn and GetHeroLevel(h.hero) < 20 and amount != 0 then
call AddHeroXP(h.hero,amount,true)
return amount
endif
return 0
endmethod
public method GoldBounty takes unit kill, integer bonus returns integer
local player p = Player(this)
local Team t = GetPlayerTeamEx(p)
local real x = GetUnitX(kill)
local real y = GetUnitY(kill)
local Hero th
local integer r
local integer i
local integer j
local real shareRange
if t == 1 then
set i = 2
set j = 6
elseif t == 2 then
set i = 7
set j = 11
endif
if GetOwningPlayer(kill) == Game.PLAYER_NEUTRAL_HOSTILE then
set r = GOLD_BASE_NEUTRAL + GOLD_LVL_NEUTRAL * GetUnitLevel(kill)
set r = r + GetRandomInt(-GOLD_VAR_NEUTRAL,GOLD_VAR_NEUTRAL) + bonus
set shareRange = SHARE_AREA_N
else
set r = GOLD_BASE_CREEPS + GOLD_LVL_CREEPS * GetUnitLevel(kill)
set r = r + GetRandomInt(-GOLD_VAR_CREEPS,GOLD_VAR_CREEPS) + bonus
set shareRange = SHARE_AREA
endif
loop
if i != this and Players[i].isPlaying then
set th = GetPlayerHero(Player(i))
if Distance(GetUnitX(th.hero),GetUnitY(th.hero),x,y) <= shareRange and UnitAlive(th.hero) then
call PlayerBounty[i].GoldBountyFixed(x,y,GetRandomInt(3,5))
endif
endif
set i = i + 1
exitwhen i > j
endloop
set p = null
if IsUnitType(kill,UNIT_TYPE_HERO) then
set r = r * bountyPercent / 100
else
set r = r * bountyPercentCreeps / 100
endif
return GoldBountyFixed(x,y,r)
endmethod
public method GoldBountyFixed takes real x, real y, integer amount returns integer
if bountyOn and amount != 0 then
call AddPlayerGold(Player(this),amount)
call CreateTextTagBounty(Player(this),x,y,GOLD_COLOR + "+"+I2S(amount)+"|r",12.00)
return amount
endif
return 0
endmethod
public static method Init takes integer p returns nothing
local thistype this = thistype(p)
set .bountyPercent = 100
set .expPercent = 100
set .bountyPercentCreeps = 100
set .expPercentCreeps = 100
set .bountyOn = true
set .expOn = true
endmethod
endstruct
private function onDeath takes nothing returns nothing
local unit u
local player pk
if GetKillingUnit() != null then
set u = GetTriggerUnit()
set pk = GetOwningPlayer(GetKillingUnit())
if GetUnitUserData(u) != 0 then
if pk != Game.PLAYER_NEUTRAL_HOSTILE and not IsUnitType(u,UNIT_TYPE_HERO) and GetUnitAbilityLevel(u,'A0AM') == 0 then
call PlayerBounty[GetPlayerId(pk)].GoldBounty(u,0)
call PlayerBounty[GetPlayerId(pk)].ExpBounty(u)
endif
endif
set u = null
set pk = null
endif
endfunction
public function Setup takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function onDeath)
call PauseBounty(Game.PLAYER_WARCHIEF_HORDE,false)
call PauseBounty(Game.PLAYER_WARCHIEF_ALLIANCE,false)
endfunction
endlibrary
library Hostile requires Table, UnitRecycler , NewGroup, InCombat, LinkedList, GoldMine, Item
globals
private constant real RESPAWN_TIME_NORMAL = 40.
private constant real RESPAWN_TIME_HARD = 60.
private constant integer CAMP_TYPE_NORMAL = 1
private constant integer CAMP_TYPE_SPECIAL = 2
private constant integer LEVEL_NORMAL = 1
private constant integer LEVEL_HARD = 2
private constant real MAX_PULL_RANGE = 1400
endglobals
struct HData extends array
private static Table array HT[6]
private static HostileCamp array CAMPS[20]
private static integer CampsCount = 0
public static method GetRandomList takes integer lvl, integer Type returns integer
local integer min = 1 + 50 * (Type - 1)
local integer max = min + HT[2 + lvl][Type] - 1
local integer r = GetRandomInt(min,max)
return HT[lvl - 1][r]
endmethod
public static method RegisterList takes LinkedList l, integer Type, integer lvl returns nothing
local integer pos = 0
local integer c = HT[2 + lvl][Type]
set HT[2 + lvl][Type] = c + 1
set pos = 50 * Type - (50 - (c + 1))
set HT[lvl - 1][pos] = l
endmethod
public static method RegisterCamp takes HostileCamp c returns nothing
set CAMPS[CampsCount] = c
set CampsCount = CampsCount + 1
endmethod
public static method GetCampByUnit takes unit u returns HostileCamp
local integer i = 0
loop
if CAMPS[i].isUnitInCamp(u) then
return CAMPS[i]
endif
set i = i + 1
exitwhen i == CampsCount
endloop
return 0
endmethod
public static method CreateAllHostile takes nothing returns nothing
local integer i = 0
loop
exitwhen i == CampsCount
if CAMPS[i].data == 0 then
call CAMPS[i].createHostile()
endif
set i = i + 1
endloop
endmethod
public static method Init takes nothing returns nothing
set HT[0] = Table.create()
set HT[1] = Table.create()
set HT[2] = Table.create()
set HT[3] = Table.create()
set HT[4] = Table.create()
set HT[5] = Table.create()
endmethod
endstruct
private function AddUnitToList takes LinkedList l, integer unitid, integer count returns nothing
loop
exitwhen count == 0
set count = count - 1
call l.add(unitid)
endloop
endfunction
private function SetHostileDatas takes nothing returns nothing
local LinkedList list
local HostileCamp camp
//NORMAL GROUPS
set list = LinkedList.create()
call AddUnitToList(list,'nsgt',2)
call AddUnitToList(list,'nsbm',1)
call HData.RegisterList(list,CAMP_TYPE_NORMAL,LEVEL_NORMAL)
set list = LinkedList.create()
call AddUnitToList(list,'nwlg',2)
call AddUnitToList(list,'nwld',1)
call HData.RegisterList(list,CAMP_TYPE_NORMAL,LEVEL_NORMAL)
set list = LinkedList.create()
call AddUnitToList(list,'nstl',2)
call AddUnitToList(list,'nsth',1)
call HData.RegisterList(list,CAMP_TYPE_NORMAL,LEVEL_NORMAL)
set list = LinkedList.create()
call AddUnitToList(list,'nftb',2)
call AddUnitToList(list,'nftk',1)
call HData.RegisterList(list,CAMP_TYPE_NORMAL,LEVEL_NORMAL)
set list = LinkedList.create()
call AddUnitToList(list,'ntrs',2)
call AddUnitToList(list,'ntrt',1)
call HData.RegisterList(list,CAMP_TYPE_NORMAL,LEVEL_NORMAL)
set list = LinkedList.create()
call AddUnitToList(list,'nmtw',2)
call AddUnitToList(list,'nmrv',1)
call HData.RegisterList(list,CAMP_TYPE_NORMAL,LEVEL_NORMAL)
set list = LinkedList.create()
call AddUnitToList(list,'nltc',2)
call AddUnitToList(list,'nlds',1)
call HData.RegisterList(list,CAMP_TYPE_NORMAL,LEVEL_NORMAL)
set list = LinkedList.create()
call AddUnitToList(list,'nrel',2)
call AddUnitToList(list,'nsel',1)
call HData.RegisterList(list,CAMP_TYPE_NORMAL,LEVEL_NORMAL)
//SPECIAL GROUPS
set list = LinkedList.create()
call AddUnitToList(list,'nggr',1)
call HData.RegisterList(list,CAMP_TYPE_SPECIAL,LEVEL_HARD)
set list = LinkedList.create()
call AddUnitToList(list,'nstw',1)
call HData.RegisterList(list,CAMP_TYPE_SPECIAL,LEVEL_HARD)
set list = LinkedList.create()
call AddUnitToList(list,'nowk',1)
call HData.RegisterList(list,CAMP_TYPE_SPECIAL,LEVEL_HARD)
set list = LinkedList.create()
call AddUnitToList(list,'nsqa',1)
call HData.RegisterList(list,CAMP_TYPE_SPECIAL,LEVEL_HARD)
//CAMPS NORMAL
set camp = HostileCamp.create(gg_rct_CreepCamp1,LEVEL_NORMAL,CAMP_TYPE_NORMAL,225)
call HData.RegisterCamp(camp)
set camp = HostileCamp.create(gg_rct_CreepCamp2,LEVEL_NORMAL,CAMP_TYPE_NORMAL,90)
call HData.RegisterCamp(camp)
set camp = HostileCamp.create(gg_rct_CreepCamp3,LEVEL_NORMAL,CAMP_TYPE_NORMAL,225)
call HData.RegisterCamp(camp)
set camp = HostileCamp.create(gg_rct_CreepCamp4,LEVEL_NORMAL,CAMP_TYPE_NORMAL,45)
call HData.RegisterCamp(camp)
set camp = HostileCamp.create(gg_rct_CreepCamp5,LEVEL_NORMAL,CAMP_TYPE_NORMAL,270)
call HData.RegisterCamp(camp)
set camp = HostileCamp.create(gg_rct_CreepCamp6,LEVEL_NORMAL,CAMP_TYPE_NORMAL,45)
call HData.RegisterCamp(camp)
//CAMPS SPECIAL
set camp = HostileCamp.create(gg_rct_CreepCampExtraD,LEVEL_HARD,CAMP_TYPE_SPECIAL,45)
call HData.RegisterCamp(camp)
set camp = HostileCamp.create(gg_rct_CreepCampExtraU,LEVEL_HARD,CAMP_TYPE_SPECIAL,225)
call HData.RegisterCamp(camp)
endfunction
struct HostileCamp
real x
real y
integer createdUnits
integer actualUnits
integer combatUnits
integer data
integer level
integer neutralType
real angle
boolean passive
Table units
LinkedList neutralList
effect clock
minimapicon iconHard
public method isPassive takes nothing returns boolean
return passive
endmethod
public method exist takes nothing returns boolean
return actualUnits > 0
endmethod
public method isUnitInCamp takes unit u returns boolean
return units[GetUnitUserData(u) + 20] != 0
endmethod
public method removeUnit takes unit u returns boolean
set units[units[GetUnitUserData(u) + 20]] = 0
set units[GetUnitUserData(u) + 20] = 0
set actualUnits = actualUnits - 1
return true
endmethod
private static method onRespawn takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
if not exist() then
call createHostile()
endif
call DestroyEffect(clock)
call ReleaseTimer(t)
set t = null
endmethod
public method makePassive takes nothing returns nothing
local integer i = 0
local unit temp
loop
exitwhen i == createdUnits
set i = i + 1
if units[i] != 0 then
set temp = Index[units[i]].u
call UnitAddAbility(temp,'A00G')
call UnitAddAbility(temp,'Abun')
call UnitAddAbility(temp,'Arel')
call UnitAddAbility(temp,Game.FLAG_NO_AGGRO)
call IssuePointOrder(temp,"move",x,y)
endif
endloop
set passive = true
set temp = null
endmethod
public method makeHostile takes real x, real y returns nothing
local unit temp
local integer i = 0
if passive then
set combatUnits = 0
endif
loop
exitwhen i == createdUnits
set i = i + 1
if units[i] != 0 then
set temp = Index[units[i]].u
if passive then
call Status.Remove(STATUS_SLEEP,temp)
call UnitRemoveAbility(temp,'A00G')
call UnitRemoveAbility(temp,'Abun')
call UnitRemoveAbility(temp,'Arel')
call UnitRemoveAbility(temp,Game.FLAG_NO_AGGRO)
call IssuePointOrder(temp,"attack",x,y)
call EnterUnitCombat(temp,null,0)
set combatUnits = combatUnits + 1
endif
endif
endloop
set passive = false
set temp = null
endmethod
public method checkRespawn takes nothing returns boolean
local timer t
local real rt = 0
if actualUnits == 0 then
set t = NewTimerEx(this)
if level == LEVEL_NORMAL then
set rt = RESPAWN_TIME_NORMAL
elseif level == LEVEL_HARD then
set rt = RESPAWN_TIME_HARD
endif
if level == LEVEL_HARD then
call DestroyMinimapIcon(iconHard)
set iconHard = null
endif
call units.flush()
set clock = AddSpecialEffect("war3mapImported\\ClockRune.mdx",x,y)
call BlzSetSpecialEffectTime(clock,0)
call BlzSetSpecialEffectTimeScale(clock,10.00/rt)
call BlzSetSpecialEffectHeight(clock,GetLocZ(x,y) + 30)
call BlzSetSpecialEffectYaw(clock,270 * bj_DEGTORAD)
call TimerStart(t, rt, false, function thistype.onRespawn)
set t = null
return true
endif
return false
endmethod
public method createHostile takes nothing returns nothing
local unit u
local real xc
local real yc
local Link temp
//local real a = angle - 25
set neutralList = HData.GetRandomList(level,neutralType)
set temp = neutralList.head
set createdUnits = 0
loop
exitwhen temp == 0
set xc = x
set yc = y
set u = GetRecycledUnit(Game.PLAYER_NEUTRAL_HOSTILE,temp.data,xc,yc,angle)
call UnitAddAbility(u,'A00G')
call UnitAddAbility(u,'Abun')
call UnitAddAbility(u,Game.FLAG_NO_AGGRO)
call Status.Add(STATUS_SLEEP,u,0.00,0)
set createdUnits = createdUnits + 1
set units[createdUnits] = GetUnitUserData(u)
set units[GetUnitUserData(u) + 20] = createdUnits
set temp = temp.next
endloop
set actualUnits = createdUnits
set passive = true
if level == LEVEL_HARD then
set iconHard = CreateMinimapIcon(x,y, 255, 0, 0, "UI\\Minimap\\MiniMap-CreepLoc-Large.mdl", FOG_OF_WAR_MASKED )
endif
set u = null
endmethod
public static method create takes rect reg, integer lvl, integer Type, real a returns thistype
local thistype this = thistype.allocate()
set x = GetRectCenterX(reg)
set y = GetRectCenterY(reg)
call RemoveRect(reg)
set level = lvl
set neutralType = Type
set neutralList = 0
set angle = a
set units = Table.create()
set createdUnits = 0
set actualUnits = 0
set combatUnits = 0
set passive = false
return this
endmethod
endstruct
private function OnDeath takes nothing returns nothing
local unit u = GetTriggerUnit()
local HostileCamp c
local Item it
if not IsUnitType(u,UNIT_TYPE_SUMMONED) then
set c = HData.GetCampByUnit(u)
call c.removeUnit(u)
set c.combatUnits = c.combatUnits - 1
if c.checkRespawn() then
if c.neutralType == CAMP_TYPE_NORMAL then
call Rune.create('rdis',c.x,c.y,null)
endif
if c.neutralType == CAMP_TYPE_SPECIAL then
call Rune.create('rma2',c.x,c.y,null)
endif
endif
endif
set u = null
endfunction
private function OnDamage takes nothing returns boolean
local DamageData d = DamageEvent.EventData
local HostileCamp c
local real d1
local real d2
local unit h = null
if GetOwningPlayer(d.target) == Game.PLAYER_NEUTRAL_HOSTILE then
set h = d.target
elseif GetOwningPlayer(d.source) == Game.PLAYER_NEUTRAL_HOSTILE then
set h = d.source
endif
if h != null then
set c = HData.GetCampByUnit(h)
if c != 0 then
set d1 = Distance(GetUnitX(d.target),GetUnitY(d.target),c.x,c.y)
set d2 = Distance(GetUnitX(d.source),GetUnitY(d.source),c.x,c.y)
if d2 > MAX_PULL_RANGE or d1 > MAX_PULL_RANGE then
call c.makePassive()
else
if h != d.source then
if UnitAlive(d.source) then
if IsUnitVisible(d.source,Game.PLAYER_NEUTRAL_HOSTILE) then
call c.makeHostile(GetUnitX(d.source),GetUnitY(d.source))
endif
endif
endif
endif
endif
set h = null
endif
return false
endfunction
private function OnLeaveCombat takes nothing returns boolean
local unit u = GetEventCombatLeaveUnit()
local HostileCamp c
if GetOwningPlayer(u) == Game.PLAYER_NEUTRAL_HOSTILE and UnitAlive(u) and not IsUnitType(u,UNIT_TYPE_STRUCTURE) then
set c = HData.GetCampByUnit(u)
set c.combatUnits = c.combatUnits - 1
if c.combatUnits == 0 then
call c.makePassive()
endif
endif
set u = null
return false
endfunction
public function Setup takes nothing returns nothing
call RegisterPlayerUnitEventForPlayer(EVENT_PLAYER_UNIT_DEATH,function OnDeath,Game.PLAYER_NEUTRAL_HOSTILE)
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call RegisterCombatEvent(function OnLeaveCombat,EVENT_UNIT_LEAVE_COMBAT)
call HData.Init()
call SetHostileDatas()
call HData.CreateAllHostile()
endfunction
endlibrary
scope NeutralHostileSpells initializer Init
globals
private Effect WEB_SFX
endglobals
struct EnvenomedWeapons extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,15,0,true)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,10.0,udg_DamageTypeMagicOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-0.15,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-15,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CO'
set BUFF_DATA.BuffID = 'B05L'
set BUFF_DATA.Name = "Envenomed Weapon"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Roar extends array
integer dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if IsUnitType(b.target,UNIT_TYPE_HERO) then
set dmg = 30
else
set dmg = 15
endif
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0C6'
set BUFF_DATA.BuffID = 'B05K'
set BUFF_DATA.Name = "Roar"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.PierceImmune = false
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function OnDummyDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
if GetUnitAbilityLevel(d.source,'ACtb') != 0 then
call CodeDamage.Damage(d.source,d.target,d.damageMod,udg_DamageTypeMagic,"",0,0)
call Status.Add(STATUS_STUN,d.target,1.2,Status_EFFECT[STATUS_STUN])
endif
if GetUnitAbilityLevel(d.source,'ACcl') != 0 then
call CodeDamage.Damage(d.source,d.target,d.damageMod,udg_DamageTypeMagicAoe,"",0,0)
endif
if GetUnitAbilityLevel(d.source,'Ambd') != 0 then
call CodeDamage.Damage(d.source,d.target,d.damageMod,udg_DamageTypeMagic,"",0,0)
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
local real bonus
if d.dmgType == udg_DamageTypeAttack then
if GetUnitAbilityLevel(d.source,'ACbh') != 0 then
if GetRandomInt(1,100) <= 15 then
set d.add = d.add + 50.00
call Status.Add(STATUS_STUN,d.target,1.5,Status_EFFECT[STATUS_STUN])
endif
endif
if GetUnitAbilityLevel(d.source,'ANbh') != 0 then
set bonus = BlzGetAbilityRealLevelField(BlzGetUnitAbility(d.source,'ANbh'),ABILITY_RLF_DAMAGE_BONUS_HBH3,0)
set d.add = d.add + bonus
call BlzSetAbilityRealLevelField(BlzGetUnitAbility(d.source,'ANbh'),ABILITY_RLF_DAMAGE_BONUS_HBH3,0,bonus + 7.0)
endif
endif
endfunction
private function OnDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
if d.dmgType == udg_DamageTypeAttack and not d.isMiss then
if GetUnitAbilityLevel(d.source,'A0CN') != 0 then
call UnitAddBuff(d.target,d.source,5.0,EnvenomedWeapons.buff,0,0)
endif
endif
endfunction
private function OnLeaveCombat takes nothing returns nothing
local unit u = GetEventCombatLeaveUnit()
if GetUnitAbilityLevel(u,'ANbh') != 0 then
call BlzSetAbilityRealLevelField(BlzGetUnitAbility(u,'ANbh'),ABILITY_RLF_DAMAGE_BONUS_HBH3,0,7.0)
endif
set u = null
endfunction
struct WebMissile extends array
private static method onFinish takes Missile missile returns boolean
if not TriggerSpellNegation(missile.target) then
call Status.Add(STATUS_ENSNARE,missile.target,2.0,WEB_SFX)
endif
if TriggerSpellReflection(missile.target) then
call SetupWebMissile.evaluate(missile.target,missile.source)
endif
return true
endmethod
implement MissileStruct
endstruct
function SetupWebMissile takes unit source, unit target returns nothing
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 45
set missile.model = "Abilities\\Spells\\Undead\\Web\\Webmissile.mdl"
set missile.scale = 1.00
call WebMissile.launch(missile)
endfunction
private function WebCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local group g = NewGroup()
local unit temp
local player p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,x,y,230.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call SetupWebMissile(u,temp)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set u = null
endfunction
private function RoarCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local group g = NewGroup()
local unit temp
local player p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),500.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ALLIED(temp,p) then
call UnitAddBuff(temp,u,10.0,Roar.buff,0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set u = null
endfunction
private function Init takes nothing returns nothing
call DamageEvent.RegisterDummyDamage(Filter(function OnDummyDamage))
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call RegisterSpellEffectEvent('ACro', function RoarCast)
call RegisterSpellEffectEvent('A0CM', function WebCast)
call RegisterCombatEvent(function OnLeaveCombat,EVENT_UNIT_LEAVE_COMBAT)
call Roar.Initialize()
call EnvenomedWeapons.Initialize()
set WEB_SFX = Effect.create("Abilities\\Spells\\Undead\\Web\\WebTarget.mdl","origin")
endfunction
endscope
library InCombat uses CTL, LinkedList, Event, MiscLibrary
globals
private constant real COMBAT_TIME = 4.0
private constant integer PREVENT_COMBAT_ID = 'A00F'
public real array CombatTime
private unit EnterUnit
private unit LeaveUnit
private unit SourceUnit
private integer EnterObject
private integer LeaveObject
Event EVENT_UNIT_LEAVE_COMBAT
Event EVENT_UNIT_ENTER_COMBAT
endglobals
module m
public static method onInit takes nothing returns nothing
set EVENT_UNIT_LEAVE_COMBAT = Event.create()
set EVENT_UNIT_ENTER_COMBAT = Event.create()
endmethod
endmodule
function GetEventCombatEnterID takes nothing returns integer
return EnterObject
endfunction
function GetEventCombatLeaveID takes nothing returns integer
return LeaveObject
endfunction
function GetEventCombatEnterUnit takes nothing returns unit
return EnterUnit
endfunction
function GetEventCombatLeaveUnit takes nothing returns unit
return LeaveUnit
endfunction
function GetEventCombatSourceUnit takes nothing returns unit
return SourceUnit
endfunction
function RegisterCombatEvent takes code c, Event e returns nothing
call e.register(Filter(c))
endfunction
private struct CombatData extends array
implement m
endstruct
function IsUnitInCombat takes unit u returns boolean
return CombatTime[GetUnitUserData(u)] > 0
endfunction
function EnterUnitCombat takes unit u, unit s, integer o returns nothing
call InCombat.EnterCombat(u,s,o)
endfunction
function LeaveUnitCombat takes unit u, integer o returns nothing
call InCombat.LeaveCombat(u,o)
endfunction
struct InCombat extends array
static LinkedList DATA
static timer T
private static method periodic takes nothing returns nothing
local Link temp
local Link r
local integer sw
local Item it = 0
local integer c
set temp = thistype.DATA.head
loop
exitwhen temp == 0
set sw = 0
set it = 0
set r = 0
if not UnitAlive(Index[temp.data].u) then
set sw = 1
call LeaveCombat(Index[temp.data].u,-1)
else
if IsUnitType(Index[temp.data].u,UNIT_TYPE_HERO) then
set it = GetUnitItemOfType.evaluate(Index[temp.data].u,'will')
if it != 0 then
set c = GetItemCharges(it.itemS) + 1
if c <= 30 then
call SetItemCharges(it.itemS,c)
endif
endif
endif
set CombatTime[temp.data] = CombatTime[temp.data] - 1
if CombatTime[temp.data] <= 0 then
set sw = 1
call LeaveCombat(Index[temp.data].u,0)
endif
endif
if sw == 1 then
set r = temp.next
call DATA.remove(temp)
set temp = r
else
set temp = temp.next
endif
endloop
if DATA.size == 0 then
call PauseTimer(T)
endif
endmethod
private static method StartPeriodic takes nothing returns nothing
if DATA.size == 1 then
call TimerStart(T,1.0,true,function thistype.periodic)
endif
endmethod
public static method LeaveCombat takes unit u , integer objectID returns nothing
set CombatTime[GetUnitUserData(u)] = 0
call CreateTextTagBounty(GetOwningPlayer(u),GetUnitX(u),GetUnitY(u),"Leave Combat",9.00)
call SetUnitAbilityLevel(u,'A00A',2)
set LeaveUnit = u
set LeaveObject = objectID
call EVENT_UNIT_LEAVE_COMBAT.fire()
set LeaveUnit = null
set LeaveObject = 0
endmethod
public static method EnterCombat takes unit u, unit source, integer objectID returns nothing
local integer id = GetUnitUserData(u)
if id != 0 and not IsUnitIllusion(u) then
if CombatTime[id] == 0 then
call DATA.add(GetUnitUserData(u))
if GetUnitTypeId(u) == 'Owc1' or GetUnitTypeId(u) == 'Awc1' then
set CombatTime[id] = 3
else
set CombatTime[id] = COMBAT_TIME
endif
call CreateTextTagBounty(GetOwningPlayer(u),GetUnitX(u),GetUnitY(u),"Enter Combat",9.00)
call SetUnitAbilityLevel(u,'A00A',1)
set EnterUnit = u
set SourceUnit = source
set EnterObject = objectID
call EVENT_UNIT_ENTER_COMBAT.fire()
set EnterUnit = null
set SourceUnit = null
set EnterObject = 0
call StartPeriodic()
else
set CombatTime[id] = COMBAT_TIME
endif
endif
endmethod
endstruct
private function OnDamage takes nothing returns boolean
local DamageData d = DamageEvent.EventData
local unit source = d.source
local unit target = d.target
if GetUnitAbilityLevel(source,PREVENT_COMBAT_ID) == 0 and UnitAlive(source) then
if d.dmgType == udg_DamageTypeHeal or d.dmgType == udg_DamageTypeHealOverTime then
if IsUnitInCombat(target) and target != source then
call EnterUnitCombat(source,source,0)
endif
else
if target != source then
call EnterUnitCombat(source,source,0)
call EnterUnitCombat(target,source,0)
endif
endif
endif
set source = null
set target = null
return false
endfunction
private function OnSpellCast takes nothing returns boolean
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetSpellAbilityId()
if id != 'A00A' and GetUnitAbilityLevel(u,PREVENT_COMBAT_ID) == 0 then
if t != null then
if IsUnitAlly(t,GetTriggerPlayer()) then
if IsUnitInCombat(t) then
call EnterUnitCombat(u,u,GetSpellAbilityId())
endif
else
call EnterUnitCombat(u,u,GetSpellAbilityId())
call EnterUnitCombat(t,u,GetSpellAbilityId())
endif
endif
endif
set u = null
set t = null
return false
endfunction
public function Setup takes nothing returns nothing
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT,function OnSpellCast)
set InCombat.DATA = LinkedList.create()
set InCombat.T = CreateTimer()
endfunction
endlibrary
library GameLoop uses MiscLibrary, GuardPath, WarTroops
globals
private integer FirstObeliskTime = 600
private integer LEVEL_UPGRADE = 0
private integer LEVEL_UPGRADE_NEUTRAL = 0
private timer INCOME_HORDE
private timer INCOME_ALLIANCE
endglobals
private function PingCD takes nothing returns nothing
local integer i = 2
loop
if Players[i].isPlaying then
if Players[i].AIPing_CD > 0 then
set Players[i].AIPing_CD = Players[i].AIPing_CD - 1
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
endfunction
struct GameLoop extends array
public static integer Minutes = 0
public static integer Seconds = 0
private static minimapicon mi1
private static minimapicon mi2
private static method Loop takes nothing returns nothing
local boolean minute = false
call PingCD()
if not Game.GameOver then
set Seconds = Seconds + 1
call BlzFrameClearAllPoints(mult1)
call BlzFrameSetAbsPoint(mult1, FRAMEPOINT_TOPRIGHT, 0.80,0.58)
call BlzFrameClearAllPoints(mult2)
call BlzFrameSetAbsPoint(mult2, FRAMEPOINT_TOPRIGHT, 0.80,0.58)
if Seconds == 60 then
set Seconds = 0
set Minutes = Minutes + 1
set minute = true
endif
if Game.PickDuration > 0 then
set Game.PickDuration = Game.PickDuration - 1
call HeroSelectorSetTitleText("Pick a Hero: "+I2S(Game.PickDuration))
else
if not Game.GameStarted then
set Game.TIME_TO_INIT_GAME = Game.TIME_TO_INIT_GAME - 1
call GameButtons_ChangeBigMessageText.evaluate(R2I(Game.TIME_TO_INIT_GAME))
if Game.TIME_TO_INIT_GAME == 0 then
call GameButtons_ChangeBigMessageText.evaluate(0)
endif
endif
endif
if Game.GameStarted then
if Game.Mode == GAME_MODE_NORMAL then
call Team[1].setIncome()
call Team[2].setIncome()
call GoldMine.GiveResources()
if minute then
call Runes_UpdateRunesDescription.evaluate()
call Team[1].commander.UpdateStats()
call Team[2].commander.UpdateStats()
call Commander.UpdateAbilities()
//
call WarHall_UpdateAbilities.evaluate()
endif
call Base.UpgradeLoop()
if not Game.CreepsSpawned then
if Base[1].owner != 0 and Base[2].owner != 0 and Base[3].owner != 0 and Base[4].owner != 0 then
set Game.CreepsSpawned = true
call WarTroops_UpdateTeamSpawnTime(Team[1])
call WarTroops_UpdateTeamSpawnTime(Team[2])
call CreateWaves(Team[1])
call CreateWaves(Team[2])
call WarTroops_Start()
endif
endif
if AncientObelisk.enabled then
if AncientObelisk.owner != 0 then
set AncientObelisk.timeC = AncientObelisk.timeC + 1
call SetUnitState(AncientObelisk.obelisk,UNIT_STATE_MANA,180 - AncientObelisk.timeC)
if AncientObelisk.timeC == 180 then
set AncientObelisk.timeP = 0
call Message.Show("The Ancient Obelisk is available.",MESSAGE_STYLE_INFO)
call AncientObelisk.ChangeOwner(true)
endif
else
set AncientObelisk.timeP = AncientObelisk.timeP + 1
if AncientObelisk.timeP == 5 then
set AncientObelisk.timeP = 0
call PingMinimapEx(AncientObelisk.x,AncientObelisk.y,2.0,0,200,50,false)
call StartSound(gg_snd_ObeliskSound)
endif
endif
else
set AncientObelisk.timeE = AncientObelisk.timeE + 1
if AncientObelisk.timeE == FirstObeliskTime then
set AncientObelisk.timeE = 0.00
call AncientObelisk.Enable(true)
call Message.Show("The Ancient Obelisk is active.",MESSAGE_STYLE_INFO)
call PingMinimapEx(AncientObelisk.x,AncientObelisk.y,3.0,0,200,50,false)
call StartSound(gg_snd_ObeliskSound)
endif
endif
if ModuloInteger(Seconds,3) == 0 then
call RestartUnitsPath()
if AncientObelisk.owner != 0 and Game.Mode != GAME_MODE_LMS then
call ObeliskRay()
endif
endif
if ModuloInteger(Minutes,5) == 0 and Minutes != 0 and Seconds == 0 then
endif
if ModuloInteger(Minutes,3) == 0 and Minutes != 0 and Seconds == 0 then
if LEVEL_UPGRADE < 20 then
set LEVEL_UPGRADE = LEVEL_UPGRADE + 1
call SetPlayerTechResearched(Game.PLAYER_WARCHIEF_HORDE,'R002',LEVEL_UPGRADE)
call SetPlayerTechResearched(Game.PLAYER_WARCHIEF_ALLIANCE,'R002',LEVEL_UPGRADE)
endif
if LEVEL_UPGRADE_NEUTRAL < 15 then
set LEVEL_UPGRADE_NEUTRAL = LEVEL_UPGRADE_NEUTRAL + 1
call SetPlayerTechResearched(Game.PLAYER_NEUTRAL_HOSTILE,'R003',LEVEL_UPGRADE_NEUTRAL)
endif
endif
endif
if Game.Mode == GAME_MODE_LMS then
if Game.RoundStarted and Winner == 0 then
call Players.CheckPositionPenalty()
if Team[1].heroesIn == 0 then
call LastManStanding_EndRound.evaluate(2)
endif
if Team[2].heroesIn == 0 then
call LastManStanding_EndRound.evaluate(1)
endif
endif
endif
/*if Game.Mode == GAME_MODE_OD then
if Game.RoundStarted then
call Players.CheckPositionPenalty()
if Team[2/CurrentOwner].heroesIn == 0 then
call ObeliskDefend_EndRound.evaluate(CurrentOwner)
endif
endif
endif*/
else
if Game.Mode == GAME_MODE_NORMAL then
call Players.CheckPositionPenalty()
endif
endif
call MultiboardUpdateTittle()
call MultiboardUpdateGold()
endif
endmethod
public static method Start takes nothing returns nothing
local timer t = CreateTimer()
call MultiboardUpdateTittle()
call TimerStart(t,1.00,true,function thistype.Loop)
set t = null
endmethod
endstruct
endlibrary
library FearSystem uses UnitData, TeamLib
struct Fear extends array
private static LinkedList list = 0
private static thistype ctl = 0
implement CTL
local Link node
local real x
local real y
local Team t
implement CTLExpire
set node = list.head
loop
exitwhen node == 0
set t = GetUnitTeam(Index[node.data].u)
if t == 0 then
set x = 0
set y = 0
else
set x = t.startX
set y = t.startY
endif
if GetUnitCurrentOrder(Index[node.data].u) != ORDER_move then
call IssuePointOrder(Index[node.data].u,"move",x,y)
endif
set node = node.next
endloop
implement CTLEnd
public static method RemoveUnit takes unit u returns nothing
local integer index = GetUnitData(u,"FearIndex")
local DefenderSquad ds
if index != 0 then
call Status.Remove(STATUS_DISABLE,u)
set ds = GetUnitData(u,"DSInstance")
if ds != 0 then
call IssuePointOrderById(u,ORDER_attack,ds.x,ds.y)
else
call IssueImmediateOrderById(u,ORDER_stop)
endif
call list.remove(index)
if list.size == 0 and ctl != 0 then
call ctl.destroy()
set ctl = 0
endif
endif
endmethod
public static method AddUnit takes unit u returns nothing
local integer index = list.add(GetUnitUserData(u))
call SetUnitData(u,"FearIndex",index)
call Status.Add(STATUS_DISABLE,u,0,0)
if list.size == 1 then
set ctl = thistype.create()
endif
endmethod
private static method onInit takes nothing returns nothing
set list = LinkedList.create()
endmethod
endstruct
endlibrary
library Status initializer Init requires Table, Effect, PlayerLib, FearSystem
globals
private constant integer DUMMY_ID = 'u001'
private constant integer BUFF_ENSNARE_AIR = 'BSI1'
private constant integer BUFF_CYCLONE_EXTRA = 'Bcy2'
private constant string EFFECT_STUN = "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl"
private constant string EFFECT_SILENCE = "Abilities\\Spells\\Other\\Silence\\SilenceTarget.mdl"
private constant string EFFECT_DISARM = "Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl"
private constant string EFFECT_ENSNARE = "Abilities\\Spells\\Orc\\Ensnare\\ensnareTarget.mdl"
private constant string EFFECT_DOOM = "Abilities\\Spells\\Other\\ImmolationRed\\ImmolationREDTarget.mdl"
private constant string EFFECT_BANISH = "Abilities\\Spells\\Human\\Banish\\BanishTarget.mdl"
private constant string EFFECT_ENTANGLE = "Abilities\\Spells\\NightElf\\EntanglingRoots\\EntanglingRootsTarget.mdl"
private constant string EFFECT_SPELL_IMMUNE = "war3mapImported\\DivineBarrier1.mdx"
private constant string EFFECT_INVIS = "Abilities\\Spells\\Items\\AIlb\\AIlbSpecialArt.mdl"
private constant string EFFECT_PHASE = "Abilities\\Weapons\\WingedSerpentMissile\\WingedSerpentMissile.mdl"
private constant string EFFECT_TRUES = "Abilities\\Spells\\Human\\MagicSentry\\MagicSentryCaster.mdl"
private constant string EFFECT_DISABLE = "Abilities\\Spells\\NightElf\\SpiritOfVengeance\\SpiritOfVengeanceOrbs1.mdl"
private constant string EFFECT_SLEEP = "Abilities\\Spells\\Undead\\Sleep\\SleepTarget.mdl"
private constant string EFFECT_FEAR = "war3mapImported\\FearEffect3.mdx"
private unit attacker
private unit DummyCaster = null
private TableArray TB
private integer array ABILITY
private integer array BUFF
private integer array ORDER
public Effect array EFFECT
StatusObject EVENT_STATUS
private Event EVENT_UNIT_STATUS
endglobals
globals
constant integer STATUS_STUN = 1
constant integer STATUS_SILENCE = 2
constant integer STATUS_DISARM = 3
constant integer STATUS_ENSNARE = 4
constant integer STATUS_HEX = 5
constant integer STATUS_ENTANGLE = 6
constant integer STATUS_BANISH = 7
constant integer STATUS_CYCLONE = 8
constant integer STATUS_FEAR = 9
constant integer STATUS_SLEEP = 10
constant integer STATUS_SPY = 11
constant integer STATUS_FROST = 12
constant integer STATUS_SPELL_IMMUNITY = 13
constant integer STATUS_INVISIBILITY = 14
constant integer STATUS_GHOST = 15
constant integer STATUS_PHASE = 16
constant integer STATUS_TRUE_SIGHT = 17
constant integer STATUS_INVULNERABLE = 18
constant integer STATUS_DISABLE = 19
constant integer STATUS_PAUSE = 20
constant integer STATUS_HIDE = 21
constant integer STATUS_UNPATH = 22
constant integer STATUS_UNTURN = 23
endglobals
function DispelMovilityStatus takes unit u returns nothing
call Status.RemoveStrong(STATUS_ENSNARE,u)
call Status.RemoveStrong(STATUS_ENTANGLE,u)
call Status.RemoveStrong(STATUS_FROST,u)
endfunction
function DispelNegativeStatus takes unit u returns nothing
call Status.RemoveStrong(STATUS_STUN,u)
call Status.RemoveStrong(STATUS_SILENCE,u)
call Status.RemoveStrong(STATUS_DISARM,u)
call Status.RemoveStrong(STATUS_ENSNARE,u)
call Status.RemoveStrong(STATUS_HEX,u)
call Status.RemoveStrong(STATUS_ENTANGLE,u)
call Status.RemoveStrong(STATUS_BANISH,u)
call Status.RemoveStrong(STATUS_CYCLONE,u)
call Status.RemoveStrong(STATUS_FEAR,u)
call Status.RemoveStrong(STATUS_SLEEP,u)
call Status.RemoveStrong(STATUS_SPY,u)
call Status.RemoveStrong(STATUS_FROST,u)
endfunction
function DispelBuffsCyclone takes unit u returns nothing
call Status.RemoveStrong(STATUS_SILENCE,u)
call Status.RemoveStrong(STATUS_DISARM,u)
call Status.RemoveStrong(STATUS_HEX,u)
call Status.RemoveStrong(STATUS_BANISH,u)
call Status.RemoveStrong(STATUS_SPY,u)
endfunction
private struct StatusLoop extends array
private static thistype ctl = 0
static LinkedList list = 0
implement CTL
local Link h
local StatusObject s
local Link temp = 0
implement CTLExpire
set h = list.head
loop
exitwhen h == 0
set temp = h.next
set s = h.data
if not s.isNull then
if s.permanent then
if s.durationEx > 0 then
set s.durationEx = s.durationEx - 0.03125
if s.durationEx <= 0 then
set s.durationEx = 0
set s.sfxDataEx = 0
endif
endif
else
set s.duration = s.duration - 0.03125
if s.duration <= 0 or not UnitAlive(s.target) then
call list.remove(h)
call Status.Finish(s.status,s.target)
call s.destroy()
endif
endif
endif
set h = temp
endloop
if list.size == 0 and ctl != 0 then
call ctl.destroy()
set ctl = 0
endif
implement CTLEnd
public static method Remove takes StatusObject a returns nothing
call list.remove(a.index)
if list.size == 0 and ctl != 0 then
call ctl.destroy()
set ctl = 0
endif
endmethod
public static method Add takes StatusObject a returns nothing
set a.index = list.add(a)
if list.size == 1 then
set ctl = thistype.create()
endif
endmethod
endstruct
struct StatusObject extends array
implement Alloc
integer status
unit target
boolean permanent
integer permanentEx
real duration
real durationEx
Effect sfxData
Effect sfxDataEx
effect sfx
integer index
public method replaceEffect takes Effect ne returns nothing
if sfx != null then
call DestroyEffect(sfx)
endif
if ne != 0 then
set sfxData = ne
set sfx = AddSpecialEffectTarget(ne.path,target,ne.attach)
endif
endmethod
public static method create takes integer s, unit ta, real t, Effect e returns thistype
local thistype this = thistype.allocate()
set status = s
set target = ta
if e != 0 then
set sfxData = e
set sfx = AddSpecialEffectTarget(e.path,target,e.attach)
endif
if t == 0 then
set permanent = true
set permanentEx = 1
else
set permanent = false
set permanentEx = 0
set duration = t
endif
set sfxDataEx = 0
set durationEx = 0
return this
endmethod
public method destroy takes nothing returns nothing
set status = 0
set target = null
set duration = 0
set sfxData = 0
set index = 0
call DestroyEffect(sfx)
set sfx = null
call this.deallocate()
endmethod
endstruct
private function DisablingStatus takes integer st returns boolean
return st == STATUS_STUN or st == STATUS_SILENCE or st == STATUS_DISARM or st == STATUS_HEX or st == STATUS_BANISH or st == STATUS_CYCLONE or st == STATUS_FEAR or st == STATUS_SLEEP or st == STATUS_DISABLE or st == STATUS_PAUSE
endfunction
struct Status extends array
private static method Apply takes integer status, unit u returns boolean
local boolean b = false
local Team t = 0
local player p = GetOwningPlayer(u)
local unit temp
if DisablingStatus(status) then
call IncUnitAbilityLevel(u,Game.FLAG_DISABLED)
endif
if (status == STATUS_UNTURN) then
call SetUnitPropWindow(u,0)
call SetUnitTurnSpeed(u,0)
set b = true
elseif (status == STATUS_INVULNERABLE) then
call SetUnitInvulnerable(u, true)
set b = true
elseif (status == STATUS_PAUSE) then
call PauseUnit(u, true)
set b = true
elseif (status == STATUS_HIDE) then
call ShowUnit(u, false)
set b = true
elseif (status == STATUS_UNPATH) then
call SetUnitPathing(u, false)
set b = true
elseif (status == STATUS_FEAR) then
call Fear.AddUnit(u)
set b = true
elseif (status == STATUS_PHASE) then
call SetPlayerAbilityAvailable(p, ABILITY[status], true)
if (UnitAddAbility(u, ABILITY[status])) then
call UnitMakeAbilityPermanent(u, true, ABILITY[status])
call IssueImmediateOrderById(u, ORDER[status])
call UnitRemoveAbility(u,ABILITY[status])
set b = true
endif
call SetPlayerAbilityAvailable(p, ABILITY[status], false)
else
if (ORDER[status] == 0) then
if status == STATUS_FROST then
call UnitAddAbility(attacker,'AHfa')
call SetUnitX(attacker,GetUnitX(u))
call SetUnitY(attacker,GetUnitY(u))
if IssueTargetOrderById(attacker, 852173,u) then
set b = true
endif
else
if UnitAddAbility(u, ABILITY[status]) then
call UnitMakeAbilityPermanent(u, true, ABILITY[status])
set b = true
if status == STATUS_SPELL_IMMUNITY then
call AddUnitNegativeStatusReduction(u,0,true)
endif
endif
endif
else
if status == STATUS_SPY then
if GetUnitTeam(u) == 1 then
set t = 2
elseif GetUnitTeam(u) == 2 then
set t = 1
endif
if t != 0 then
call UnitAddAbility(GetPlayerDummy(t.captain), ABILITY[status])
if IssueTargetOrderById(GetPlayerDummy(t.captain), ORDER[status], u) then
set b = true
endif
call UnitRemoveAbility(GetPlayerDummy(t.captain), ABILITY[status])
endif
else
call SetUnitOwner(DummyCaster,p,false)
call UnitAddAbility(DummyCaster, ABILITY[status])
if status == STATUS_HEX then
//call BJDebugMsg(BlzGetAbilityStringLevelField(BlzGetUnitAbility(DummyCaster,'ASHX'),ABILITY_SLF_MORPH_UNITS_GROUND,0))
//call BlzSetAbilityStringLevelField(BlzGetUnitAbility(DummyCaster,'ASHX'),ABILITY_SLF_MORPH_UNITS_GROUND,0,"")
//call BlzSetAbilityStringLevelField(BlzGetUnitAbility(DummyCaster,'ASHX'),ABILITY_SLF_MORPH_UNITS_GROUND,0,"nfro")
endif
if IssueTargetOrderById(DummyCaster, ORDER[status], u) then
set b = true
if status == STATUS_DISABLE then
call BlzUnitDisableAbility(u,'Aatk',true,false)
endif
//call SetUnitOwner(DummyCaster,Player(15),false)
if status == STATUS_HEX then
call Movespeed.calculateMove(u)
endif
if status == STATUS_SLEEP then
call UnitAddBuff(u,u,9999,SleepSecond.buff,0,0)
endif
endif
call UnitRemoveAbility(DummyCaster, ABILITY[status])
endif
endif
endif
set p = null
return b
endmethod
public static method Finish takes integer status, unit u returns nothing
if DisablingStatus(status) then
call DecUnitAbilityLevel(u,Game.FLAG_DISABLED)
endif
if (status == STATUS_UNTURN) then
call SetUnitPropWindow(u,GetUnitDefaultPropWindow(u) * bj_DEGTORAD)
call SetUnitTurnSpeed(u,GetUnitDefaultTurnSpeed(u))
elseif (status == STATUS_INVULNERABLE) then
call SetUnitInvulnerable(u, false)
elseif (status == STATUS_PAUSE) then
call PauseUnit(u, false)
elseif (status == STATUS_HIDE) then
call ShowUnit(u, true)
elseif (status == STATUS_UNPATH) then
call SetUnitPathing(u, true)
elseif (status == STATUS_PHASE) then
call UnitRemoveAbility(u, BUFF[status])
elseif (status == STATUS_FEAR) then
call Fear.RemoveUnit(u)
else
if (ORDER[status] == 0) then
call UnitMakeAbilityPermanent(u, false, ABILITY[status])
call UnitRemoveAbility(u, ABILITY[status])
if status == STATUS_SPELL_IMMUNITY then
call AddUnitNegativeStatusReduction(u,0,false)
endif
endif
if (BUFF[status] != 0) then
call UnitRemoveAbility(u, BUFF[status])
if (status == STATUS_DISABLE) then
call BlzUnitDisableAbility(u,'Aatk',false,false)
endif
if (status == STATUS_ENSNARE) then
call UnitRemoveAbility(u, BUFF_ENSNARE_AIR)
endif
if (status == STATUS_CYCLONE) then
call UnitRemoveAbility(u, BUFF_CYCLONE_EXTRA)
endif
if (status == STATUS_ENTANGLE or status == STATUS_ENSNARE) then
set AICore[GetPlayerId(GetOwningPlayer(u))].lastTargetX = 0
set AICore[GetPlayerId(GetOwningPlayer(u))].lastTargetY = 0
set AICore[GetPlayerId(GetOwningPlayer(u))].lastTarget = null
endif
if status == STATUS_HEX then
call Movespeed.calculateMove(u)
endif
if status == STATUS_SLEEP then
call UnitRemoveBuff(u,SleepSecond.buff)
endif
endif
endif
call SetStatusObject(status,u,0)
endmethod
private static method GetStatusObject takes integer status, unit u returns integer
return TB[status].integer[GetUnitUserData(u)]
endmethod
private static method SetStatusObject takes integer status, unit u, integer data returns nothing
set TB[status].integer[GetUnitUserData(u)] = data
endmethod
public static method UnitHasStatus takes integer status, unit u returns boolean
return TB[status].integer[GetUnitUserData(u)] != 0
endmethod
public static method Add takes integer status, unit target, real time, Effect e returns real
local integer unitID = GetUnitUserData(target)
local StatusObject ob
if UnitAlive(target) and time >= 0 then
if status <= 12 and time > 0 then
if TriggerStatusNegation(status,target) or IsUnitImmuneToStatus(status,target) then
call CreateTextTagForAll(GetUnitX(target),GetUnitY(target),"|c0012ebe6[Immune]|r",15)
return 0.00
endif
if time > 0 then
set time = time - time * GetUnitStatusReduction(status,target)
if not (time >= 0.01) then
call CreateTextTagForAll(GetUnitX(target),GetUnitY(target),"|c0012ebe6[Immune]|r",15)
return 0.00
endif
endif
endif
if not UnitHasStatus(status,target) then
if Apply(status,target) then
if status == STATUS_CYCLONE then
call DispelBuffsCyclone(target)
endif
if status == STATUS_SPELL_IMMUNITY then
call DispelNegativeStatus(target)
call UnitDispelAllBuffsImmune(target)
endif
set ob = StatusObject.create(status,target,time,e)
call SetStatusObject(status,target,ob)
call StatusLoop.Add(ob)
if status == STATUS_SLEEP then
set ob.duration = ob.duration + 0.40
endif
set EVENT_STATUS = ob
call EVENT_UNIT_STATUS.fire()
return ob.duration
endif
else
set ob = GetStatusObject(status,target)
if ob.permanent then
if time > 0 then
if time >= ob.durationEx then
set ob.durationEx = time
set ob.sfxDataEx = e
else
call DestroyEffect(AddSpecialEffectTarget(e.path,target,e.attach))
endif
else
set ob.permanentEx = ob.permanentEx + 1
if e != 0 then
call ob.replaceEffect(e)
endif
endif
else
if time == 0 then
set ob.permanent = true
set ob.permanentEx = 1
set ob.durationEx = ob.duration
set ob.sfxDataEx = ob.sfxData
call ob.replaceEffect(e)
else
if time >= ob.duration then
call ob.replaceEffect(e)
set ob.duration = time
if status == STATUS_SLEEP then
set ob.duration = ob.duration + 0.40
endif
else
call DestroyEffect(AddSpecialEffectTarget(e.path,target,e.attach))
endif
endif
endif
return ob.duration
endif
return 0.00
else
return 0.00
endif
endmethod
public static method GetTime takes integer status, unit target returns real
local StatusObject ob = GetStatusObject(status,target)
if ob != 0 then
return ob.duration
endif
return 0.00
endmethod
public static method AddTime takes integer status, unit target, real mod returns real
local StatusObject ob = GetStatusObject(status,target)
if ob != 0 then
if not ob.permanent then
set ob.duration = ob.duration + mod
endif
return ob.duration
endif
return 0.00
endmethod
public static method RemoveStrong takes integer status, unit target returns nothing
local StatusObject ob = GetStatusObject(status,target)
if ob != 0 then
call StatusLoop.Remove(ob)
call ob.destroy()
call Finish(status,target)
endif
endmethod
public static method Remove takes integer status, unit target returns boolean
local StatusObject ob = GetStatusObject(status,target)
if ob != 0 and GetUnitUserData(target) != 0 then
if ob.permanent then
set ob.permanentEx = ob.permanentEx - 1
if ob.permanentEx <= 0 then
set ob.permanentEx = 0
set ob.permanent = false
if ob.durationEx > 0 then
set ob.duration = ob.durationEx
call ob.replaceEffect(ob.sfxDataEx)
set ob.sfxDataEx = 0
set ob.durationEx = 0
else
call Finish(status,target)
call StatusLoop.Remove(ob)
call ob.destroy()
endif
endif
else
call StatusLoop.Remove(ob)
call ob.destroy()
call Finish(status,target)
endif
return true
endif
return false
endmethod
endstruct
function RegisterUnitStatusEvent takes code c returns nothing
call EVENT_UNIT_STATUS.register(Filter(c))
endfunction
private function Load takes nothing returns nothing
set ABILITY[STATUS_STUN] = 'ASST'
set ABILITY[STATUS_SILENCE] = 'ASSI'
set ABILITY[STATUS_DISARM] = 'ASDB'
set ABILITY[STATUS_ENSNARE] = 'ASIM'
set ABILITY[STATUS_DISABLE] = 'ASDO'
set ABILITY[STATUS_HEX] = 'ASHX'
set ABILITY[STATUS_CYCLONE] = 'ASCY'
set ABILITY[STATUS_BANISH] = 'ASBN'
set ABILITY[STATUS_ENTANGLE] = 'ASEN'
set ABILITY[STATUS_SPY] = 'ASEV'
set ABILITY[STATUS_SPELL_IMMUNITY] = 'ASMI'
set ABILITY[STATUS_INVISIBILITY] = 'ASIN'
set ABILITY[STATUS_GHOST] = 'ASGT'
set ABILITY[STATUS_PHASE] = 'ASPH'
set ABILITY[STATUS_TRUE_SIGHT] = 'ASTS'
set ABILITY[STATUS_FROST] = 'ASFR'
set ABILITY[STATUS_SLEEP] = 'ASSL'
set BUFF[STATUS_STUN] = 'BSST'
set BUFF[STATUS_SILENCE] = 'BSSL'
set BUFF[STATUS_DISARM] = 'BSDB'
set BUFF[STATUS_ENSNARE] = 'BSI2'
set BUFF[STATUS_DISABLE] = 'BSDA'
set BUFF[STATUS_HEX] = 'BSHX'
set BUFF[STATUS_BANISH] = 'BSBN'
set BUFF[STATUS_CYCLONE] = 'Bcyc'
set BUFF[STATUS_ENTANGLE] = 'BSEN'
set BUFF[STATUS_SPY] = 'BSEV'
set BUFF[STATUS_PHASE] = 'BSPS'
set BUFF[STATUS_FROST] = 'Bfro'
set BUFF[STATUS_SLEEP] = 'BUsl'
set ORDER[STATUS_STUN] = 852231
set ORDER[STATUS_SILENCE] = 852668
set ORDER[STATUS_DISARM] = 852585
set ORDER[STATUS_ENSNARE] = 852106
set ORDER[STATUS_DISABLE] = 852583
set ORDER[STATUS_HEX] = 852502
set ORDER[STATUS_BANISH] = 852486
set ORDER[STATUS_CYCLONE] = 852144
set ORDER[STATUS_ENTANGLE] = 852171
set ORDER[STATUS_SLEEP] = 852227
set ORDER[STATUS_SPY] = 852149
set ORDER[STATUS_PHASE] = 852129
set EFFECT[STATUS_STUN] = Effect.create(EFFECT_STUN,"overhead")
set EFFECT[STATUS_SILENCE] = Effect.create(EFFECT_SILENCE,"overhead")
set EFFECT[STATUS_DISARM] = Effect.create(EFFECT_DISARM,"overhead")
set EFFECT[STATUS_ENSNARE] = Effect.create(EFFECT_ENSNARE,"origin")
set EFFECT[STATUS_DISABLE] = Effect.create(EFFECT_DOOM,"chest")
set EFFECT[STATUS_BANISH] = Effect.create(EFFECT_BANISH,"chest")
set EFFECT[STATUS_ENTANGLE] = Effect.create(EFFECT_ENTANGLE,"origin")
set EFFECT[STATUS_SPELL_IMMUNITY] = Effect.create(EFFECT_SPELL_IMMUNE,"origin")
set EFFECT[STATUS_INVISIBILITY] = Effect.create(EFFECT_INVIS,"overhead")
set EFFECT[STATUS_PHASE] = Effect.create(EFFECT_PHASE,"origin")
set EFFECT[STATUS_GHOST] = Effect.create(EFFECT_INVIS,"overhead")
set EFFECT[STATUS_TRUE_SIGHT] = Effect.create(EFFECT_TRUES,"overhead")
set EFFECT[STATUS_SLEEP] = Effect.create(EFFECT_SLEEP,"overhead")
set EFFECT[STATUS_FEAR] = Effect.create(EFFECT_FEAR,"overhead")
set TB = TableArray[27]
endfunction
private function DummyDamage takes nothing returns nothing
local unit u = udg_DamageEventSource
if GetUnitTypeId(u) == 'u000' and GetUnitAbilityLevel(u,ABILITY[STATUS_SLEEP]) != 0 then
call RemoveUnit(u)
endif
set u = null
endfunction
private function AttackFix takes nothing returns nothing
if GetSpellAbilityId() == 'AHfa' then
call UnitRemoveAbility(GetTriggerUnit(), 'AHfa')
endif
endfunction
private function Init takes nothing returns nothing
local integer i = 1
local integer n = 0
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_DamageEvent", EQUAL, 2.00 )
call TriggerAddCondition(t,function DummyDamage)
set t = null
set DummyCaster = CreateUnit(Game.PLAYER_NEUTRAL_EXTRA, DUMMY_ID, Game.HIDE_X, Game.HIDE_Y, 0)
set attacker = CreateUnit(Game.PLAYER_NEUTRAL_EXTRA,'u000', Game.HIDE_X, Game.HIDE_Y, 0)
call UnitAddAbility(attacker,'ASFR')
call TriggerRegisterUnitEvent(t2,attacker,EVENT_UNIT_SPELL_CHANNEL)
call TriggerAddCondition(t2,function AttackFix)
set t2 = null
call Load()
loop
exitwhen ABILITY[i] == 0
call PreloadGen.Add(ABILITY[i],PRELOAD_FIRST)
if (ORDER[i] == 0) and i != 10 then
loop
exitwhen n > Game.PLAYER_MAX
call SetPlayerAbilityAvailable(Player(n), ABILITY[i], false)
set n = n + 1
endloop
set n = 0
endif
set i = i + 1
endloop
set StatusLoop.list = LinkedList.create()
set EVENT_UNIT_STATUS = Event.create()
call Preload(EFFECT_STUN)
call Preload(EFFECT_SILENCE)
call Preload(EFFECT_DISARM)
call Preload(EFFECT_ENSNARE)
call Preload(EFFECT_INVIS)
call Preload(EFFECT_DOOM)
call Preload(EFFECT_BANISH)
call Preload(EFFECT_PHASE)
call Preload(EFFECT_DISABLE)
call Preload(EFFECT_SLEEP)
call Preload(EFFECT_TRUES)
endfunction
endlibrary
scope StatusBuffs initializer init
struct SleepSecond extends array
boolean s
real time
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_PAUSE,b.target)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if not s then
set time = time + 0.03125
if time >= 0.40 then
//call UnitRemoveAbility(b.target,'BUsl')
call UnitRemoveAbility(b.target,'BUsp')
call UnitRemoveAbility(b.target,'Bust')
set s = true
call Status.Remove(STATUS_INVULNERABLE,b.target)
call Status.Add(STATUS_PAUSE,b.target,0,0)
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Add(STATUS_INVULNERABLE,b.target,0,0)
call IssueImmediateOrderById(b.target,ORDER_stop)
set s = false
set time = 0.00
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0B0'
set BUFF_DATA.BuffID = 'BUsl'
set BUFF_DATA.Name = "Sleep"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.PierceImmune = false
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function init takes nothing returns nothing
call SleepSecond.Initialize()
endfunction
endscope
library StatusReduction initializer init uses Table
globals
private HashTable HT
endglobals
function GetUnitStatusReduction takes integer status, unit target returns real
return HT[status].real[GetUnitUserData(target)]
endfunction
function IsUnitImmuneToStatus takes integer status, unit target returns boolean
return HT[status].integer[GetUnitUserData(target)] > 0
endfunction
function AddUnitStatusReduction takes integer status, unit target, real percent, boolean immunity returns nothing
local integer id = GetUnitUserData(target)
local real p = HT[status].real[id]
if immunity then
set HT[status].integer[id] = HT[status].integer[id] + 1
elseif percent == 0 then
set HT[status].integer[id] = HT[status].integer[id] - 1
endif
set p = p + percent
set HT[status].real[id] = p
endfunction
function AddUnitNegativeStatusReduction takes unit target, real percent, boolean immunity returns nothing
call AddUnitStatusReduction(STATUS_STUN,target,percent,immunity)
call AddUnitStatusReduction(STATUS_SILENCE,target,percent,immunity)
call AddUnitStatusReduction(STATUS_DISARM,target,percent,immunity)
call AddUnitStatusReduction(STATUS_ENSNARE,target,percent,immunity)
call AddUnitStatusReduction(STATUS_HEX,target,percent,immunity)
call AddUnitStatusReduction(STATUS_ENTANGLE,target,percent,immunity)
call AddUnitStatusReduction(STATUS_BANISH,target,percent,immunity)
call AddUnitStatusReduction(STATUS_CYCLONE,target,percent,immunity)
call AddUnitStatusReduction(STATUS_FEAR,target,percent,immunity)
call AddUnitStatusReduction(STATUS_SLEEP,target,percent,immunity)
call AddUnitStatusReduction(STATUS_FROST,target,percent,immunity)
endfunction
private function init takes nothing returns nothing
set HT = HashTable.create()
endfunction
endlibrary
library BuffManager uses LinkedList, Table
globals
constant integer BUFF_TYPE_NEGATIVE = 0
constant integer BUFF_TYPE_POSITIVE = 1
constant integer BUFF_TYPE_NEUTRAL = 2
constant integer EFFECT_TYPE_SLOW = 1
constant integer EFFECT_TYPE_SHIELD = 2
constant integer EFFECT_TYPE_HEAL = 3
constant integer STACK_TYPE_NOSTACK = 0 //NO STACKEA
constant integer STACK_TYPE_NORMAL = 1 //STACKEA EN VARIOS BUFF, EL ULTIMO BUFF APLICADO SERA EL BUFF ACTUAL.
constant integer STACK_TYPE_INDEPENDENT = 2 //STACKEA EN VARIOS BUFF, CADA STACK ES UN BUFF DIFERENTE.
constant integer STACK_RULES_OTHER_SOURCE = 0 //Aplica un nuevo stack si el source es diferente al jugador owner.
constant integer STACK_RULES_UNIQUE_SOURCE = 1 //Aplica un nuevo stack si el source es el mismo jugador del buff
constant integer STACK_RULES_ANY_SOURCE = 2 //Aplica un nuevo stack con coualquier source
constant integer OBJECT_SOURCE_TYPE_ITEM = 0
constant integer OBJECT_SOURCE_TYPE_ABILITY = 1
constant integer OBJECT_SOURCE_TYPE_UNIT = 2
endglobals
globals
private Event ON_APPLY_BUFF = 0
Buff EVENT_BUFF_APPLIED = 0
private Table array T //Tabla donde se guarda cada tipo de Buff.
private Event array E //Event para eliminar un buff.
private Buff array EB //Buff del evento de eliminacion
private integer array ED //Data del evento añadir o eliminar
LinkedList array UB //Listas de cada unidad, guardando todos los buffs que tiene actualmente.
endglobals
function TriggerRegisterBuffApply takes code c returns nothing
if ON_APPLY_BUFF == 0 then
set ON_APPLY_BUFF = Event.create()
endif
call ON_APPLY_BUFF.register(Filter(c))
endfunction
function GetUnitBuff takes unit u, integer buffindex returns Buff
return T[buffindex].integer[GetUnitUserData(u)]
endfunction
function UnitHasBuff takes unit u, integer buffindex returns boolean
if u == null then
return false
endif
return T[buffindex].boolean[GetUnitUserData(u)]
endfunction
function UnitAddBuff takes unit target, unit source, real duration, integer buffindex, integer lvl, integer data returns Buff
local Buff b = Buff.create(target,source,duration,buffindex,lvl,data)
if b != 0 then
if b.StackType != STACK_TYPE_NOSTACK then
//if b.stacks <= b.StackMax then
set EB[buffindex] = b
set ED[buffindex] = 1
call E[buffindex].fire()
set EVENT_BUFF_APPLIED = b
call ON_APPLY_BUFF.fire()
//endif
else
set EB[buffindex] = b
set ED[buffindex] = 1
call E[buffindex].fire()
set EVENT_BUFF_APPLIED = b
call ON_APPLY_BUFF. fire()
endif
endif
return b
endfunction
function UnitRemoveBuff takes unit u, integer buffindex returns boolean
local Buff b = GetUnitBuff(u,buffindex)
if b != 0 then
call b.remove()
return true
endif
return false
endfunction
function SetUnitBuffDuration takes unit u, integer buffindex, real d returns boolean
local Buff b
if UnitHasBuff(u,buffindex) then
set b = GetUnitBuff(u,buffindex)
if d <= 0 then
set d = 0
endif
set b.duration = d
set b.elapsedTime = 0.00
return true
endif
return false
endfunction
function AddUnitBuffDuration takes unit u, integer buffindex, real d returns boolean
local Buff b
if UnitHasBuff(u,buffindex) then
set b = GetUnitBuff(u,buffindex)
set b.duration = b.duration + d
return true
endif
return false
endfunction
function GetUnitBuffTime takes unit u, integer buffindex returns real
local Buff b
if UnitHasBuff(u,buffindex) then
set b = GetUnitBuff(u,buffindex)
if b.StackType == STACK_TYPE_NOSTACK then
return b.elapsedTime
endif
endif
return 0.
endfunction
function GetUnitBuffRemainingTime takes unit u, integer buffindex returns real
local Buff b
if UnitHasBuff(u,buffindex) then
set b = GetUnitBuff(u,buffindex)
if b.StackType == STACK_TYPE_NOSTACK then
return b.duration - b.elapsedTime
endif
endif
return 0.
endfunction
function SetUnitBuffTime takes unit u, integer buffindex, real time returns boolean
local Buff b
if UnitHasBuff(u,buffindex) then
set b = GetUnitBuff(u,buffindex)
set b.elapsedTime = time
return true
endif
return false
endfunction
function UnitDispelBuff takes unit u, integer buffindex returns boolean
local Buff b
if UnitHasBuff(u,buffindex) then
set b = GetUnitBuff(u,buffindex)
if b.dispelable then
set b.disipated = true
call b.remove()
return true
endif
endif
return false
endfunction
function UnitRemoveAllBuffs takes unit u returns nothing
local Link h
local Link t
local Buff b
if GetUnitUserData(u) != 0 then
set h = UB[GetUnitUserData(u)].head
loop
exitwhen h == 0
set b = h.data
set t = h.next
call b.remove()
set h = t
endloop
endif
endfunction
function UnitDispelAllBuffsType takes unit u, integer btype returns nothing
local Link h
local Link t
local Buff b
if GetUnitUserData(u) != 0 then
set h = UB[GetUnitUserData(u)].head
loop
exitwhen h == 0
set b = h.data
set t = h.next
if b.EffectType == btype then
call UnitDispelBuff(u,b.data)
endif
set h = t
endloop
endif
endfunction
function UnitDispelAllBuffs takes unit u, integer polarity returns integer
local Link h
local Link t
local Buff b
local integer c = 0
if GetUnitUserData(u) != 0 then
set h = UB[GetUnitUserData(u)].head
loop
exitwhen h == 0
set b = h.data
set t = h.next
if b.buffType == polarity then
if UnitDispelBuff(u,b.data) then
set c = c + 1
endif
endif
set h = t
endloop
endif
return c
endfunction
function UnitDispelAllBuffsImmune takes unit u returns nothing
local Link h
local Link t
local Buff b
if GetUnitUserData(u) != 0 then
set h = UB[GetUnitUserData(u)].head
loop
exitwhen h == 0
set t = h.next
set b = h.data
if b.buffType == BUFF_TYPE_NEGATIVE and not b.pierceImmune then
call UnitDispelBuff(u,b.data)
endif
set h = t
endloop
endif
endfunction
function UnitRestartBuffs takes unit u, integer polarity returns nothing
local Link h
local Link t
local Buff b
if GetUnitUserData(u) != 0 then
set h = UB[GetUnitUserData(u)].head
loop
exitwhen h == 0
set b = h.data
if b.buffType == polarity then
set b.elapsedTime = 0.0
endif
set h = h.next
endloop
endif
endfunction
function UnitDispelBuffs takes unit u, integer count, integer polarity returns boolean
local Link h
local Link t
local Buff b
if GetUnitUserData(u) != 0 then
set h = UB[GetUnitUserData(u)].head
loop
exitwhen h == 0 or count == 0
set b = h.data
set t = h.next
if b.buffType == polarity then
call b.remove()
set count = count - 1
endif
set h = t
endloop
endif
return count == 0
endfunction
function UnitStealBuff takes unit target, unit source returns Buff
local Link h = UB[GetUnitUserData(target)].head
local Link t
local Buff b
local Buff s = 0
local integer c = 0
loop
exitwhen h == 0
set t = h.next
set b = h.data
if b.stealable and b.buffType == BUFF_TYPE_POSITIVE then
if b.StackType != STACK_TYPE_NOSTACK then
set c = b.stacks
loop
exitwhen c == 0
set s = UnitAddBuff(source,source,b.duration,b.data,b.level,b.int)
set c = c - 1
endloop
else
set s = UnitAddBuff(source,source,b.duration,b.data,b.level,b.int)
endif
call UnitRemoveBuff(target,b.data)
return s
endif
set h = t
endloop
return s
endfunction
function CountBuffsOfUnit takes unit owner, LinkedList buffList returns integer
local Link node = buffList.head
local Buff b
local integer c = 0
loop
exitwhen node == 0
set b = node.data
if b.owner == owner then
set c = c + 1
endif
set node = node.next
endloop
return c
endfunction
struct BuffData extends array
implement Alloc
integer BuffID
integer AuraID
real Period
string Name
integer BuffType
integer StackType
integer EffectType
integer StackRules
integer StackMax
boolean Persistent
boolean Dispelable
boolean PierceImmune
boolean Stealable
public static method create takes nothing returns thistype
return thistype.allocate()
endmethod
endstruct
struct Buff extends array
implement Alloc
unit target
unit owner
integer buffType
integer level
integer newLevel
real period
real count
real duration
real elapsedTime
boolean stealable
boolean dispelable
boolean pierceImmune
integer stacks
boolean stealed
boolean paused
boolean refreshed
boolean disipated
integer int
thistype prev
boolean removeInside
integer buffTypeIndex
integer buffAllocIndex
integer unitBuffIndex
delegate BuffData data
public method restart takes nothing returns nothing
set elapsedTime = 0
endmethod
public method pause takes boolean flag returns nothing
set paused = flag
endmethod
public method removePartialBuff takes nothing returns nothing
local Buff sbuff = 0
local Buff p = 0
local integer kl = 0
if data.StackType == STACK_TYPE_INDEPENDENT then
set sbuff = T[.data].integer[GetUnitUserData(.target)]
loop
exitwhen sbuff == 0 or kl == 1
if sbuff == this then
if p != 0 then
set p.prev = sbuff.prev
else
set sbuff.stacks = sbuff.stacks - 1
set T[.data].integer[GetUnitUserData(.target)] = sbuff.prev
endif
set kl = 1
else
set sbuff.stacks = sbuff.stacks - 1
set p = sbuff
set sbuff = sbuff.prev
endif
endloop
elseif data.StackType == STACK_TYPE_NORMAL then
set T[.data].integer[GetUnitUserData(.target)] = .prev
set stacks = stacks - 1
endif
if stacks == 0 or data.StackType == STACK_TYPE_NOSTACK then
call BuffAbilityOption(2)
set T[data].integer[GetUnitUserData(target)] = 0
set T[data].boolean[GetUnitUserData(target)] = false
endif
endmethod
public method remove takes nothing returns boolean
local Buff b = this
local Buff b2
if StackType == STACK_TYPE_NORMAL or StackType == STACK_TYPE_INDEPENDENT then
loop
exitwhen b == 0
set b2 = b.prev
set EB[data] = b
set ED[data] = 2
call E[data].fire()
set b = b2
endloop
return true
else
set EB[data] = b
set ED[data] = 2
call E[data].fire()
return true
endif
return false
endmethod
private method BuffAbilityOption takes integer option returns nothing
if option == 1 then
if data.AuraID != 0 then
if UnitAddAbility(target,data.AuraID) then
call UnitMakeAbilityPermanent(target,true,data.AuraID)
endif
endif
elseif option == 2 then
call UnitRemoveAbility(target,AuraID)
call UnitRemoveAbility(target,BuffID)
endif
endmethod
private method verifyStack takes unit s returns boolean
if data.StackRules == STACK_RULES_OTHER_SOURCE then
return s != owner
elseif data.StackRules == STACK_RULES_UNIQUE_SOURCE then
return s == owner
elseif data.StackRules == STACK_RULES_ANY_SOURCE then
return true
endif
return false
endmethod
public static method create takes unit target, unit source, real duration, BuffData data, integer lvl, integer d returns thistype
local thistype this = 0
local thistype new = 0
local thistype temp = 0
if target == null or GetUnitUserData(target) == 0 then
return 0
endif
if not data.PierceImmune and IsUnitEnemy(target,GetOwningPlayer(source)) and Status.UnitHasStatus(STATUS_SPELL_IMMUNITY,target) then
return 0
endif
if not UnitHasBuff(target,data) then
set this = thistype.allocate()
set this.data = data
set this.target = target
set this.owner = source
set this.level = lvl
set this.duration = duration
set this.int = d
set this.period = data.Period
set this.stealable = data.Stealable
set this.dispelable = data.Dispelable
set this.pierceImmune = data.PierceImmune
set this.stacks = 1
set this.buffType = data.BuffType
set this.elapsedTime = 0
call BuffAbilityOption(1)
set T[data].integer[GetUnitUserData(target)] = this
set T[data].boolean[GetUnitUserData(target)] = true
else
set this = GetUnitBuff(target,data)
if data.StackType == STACK_TYPE_NOSTACK then
set this.owner = source
set this.elapsedTime = 0
set this.duration = duration
set this.refreshed = true
set this.int = d
set this.period = data.Period
set this.newLevel = lvl
set this.stealable = data.Stealable
set this.dispelable = data.Dispelable
set this.pierceImmune = data.PierceImmune
//call BuffAbilityOption(2)
//call BuffAbilityOption(1)
return this
else
if stacks < StackMax and verifyStack(source) then
set new = thistype.allocate()
set new.buffType = data.BuffType
set new.prev = this
set new.data = data
set new.target = target
set new.owner = source
set new.duration = duration
set new.stacks = stacks + 1
set new.level = lvl
set new.int = d
set new.period = data.Period
set new.stealable = data.Stealable
set new.dispelable = data.Dispelable
set new.pierceImmune = data.PierceImmune
set temp = new.prev
loop
exitwhen temp == 0
set temp.owner = source
if data.StackType == STACK_TYPE_NORMAL then
set temp.duration = duration
set temp.elapsedTime = 0
endif
set temp = temp.prev
endloop
set T[data].integer[GetUnitUserData(target)] = new
call BuffAbilityOption(2)
call BuffAbilityOption(1)
else
set this.elapsedTime = 0
set this.duration = duration
set this.owner = source
set temp = this.prev
loop
exitwhen temp == 0
set temp.owner = source
set temp.duration = duration
set temp.elapsedTime = 0
set temp = temp.prev
endloop
endif
return new
endif
endif
return this
endmethod
method destroy takes nothing returns nothing
set target = null
set owner = null
set stealed = false
set paused = false
set refreshed = false
set disipated = false
set stealable = false
set dispelable = false
set pierceImmune = false
set stacks = 0
set period = 0
set count = 0
set duration = 0
set elapsedTime = 0
set removeInside = false
set prev = 0
set buffTypeIndex = 0
set buffAllocIndex = 0
set unitBuffIndex = 0
set int = 0
call this.deallocate()
endmethod
endstruct
module BuffCore
static LinkedList DATAS = 0
private static timer TIMER
static BuffData BUFF_DATA = 0
Buff thisBuff
implement Alloc
public static method operator buff takes nothing returns BuffData
return BUFF_DATA
endmethod
private static method Loop takes nothing returns nothing
local Buff b
local Link temp = DATAS.head
local integer sw
local Link r
loop
exitwhen temp == 0
set r = temp.next
set b = temp.data
set sw = 0
if b != 0 then
if UnitAlive(b.target) and b.duration > 0 then
if not b.paused then
set b.count = b.count + 0.03125
set b.elapsedTime = b.elapsedTime + 0.03125
if b.count >= b.period or b.period == 0 then
set b.count = 0
static if thistype.onPeriodic.exists then
call thistype.onPeriodic(b)
endif
endif
if b.elapsedTime >= b.duration and not b.isNull then
static if thistype.onFinish.exists then
call thistype.onFinish(b)
endif
set sw = 1
endif
endif
else
if not b.Persistent then
set sw = 1
endif
endif
if sw == 1 or b.removeInside and not b.isNull then
set EB[b.data] = b
set ED[b.data] = 2
call E[b.data].fire()
endif
endif
set temp = r
endloop
endmethod
private static method Actions takes nothing returns boolean
local Buff b = EB[BUFF_DATA]
local integer d = ED[BUFF_DATA]
local thistype in
if d == 1 then
if b.StackType == STACK_TYPE_NOSTACK then
if b.refreshed then
static if thistype.onRemove.exists then
call thistype.onRemove(b)
endif
set b.level = b.newLevel
static if thistype.onApply.exists then
call thistype.onApply(b)
endif
static if thistype.onRefresh.exists then
call thistype.onRefresh(b)
endif
set b.refreshed = false
else
set b.buffTypeIndex = DATAS.addLast(b)
set b.buffAllocIndex = thistype.allocate()
//call BJDebugMsg("allocating " +b.Name +" with "+I2S(b.buffAllocIndex) + "to" + GetUnitName(b.target))
set thistype[b.buffAllocIndex].thisBuff = b
set b.unitBuffIndex = UB[GetUnitUserData(b.target)].add(b)
static if thistype.onApply.exists then
call thistype.onApply(b)
endif
endif
else
set b.buffTypeIndex = DATAS.addLast(b)
set b.buffAllocIndex = thistype.allocate()
set thistype[b.buffAllocIndex].thisBuff = b
if b.stacks == 1 then
set b.unitBuffIndex = UB[GetUnitUserData(b.target)].add(b)
endif
static if thistype.onStackApply.exists then
call thistype.onStackApply(b)
endif
endif
if DATAS.size == 1 then
call TimerStart(TIMER,0.03125,true,function thistype.Loop)
endif
else
if b.disipated then
static if thistype.onDispel.exists then
call thistype.onDispel(b)
endif
endif
if b.StackType == STACK_TYPE_NOSTACK then
static if thistype.onRemove.exists then
call thistype.onRemove(b)
endif
else
static if thistype.onStackRemove.exists then
call thistype.onStackRemove(b)
endif
endif
call DATAS.remove(b.buffTypeIndex)
call b.removePartialBuff()
set in = b.buffAllocIndex
set in.allocName = b.Name
//call BJDebugMsg("Deallocating " + b.Name +" with "+I2S(b.buffAllocIndex) + "from" + GetUnitName(b.target))
call in.deallocate()
if b.unitBuffIndex != 0 then
call UB[GetUnitUserData(b.target)].remove(b.unitBuffIndex)
endif
call b.destroy()
if DATAS.size == 0 then
call PauseTimer(TIMER)
endif
endif
return false
endmethod
public static method Initialize takes nothing returns nothing
static if thistype.ConfigData.exists then
call ConfigData()
set T[BUFF_DATA] = Table.create()
set E[BUFF_DATA] = Event.create()
set TIMER = CreateTimer()
set DATAS = LinkedList.create()
call E[BUFF_DATA].register(Filter(function thistype.Actions))
else
debug call BJDebugMsg("METODO CONFIG NO ENCONTRADO - Creacion fallida")
endif
endmethod
endmodule
endlibrary
library Message
globals
MessageStyle MESSAGE_STYLE_INFO
MessageStyle MESSAGE_STYLE_ERROR
MessageStyle MESSAGE_STYLE_WARNING
MessageStyle MESSAGE_STYLE_HORDE
MessageStyle MESSAGE_STYLE_ALLIANCE
MessageStyle MESSAGE_STYLE_COMMAND
MessageStyle MESSAGE_STYLE_LMS
endglobals
struct MessageStyle extends array
implement Alloc
string msgcolor
real xoffset
real yoffset
real duration
sound soundeff
string startChar
string endChar
public method destroy takes nothing returns nothing
set msgcolor = ""
call KillSoundWhenDone(soundeff)
set soundeff = null
set startChar = ""
set endChar = ""
call deallocate()
endmethod
public static method create takes string cc, real x, real y, real d, sound s, string sc, string ec returns thistype
local thistype this = thistype.allocate()
set msgcolor = cc
set xoffset = x
set yoffset = y
set duration = d
set soundeff = s
set startChar = sc
set endChar = ec
return this
endmethod
endstruct
struct Message extends array
public static method ShowToPlayer takes player p, string msg, MessageStyle style returns nothing
if Game.LocalPlayer == p then
if style == MESSAGE_STYLE_ERROR then
call ClearTextMessages()
endif
if style.msgcolor != "" then
call DisplayTimedTextToPlayer(p,style.xoffset,style.yoffset,style.duration,style.startChar+style.msgcolor+msg+"|r"+style.endChar)
else
call DisplayTimedTextToPlayer(p,style.xoffset,style.yoffset,style.duration,style.startChar+msg+style.endChar)
endif
call StartSound(style.soundeff)
endif
endmethod
public static method ShowToForce takes force f, string msg, MessageStyle style returns nothing
if IsPlayerInForce(Game.LocalPlayer,f) or GetPlayerState(Game.LocalPlayer,PLAYER_STATE_OBSERVER) == 1 then
call ShowToPlayer(Game.LocalPlayer,msg,style)
endif
endmethod
public static method ShowToAllies takes player p, string msg, MessageStyle style returns nothing
if Team[1].isPlayerInTeam(p) then
call ShowToForce(Team[1].forceP,msg,style)
else
call ShowToForce(Team[2].forceP,msg,style)
endif
endmethod
public static method Show takes string msg, MessageStyle style returns nothing
call ShowToForce(bj_FORCE_ALL_PLAYERS,msg,style)
endmethod
endstruct
public function init takes nothing returns nothing
set MESSAGE_STYLE_INFO = MessageStyle.create("",0,0,10,gg_snd_Hint,"|cFF0063C6[Info]|r ","")
set MESSAGE_STYLE_ERROR = MessageStyle.create("|cffffcc00",0.52,0.10,3,gg_snd_Error,"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t",".")
set MESSAGE_STYLE_WARNING = MessageStyle.create("|cffff151c",0,0,5,gg_snd_Warning,"","")
set MESSAGE_STYLE_HORDE = MessageStyle.create("",0,0,7,null,"|cffdc143c[The Orcs]|r","")
set MESSAGE_STYLE_ALLIANCE = MessageStyle.create("",0,0,7,null,"|cff0000cd[The Humans]|r","")
set MESSAGE_STYLE_COMMAND = MessageStyle.create("",0,0,7,null,"|c00ffff00[cmd]|r ","")
set MESSAGE_STYLE_LMS = MessageStyle.create("",0,0,7,null,"|c00ff8000[Arena]|r","")
endfunction
endlibrary
library UpgradeSkill initializer init uses PlayerLib
globals
private constant string EFFECT_DONE = "war3mapImported\\MegaHeal.mdx"
private constant string MSG_UPGRADE_DONE1 = " Upgrade "
private constant string MSG_UPGRADE_DONE2 = " increased to lvl "
private constant string MSG_UPGRADE_MAX = " Upgrade is at the MAX level."
private constant string MSG_UPGRADE_NOPOINTS = " Not enough points to spent"
private constant string MSG_UPGRADE_UP4 = " The 4th Upgrade was unlocked, Choose the Mastery especialization"
private constant string MSG_UPGRADE_UP4_2 = " Mastery already chosen"
private constant string MSG_UPGRADE_UP4_SELECT = " You choose "
private constant string MSG_UPGRADE_UP4_WAR = " The Mastery requires level 14"
private constant string MSG_UPGRADE_UP5 = " Superior Upgrade selected on "
private constant string COLOR_HIGHLIGHT = "|cffff6347"
private string array ICONS
private trigger PURCHASE_SKILL_TRIGGER = CreateTrigger()
private MessageStyle MESSAGE_STYLE_UPGRADE
private Upgrade UPGRADE_UP
constant integer UPGRADE1_ID = 'A083'
constant integer UPGRADE2_ID = 'A084'
constant integer UPGRADE3_ID = 'A085'
constant integer UPGRADE_FIRST = 1
constant integer UPGRADE_SECOND = 2
constant integer UPGRADE_THIRD = 3
constant integer UPGRADE_FOURTH = 4
private constant string COLOR_NAME = "|c0099b4d1"
private constant string COLOR_SUP = "|c0000bfff"
private constant string COLOR_CURRENT = "|c0000ff00"
private hashtable HT = InitHashtable()
endglobals
function GetHeroMasteryType takes unit u returns integer
local Hero h = GetUnitData(u,"HeroIndex")
if h != 0 then
return h.masteryType
endif
return 0
endfunction
function GetUpgradeSkillLevel takes unit u, integer id returns integer
local Upgrade up = GetUnitData(u,I2S(id))
if up != 0 then
return up.level
endif
return 0
endfunction
function IsUpgradeSuperior takes unit u, integer id returns boolean
local Upgrade up = GetUnitData(u,I2S(id))
if up != 0 then
return up.isSuperior
endif
return false
endfunction
function RegisterUpgradeSkillEvent takes boolexpr c returns nothing
call Upgrade.OnUpgradeSkill.register(c)
endfunction
function GetEventUpgrade takes nothing returns Upgrade
return UPGRADE_UP
endfunction
private function buildDataLevel takes UpgradeData data, integer lvl returns string
local string r = "|n"
if lvl == 1 then
set r = r + COLOR_NAME+"Level 1:|r "+COLOR_CURRENT+data.LevelData1+"|r|n"
else
set r = r + COLOR_NAME+"Level 1:|r "+data.LevelData1+"|n"
endif
if lvl == 2 then
set r = r + COLOR_NAME+"Level 2:|r "+COLOR_CURRENT+data.LevelData2+"|r|n"
else
set r = r + COLOR_NAME+"Level 2:|r "+data.LevelData2+"|n"
endif
if lvl == 3 then
set r = r + COLOR_NAME+"Level 3:|r "+COLOR_CURRENT+data.LevelData3+"|r|n"
else
set r = r + COLOR_NAME+"Level 3:|r "+data.LevelData3+"|n"
endif
return r
endfunction
private function buildData takes UpgradeData d, integer level, integer sup returns string
local string r = d.Text+"|n"+ buildDataLevel(d,level)
if sup == d.UpIndex or sup == 0 then
set r = r + "|n"+COLOR_SUP+"[Superior Upgrade]|r|n" + d.SupText
endif
return r
endfunction
function BuildDescriptionByData takes UpgradeData d, unit u returns nothing
local string s1 = buildData(d,0,0)
local string s2 = COLOR_NAME+d.Name+"|r - level "+I2S(0)
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(u,d.UpAbility),ABILITY_SLF_TOOLTIP_NORMAL,0,s2)
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(u,d.UpAbility),ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,s1)
endfunction
function buildDescription takes Upgrade d, integer level, integer sup returns nothing
local string s1 = buildData(d.data,level,sup)
local string s2 = COLOR_NAME+d.Name+"|r - level "+I2S(level)
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(d.ownerHero.hero,d.UpAbility),ABILITY_SLF_TOOLTIP_NORMAL,0,s2)
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(d.ownerHero.hero,d.UpAbility),ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,s1)
endfunction
struct UpgradeData extends array
implement Alloc
integer UpId
integer UpIndex
integer UpAbility
string Name
string Text
string SupText
string LevelData1
string LevelData2
string LevelData3
string Icon
public static method create takes nothing returns thistype
return thistype.allocate()
endmethod
endstruct
struct Upgrade extends array
implement Alloc
integer upID
integer level
boolean isSuperior
integer levelSkip
Hero ownerHero
delegate UpgradeData data
public static Event OnUpgradeSkill
private method CheckSuperiorUp takes nothing returns nothing
local player p = GetOwningPlayer(ownerHero.hero)
if ownerHero.supUp == 0 and level == 3 then
set ownerHero.supUp = UpIndex
set isSuperior = true
call Message.ShowToPlayer(p,MSG_UPGRADE_UP5+COLOR_HIGHLIGHT+Name+"|r",MESSAGE_STYLE_UPGRADE)
if UpIndex == 1 then
call buildDescription(ownerHero.up2,ownerHero.up2.level,UpIndex)
call buildDescription(ownerHero.up3,ownerHero.up3.level,UpIndex)
elseif UpIndex == 2 then
call buildDescription(ownerHero.up1,ownerHero.up1.level,UpIndex)
call buildDescription(ownerHero.up3,ownerHero.up3.level,UpIndex)
elseif UpIndex == 3 then
call buildDescription(ownerHero.up1,ownerHero.up1.level,UpIndex)
call buildDescription(ownerHero.up2,ownerHero.up2.level,UpIndex)
endif
endif
set p = null
endmethod
public static method ActiveFourthUp takes Hero h returns nothing
if GetUnitAbilityLevel(h.hero,h.up4.UpId) == 1 then
call Message.ShowToPlayer(GetOwningPlayer(h.hero),MSG_UPGRADE_UP4,MESSAGE_STYLE_UPGRADE)
call BlzUnitDisableAbility(h.hero,h.up4.UpId,false,false)
set h.up4.level = 1
set UPGRADE_UP = h.up4
call OnUpgradeSkill.fire()
endif
endmethod
private static method checkUpgradeLevels takes Hero h returns boolean
if h.up1.level == 3 and h.up2.level == 3 then
return true
endif
if h.up1.level == 3 and h.up3.level == 3 then
return true
endif
if h.up2.level == 3 and h.up3.level == 3 then
return true
endif
return false
endmethod
public method IncreaseLevel takes nothing returns boolean
local integer herolvl = GetHeroLevel(ownerHero.hero)
local player owner = GetOwningPlayer(ownerHero.hero)
local boolean result = true
if ownerHero.upgradePoints > 0 then
if level < 3 then
if herolvl >= levelSkip or herolvl == 3 then
if checkUpgradeLevels(ownerHero) then
set levelSkip = herolvl + 2
else
set levelSkip = herolvl + 4
endif
if levelSkip > 20 then
set levelSkip = 20
endif
set ownerHero.upgradePoints = ownerHero.upgradePoints - 1
if owner == Game.LocalPlayer then
call BlzSetAbilityIcon(ownerHero.InfoID,ICONS[ownerHero.upgradePoints])
if ownerHero.upgradePoints == 0 then
call ForceUICancel()
endif
endif
call DestroyEffect(AddSpecialEffectTarget(EFFECT_DONE,ownerHero.hero,"origin"))
set level = level + 1
call Message.ShowToPlayer(owner,MSG_UPGRADE_DONE1+COLOR_HIGHLIGHT+Name+"|r"+MSG_UPGRADE_DONE2+COLOR_HIGHLIGHT+I2S(level)+"|r",MESSAGE_STYLE_UPGRADE)
call CheckSuperiorUp()
set UPGRADE_UP = this
call OnUpgradeSkill.fire()
call ownerHero.updateAbilityTooltip(UpIndex)
call buildDescription(this,level,ownerHero.supUp)
else
set result = false
call Message.ShowToPlayer(owner,"The Upgrade requires hero level "+I2S(levelSkip),MESSAGE_STYLE_UPGRADE)
endif
else
set result = false
call Message.ShowToPlayer(owner,MSG_UPGRADE_MAX,MESSAGE_STYLE_UPGRADE)
endif
else
set result = false
call Message.ShowToPlayer(owner,MSG_UPGRADE_NOPOINTS,MESSAGE_STYLE_UPGRADE)
endif
set owner = null
return result
endmethod
public static method SetHeroTittle takes unit u, integer m returns nothing
if m == 1 then
call BlzSetHeroProperName(u,"|cffff2b2b"+GetHeroProperName(u))
elseif m == 2 then
call BlzSetHeroProperName(u,"|cff00ff00"+GetHeroProperName(u))
elseif m == 3 then
call BlzSetHeroProperName(u,"|cff0080ff"+GetHeroProperName(u))
endif
endmethod
public method SelectMastery takes integer m returns boolean
local player owner = GetOwningPlayer(ownerHero.hero)
local boolean result = true
if GetHeroLevel(ownerHero.hero) >= 14 then
if ownerHero.masteryType == 0 then
set ownerHero.masteryType = m
call SetUnitAbilityLevel(ownerHero.hero,UpId,m + 1)
call DestroyEffect(AddSpecialEffectTarget(EFFECT_DONE,ownerHero.hero,"origin"))
if m == 1 then
call Message.ShowToPlayer(owner,MSG_UPGRADE_UP4_SELECT+COLOR_HIGHLIGHT+"Combat Mastery.|r",MESSAGE_STYLE_UPGRADE)
elseif m == 2 then
call Message.ShowToPlayer(owner,MSG_UPGRADE_UP4_SELECT+COLOR_HIGHLIGHT+"Dexterity Mastery.|r",MESSAGE_STYLE_UPGRADE)
elseif m == 3 then
call Message.ShowToPlayer(owner,MSG_UPGRADE_UP4_SELECT+COLOR_HIGHLIGHT+"Wisdom Mastery.|r",MESSAGE_STYLE_UPGRADE)
endif
call SetHeroTittle(ownerHero.hero,m)
set level = 2
set UPGRADE_UP = this
call OnUpgradeSkill.fire()
else
call Message.ShowToPlayer(owner,MSG_UPGRADE_UP4_2,MESSAGE_STYLE_UPGRADE)
set result = false
endif
else
call Message.ShowToPlayer(owner,MSG_UPGRADE_UP4_WAR,MESSAGE_STYLE_UPGRADE)
set result = false
endif
set owner = null
return result
endmethod
public static method create takes UpgradeData d, Hero h returns thistype
local thistype this = thistype.allocate()
set upID = d.UpId
set level = 0
set isSuperior = false
set ownerHero = h
set data = d
set levelSkip = 0
call SetUnitData(h.hero,I2S(d.UpId),this)
if d.UpIndex != UPGRADE_FOURTH then
call buildDescription(this,level,0)
endif
return this
endmethod
private static method onUpgrade1 takes nothing returns nothing
local Hero h = GetPlayerHero(GetTriggerPlayer())
call h.up1.IncreaseLevel()
endmethod
private static method onUpgrade2 takes nothing returns nothing
local Hero h = GetPlayerHero(GetTriggerPlayer())
call h.up2.IncreaseLevel()
endmethod
private static method onUpgrade3 takes nothing returns nothing
local Hero h = GetPlayerHero(GetTriggerPlayer())
call h.up3.IncreaseLevel()
endmethod
private static method onPurchaseMastery takes nothing returns nothing
local item it = GetManipulatedItem()
local integer itemID = GetItemTypeId(it)
local Hero h = GetPlayerHero(GetTriggerPlayer())
if itemID == 'ICS1' then
call RemoveItem(it)
call h.up4.SelectMastery(1)
endif
if itemID == 'ICS2' then
call RemoveItem(it)
call h.up4.SelectMastery(2)
endif
if itemID == 'ICS3' then
call RemoveItem(it)
call h.up4.SelectMastery(3)
endif
set it = null
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(PURCHASE_SKILL_TRIGGER,Condition(function thistype.onPurchaseMastery))
call TriggerRegisterAnyUnitEventBJ(PURCHASE_SKILL_TRIGGER,EVENT_PLAYER_UNIT_PICKUP_ITEM)
call RegisterSpellEffectEvent(UPGRADE1_ID, function thistype.onUpgrade1)
call RegisterSpellEffectEvent(UPGRADE2_ID, function thistype.onUpgrade2)
call RegisterSpellEffectEvent(UPGRADE3_ID, function thistype.onUpgrade3)
set MESSAGE_STYLE_UPGRADE = MessageStyle.create("",0,0,7,null,"|cffffff00[Upgrade]|r","")
set thistype.OnUpgradeSkill = Event.create()
endmethod
public static method AddUpgradePoints takes Hero h returns nothing
set h.upgradePoints = h.upgradePoints + 1
//change icon
if GetOwningPlayer(h.hero) == Game.LocalPlayer then
call BlzSetAbilityIcon(h.InfoID,ICONS[h.upgradePoints])
endif
endmethod
endstruct
private function init takes nothing returns nothing
call PreloadGen.Add(UPGRADE1_ID,PRELOAD_SECOND)
call PreloadGen.Add(UPGRADE2_ID,PRELOAD_SECOND)
call PreloadGen.Add(UPGRADE3_ID,PRELOAD_SECOND)
set ICONS[0] = "ReplaceableTextures\\CommandButtons\\BTNStatUp.blp"
set ICONS[1] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade1.blp"
set ICONS[2] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade2.blp"
set ICONS[3] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade3.blp"
set ICONS[4] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade4.blp"
set ICONS[5] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade5.blp"
set ICONS[6] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade6.blp"
set ICONS[7] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade7.blp"
set ICONS[8] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade8.blp"
set ICONS[9] = "ReplaceableTextures\\CommandButtons\\BTNUpgrade9.blp"
endfunction
endlibrary
library Effect
struct Effect extends array
implement Alloc
string path
string attach
public method destroy takes nothing returns nothing
set path = ""
set attach = ""
call this.deallocate()
endmethod
public static method create takes string p, string at returns thistype
local thistype this = thistype.allocate()
set path = p
set attach = at
return this
endmethod
endstruct
endlibrary
library LoadFunction
globals
private Table tab
endglobals
struct LoadFunction extends array
public static method RegisterFunction takes code c, integer id returns nothing
local Event ev = tab[id]
if ev == 0 then
set ev = Event.create()
set tab[id] = ev
endif
call ev.register(Filter(c))
endmethod
public static method RunFunction takes integer id returns nothing
local Event ev = tab[id]
if ev != 0 then
call ev.fire()
set tab[id] = 0
endif
endmethod
public static method Destroy takes nothing returns nothing
call tab.flush()
call tab.destroy()
endmethod
implement main
endstruct
module main
private static method onInit takes nothing returns nothing
set tab = Table.create()
endmethod
endmodule
endlibrary
library PlayerTarget initializer init uses UnitData,PlayerLib
private function onAttack takes nothing returns nothing
local unit u = GetAttacker()
local unit t = GetTriggerUnit()
local player p = GetOwningPlayer(t)
local integer id = GetUnitTypeId(u)
local Base b
local Team te
local real x
local real y
if IsUnitAlly(u,p) and p != Player(PLAYER_NEUTRAL_PASSIVE) and id != 'u000' and GetUnitAbilityLevel(t,'A0BY') == 0 then
if not Status.UnitHasStatus(STATUS_SLEEP,t) then
//call IssueImmediateOrder(u,"stop")
call BlzUnitInterruptAttack(u)
endif
elseif IsUnitType(u,UNIT_TYPE_HERO) and IsUnitType(t,UNIT_TYPE_HERO) then
set x = GetUnitX(u)
set y = GetUnitY(u)
set te = GetPlayerTeamEx(p)
if Base[1].owner == te and Base[1].target == null then
if Distance(x,y,Base[1].x,Base[1].y) <= 750 then
call IssueTargetOrderById(Base[1].tower,ORDER_attack,u)
set Base[1].target = u
endif
endif
if Base[2].owner == te and Base[2].target == null then
if Distance(x,y,Base[2].x,Base[2].y) <= 700 then
call IssueTargetOrderById(Base[2].tower,ORDER_attack,u)
set Base[2].target = u
endif
endif
if Base[3].owner == te and Base[3].target == null then
if Distance(x,y,Base[3].x,Base[3].y) <= 750 then
call IssueTargetOrderById(Base[3].tower,ORDER_attack,u)
set Base[3].target = u
endif
endif
if Base[4].owner == te and Base[4].target == null then
if Distance(x,y,Base[4].x,Base[4].y) <= 750 then
call IssueTargetOrderById(Base[4].tower,ORDER_attack,u)
set Base[4].target = u
endif
endif
endif
if id == 'n009' or id == 'n006' then
set b = Base.GetBaseFromTower(u)
if b != 0 then
if b.target != null then
if b.target != t then
if not IsUnitType(t,UNIT_TYPE_HERO) then
set b.target = null
else
set b.target = t
endif
endif
endif
endif
endif
set u = null
set t = null
set p = null
endfunction
private function init takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED,function onAttack)
endfunction
endlibrary
library TowerAttackControl initializer init uses UnitData,PlayerLib
private function AllyAttack takes unit u, unit t, player p, integer id returns nothing
if IsUnitAlly(u,p) then
if p != Player(PLAYER_NEUTRAL_PASSIVE) and id != 'u000' and GetUnitAbilityLevel(t,'A0BY') == 0 then
if not Status.UnitHasStatus(STATUS_SLEEP,t) then
call BlzUnitInterruptAttack(u)
endif
endif
endif
endfunction
private function SetHeroTarget takes unit u, unit t returns nothing
if GetUnitAbilityLevel(u,'A09Q') != 0 then
call SetUnitData(u,"Target",GetUnitUserData(t))
endif
endfunction
private function onAttack takes nothing returns nothing
local unit u = GetAttacker()
local unit t = GetTriggerUnit()
local player p = GetOwningPlayer(t)
local integer id = GetUnitTypeId(u)
local unit temp
local group g
local Base b
local Team te
local real x
local real y
//Tower Attack
call AllyAttack(u,t,p,id)
call SetHeroTarget(u,t)
if GetUnitAbilityLevel(u,'A0BD') != 0 then
set b = Base.GetBaseFromTower(u)
if IsUnitType(t,UNIT_TYPE_HERO) then
if b.target != null then
if b.target != t then
call BlzUnitInterruptAttack(b.tower)
set b.target = null
endif
else
set g = NewGroup()
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),700.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if UnitAlive(temp) and not IsUnitType(temp,UNIT_TYPE_HERO) and not IsUnitType(temp,UNIT_TYPE_SUMMONED) and not IsUnitHidden(temp) and IsUnitAlly(temp,p) then
exitwhen true
endif
endloop
if temp != null then
call BlzUnitInterruptAttack(b.tower)
call IssueTargetOrderById(b.tower,ORDER_attack,temp)
endif
call ReleaseGroup(g)
set temp = null
set g = null
set u = null
set t = null
set p = null
endif
else
set b.target = null
endif
endif
//Hero Attacked
if IsUnitType(u,UNIT_TYPE_HERO) and GetUnitAbilityLevel(t,'B05Q') != 0 then
set x = GetUnitX(u)
set y = GetUnitY(u)
set te = GetPlayerTeamEx(p)
if Base[1].owner == te and Base[1].target == null then
if Distance(x,y,Base[1].x,Base[1].y) <= 700 then
call IssueTargetOrderById(Base[1].tower,ORDER_attack,u)
set Base[1].target = u
set u = null
set t = null
set p = null
return
endif
endif
if Base[2].owner == te and Base[2].target == null then
if Distance(x,y,Base[2].x,Base[2].y) <= 700 then
call IssueTargetOrderById(Base[2].tower,ORDER_attack,u)
set Base[2].target = u
set u = null
set t = null
set p = null
return
endif
endif
if Base[3].owner == te and Base[3].target == null then
if Distance(x,y,Base[3].x,Base[3].y) <= 700 then
call IssueTargetOrderById(Base[3].tower,ORDER_attack,u)
set Base[3].target = u
set u = null
set t = null
set p = null
return
endif
endif
if Base[4].owner == te and Base[4].target == null then
if Distance(x,y,Base[4].x,Base[4].y) <= 700 then
call IssueTargetOrderById(Base[4].tower,ORDER_attack,u)
set Base[4].target = u
set u = null
set t = null
set p = null
return
endif
endif
set u = null
set t = null
set p = null
return
endif
set u = null
set t = null
set p = null
endfunction
private function init takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED,function onAttack)
endfunction
endlibrary
library UnitData initializer init uses Table
globals
private HashTable HT
endglobals
function flushDummyData takes unit d returns nothing
call HT[GetHandleId(d)].flush()
endfunction
function flushUnitData takes unit u returns nothing
call HT[GetUnitUserData(u)].flush()
endfunction
function SetDummyData takes unit d, string label, integer data returns nothing
set HT[GetHandleId(d)][StringHash(label)] = data
endfunction
function GetDummyData takes unit d, string label returns integer
return HT[GetHandleId(d)][StringHash(label)]
endfunction
function SetUnitData takes unit u, string label, integer data returns nothing
set HT[GetUnitUserData(u)][StringHash(label)] = data
endfunction
function GetUnitData takes unit u, string label returns integer
return HT[GetUnitUserData(u)][StringHash(label)]
endfunction
function SetIntData takes integer id, integer label, integer data returns nothing
set HT[id][label] = data
endfunction
function GetIntData takes integer id, integer label returns integer
return HT[id][label]
endfunction
private function init takes nothing returns nothing
set HT = HashTable.create()
endfunction
endlibrary
library KPJ initializer init uses MiscLibrary
globals
private constant real TimeOut = 0.03125
private rect ENUM_RECT
private real X
private real Y
private real AREA
private item I
constant integer KPJ_TYPE_KNOCKBACK = 0
constant integer KPJ_TYPE_JUMP = 1
KPJConfig KPJDefaultConfig
KPJConfig KPJDefaultConfig2
KPJConfig KPJDefaultConfig3
KPJConfig KPJDefaultConfig4
Event EVENT_KPJ_END
Event EVENT_KPJ_IMPACT
Event EVENT_KPJ_PERIOD
endglobals
function CheckPathabilityTrickGet takes nothing returns nothing
set bj_rescueChangeColorUnit = bj_rescueChangeColorUnit or GetEnumItem() != I
endfunction
function CheckPathabilityTrick takes real x, real y returns boolean
local integer i = 30
local real X
local real Y
local rect r
call SetItemPosition(I, x, y)
set X = GetItemX(I) - x
set Y = GetItemY(I) - y
if X * X + Y * Y <= 100 then
return true
endif
set r = Rect(x - i, y - i, x + i, y + i)
set bj_rescueChangeColorUnit = false
call EnumItemsInRect(r, null, function CheckPathabilityTrickGet)
call RemoveRect(r)
set r = null
return bj_rescueChangeColorUnit
endfunction
function CheckPathability takes real x, real y returns boolean
local boolean b = CheckPathabilityTrick(x, y)
call SetItemVisible(I, false)
return b
endfunction
private struct KPJEvent extends array
static KPJUnit EventKPJUnit
public static method Setup takes nothing returns nothing
set EVENT_KPJ_END = Event.create()
set EVENT_KPJ_IMPACT = Event.create()
set EVENT_KPJ_PERIOD = Event.create()
endmethod
endstruct
function KillDest takes nothing returns nothing
local real x
local real y
set bj_destRandomCurrentPick = GetEnumDestructable()
if GetWidgetLife(bj_destRandomCurrentPick) > 0.405 and IsDestructableTree(GetDestructableTypeId(bj_destRandomCurrentPick)) then
set x = GetWidgetX(bj_destRandomCurrentPick)
set y = GetWidgetY(bj_destRandomCurrentPick)
if Distance(x,y,X,Y) <= AREA then
call KillDestructable(bj_destRandomCurrentPick)
endif
endif
endfunction
function EnumDest takes real x, real y, real area returns nothing
call MoveRectTo(ENUM_RECT,x,y)
set X = x
set Y = y
set AREA = area
call EnumDestructablesInRect(ENUM_RECT, null, function KillDest)
endfunction
private struct KPJLoop extends array
private static LinkedList list = 0
private static thistype ctl = 0
implement CTL
local Link h = list.head
local KPJUnit k
local Link temp
local real x
local real y
local real xn
local real yn
local boolean b
implement CTLExpire
loop
exitwhen h == 0
set temp = h.next
set k = h.data
set k.timeLeft = k.timeLeft - TimeOut
set k.distanceLeft = k.distanceLeft - k.velocity
if k.timeLeft > 0.00 then
if k.timeLeft < k.heightThreshold and k.heightThreshold != 0.00 then
call SetUnitFlyHeight(k.target,k.defaultHeight, (GetUnitFlyHeight(k.target) - k.defaultHeight)/k.heightThreshold)
set k.heightThreshold = 0.00
endif
set x = GetUnitX(k.target)
set xn = x + k.velocity * k.cos
set y = GetUnitY(k.target)
set yn = y + k.velocity * k.sin
set b = WorldBounds.IsPointInMap(xn,yn)
if k.killTrees then
call EnumDest(xn,yn,120)
endif
if (k.height == 0 and CheckPathability(xn,yn) and b) or (k.height != 0 and b) then
call SetUnitX(k.target,xn)
call SetUnitY(k.target,yn)
else
call SetUnitX(k.target,x)
call SetUnitY(k.target,y)
endif
if k.sfxModel != "" and k.height == 0 then
set k.sfxTimeLeft = k.sfxTimeLeft - TimeOut
if k.sfxTimeLeft <= 0 then
set k.sfxTimeLeft = k.sfxTime
call DestroyEffect(AddSpecialEffect(k.sfxModel,x,y))
endif
endif
set k.velocity = k.velocity - k.frictionA
else
call Remove(k)
endif
set h = temp
endloop
implement CTLEnd
public static method Add takes KPJUnit k returns nothing
set k.listIndex = list.add(k)
if list.size == 1 then
set ctl = thistype.create()
endif
endmethod
public static method Remove takes KPJUnit k returns nothing
call list.remove(k.listIndex)
call k.destroy()
if list.size == 0 then
if ctl != 0 then
call ctl.destroy()
set ctl = 0
endif
endif
endmethod
private static method onInit takes nothing returns nothing
set list = LinkedList.create()
endmethod
endstruct
struct KPJConfig extends array
implement Alloc
real friction
real gravity
boolean disable
boolean hardDisable
boolean killTrees
boolean ignorePath
boolean stopOnDead
string name
string sfxModel
real sfxTime
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
return this
endmethod
public method destroy takes nothing returns nothing
set friction = 0
set gravity = 0
set disable = false
set killTrees = false
set stopOnDead = false
set ignorePath = false
set name = ""
set sfxModel = ""
set sfxTime = 0
call this.deallocate()
endmethod
endstruct
struct KPJUnit extends array
implement Alloc
unit target
real angle
real distance
real time
real frictionA
real velocity
real height
real distanceLeft
real timeLeft
real heightThreshold
real cos
real sin
real sfxTimeLeft
real defaultHeight
integer KPJType
integer listIndex
integer data
string name
delegate KPJConfig config
public static method create takes unit u, real d, real a, real t, real h, KPJConfig c, integer ktype returns thistype
local thistype this = 0
local real r = 0
if GetUnitUserData(u) != 0 and t > 0 then
set this = GetUnitData(u,"KPJ"+I2S(ktype))
if this != 0 then
call KPJLoop.Remove(this)
endif
set this = thistype.allocate()
set target = u
set angle = a
set distance = d
set time = t
set config = c
set cos = Cos(angle)
set sin = Sin(angle)
set KPJType = ktype
set defaultHeight = GetUnitDefaultFlyHeight(u)
call SetUnitPathing(target,false)
if h != 0 then
set height = h
call MakeFly(target)
call SetUnitFlyHeight(target,defaultHeight + height,(height - defaultHeight) / (gravity * time))
set heightThreshold = ( 1 - gravity ) * time
endif
call Status.Add(STATUS_UNPATH,target,0,0)
if disable then
call Status.Add(STATUS_UNTURN,target,0,0)
elseif hardDisable then
call Status.Add(STATUS_STUN,target,0,0)
endif
set distanceLeft = distance
set r = (( 1.00 + c.friction ) * distance) / time
set frictionA = (r / time) * ((1.00 - (1 - c.friction)) * (TimeOut * TimeOut))
set velocity = r * TimeOut
set timeLeft = time
set sfxTimeLeft = sfxTime
call SetUnitData(u,"KPJ"+I2S(ktype),this)
call KPJLoop.Add(this)
endif
return this
endmethod
public method destroy takes nothing returns nothing
if disable then
call Status.Remove(STATUS_UNTURN,target)
elseif hardDisable then
call Status.Remove(STATUS_STUN,target)
endif
call SetUnitData(target,"KPJ"+I2S(KPJType),0)
if KPJType == 1 then
call SetUnitFlyHeight(target,defaultHeight,0.00)
endif
call Status.Remove(STATUS_UNPATH,target)
set heightThreshold = 0
set height = 0
set config = 0
set target = null
set angle = 0
set distance = 0
set time = 0
set data = 0
set name = ""
call this.deallocate()
endmethod
endstruct
private function init takes nothing returns nothing
set KPJDefaultConfig = KPJConfig.create()
set KPJDefaultConfig.friction = 0
set KPJDefaultConfig.gravity = 0.5
set KPJDefaultConfig.disable = true
set KPJDefaultConfig.hardDisable = false
set KPJDefaultConfig.killTrees = true
set KPJDefaultConfig.sfxModel = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
set KPJDefaultConfig.sfxTime = 0.10
set KPJDefaultConfig2 = KPJConfig.create()
set KPJDefaultConfig2.friction = 0
set KPJDefaultConfig2.gravity = 0.5
set KPJDefaultConfig2.disable = false
set KPJDefaultConfig2.hardDisable = true
set KPJDefaultConfig2.killTrees = false
set KPJDefaultConfig2.sfxModel = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
set KPJDefaultConfig2.sfxTime = 0.10
set KPJDefaultConfig3 = KPJConfig.create()
set KPJDefaultConfig3.friction = 0
set KPJDefaultConfig3.gravity = 0.5
set KPJDefaultConfig3.disable = false
set KPJDefaultConfig3.hardDisable = true
set KPJDefaultConfig3.killTrees = true
set KPJDefaultConfig3.sfxModel = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl"
set KPJDefaultConfig3.sfxTime = 0.10
set KPJDefaultConfig4 = KPJConfig.create()
set KPJDefaultConfig4.friction = 0
set KPJDefaultConfig4.gravity = 0.5
set KPJDefaultConfig4.disable = false
set KPJDefaultConfig4.hardDisable = false
set KPJDefaultConfig4.killTrees = true
set KPJDefaultConfig4.sfxModel = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl"
set KPJDefaultConfig4.sfxTime = 0.10
set ENUM_RECT = gg_rct_KPJRect
set I = CreateItem('ciri', Game.HIDE_X,Game.HIDE_Y)
endfunction
endlibrary
library TreeRespawn uses LinkedList, MiscLibrary
globals
private trigger DEATH_EVENT
private timer Revive_Timer
private LinkedList Revive_List
private destructable array Trees
endglobals
private function ReviveTree takes nothing returns nothing
local Link head = Revive_List.head
local Link temp
loop
exitwhen head == 0
set temp = head.next
call DestructableRestoreLife(Trees[head.data],50,true)
call Revive_List.remove(head)
set head = temp
endloop
endfunction
private function OnDeath takes nothing returns nothing
local destructable d = GetTriggerDestructable()
local integer c = Revive_List.size
set Trees[c] = d
call Revive_List.add(c)
if c == 0 then
call TimerStart(Revive_Timer,180.00,true,function ReviveTree)
endif
set d = null
endfunction
private function EnumDest takes nothing returns nothing
set bj_destRandomCurrentPick = GetEnumDestructable()
if IsDestructableTree(GetDestructableTypeId(bj_destRandomCurrentPick)) then
call TriggerRegisterDeathEvent(DEATH_EVENT,bj_destRandomCurrentPick)
endif
set bj_destRandomCurrentPick = null
endfunction
public function Setup takes nothing returns nothing
set DEATH_EVENT = CreateTrigger()
set Revive_List = LinkedList.create()
set Revive_Timer = CreateTimer()
call TriggerAddCondition(DEATH_EVENT,function OnDeath)
call EnumDestructablesInRect(WorldBounds.world,null,function EnumDest)
endfunction
endlibrary
library EnumLib
globals
public group TEMP_GROUP = CreateGroup()
private unit U = null
endglobals
function FILT_VALID_UNIT takes unit u returns boolean
return UnitAlive(u) and not IsUnitType(u,UNIT_TYPE_STRUCTURE) and not IsUnitType(u,UNIT_TYPE_MECHANICAL) and not IsUnitHidden(u) and GetUnitAbilityLevel(u,'A04R') == 0 and not Status.UnitHasStatus(STATUS_INVULNERABLE,u)
endfunction
function FILT_VALID_STRUCTURE takes unit u returns boolean
return UnitAlive(u) and IsUnitType(u,UNIT_TYPE_STRUCTURE) and not IsUnitHidden(u)
endfunction
function FILT_HERO_ALLIED takes unit u, player p returns boolean
return FILT_VALID_UNIT(u) and IsUnitType(u,UNIT_TYPE_HERO) and IsUnitAlly(u,p)
endfunction
function FILT_HERO_ENEMY takes unit u, player p returns boolean
return FILT_VALID_UNIT(u) and IsUnitType(u,UNIT_TYPE_HERO) and IsUnitEnemy(u,p)
endfunction
function FILT_UNIT_ALLIED takes unit u, player p returns boolean
return FILT_VALID_UNIT(u) and IsUnitAlly(u,p)
endfunction
function FILT_UNIT_ENEMY takes unit u, player p returns boolean
return FILT_VALID_UNIT(u) and IsUnitEnemy(u,p)
endfunction
function GetRandomEnemyHeroInAreaExcept takes player p, real x, real y, real range, unit ex returns unit
local unit ru = null
local unit temp
local integer c = 0
call GroupClear(TEMP_GROUP)
call GroupEnumUnitsInRange(TEMP_GROUP,x,y,range,null)
loop
set temp = FirstOfGroup(TEMP_GROUP)
exitwhen temp == null
call GroupRemoveUnit(TEMP_GROUP,temp)
if FILT_UNIT_ENEMY(temp,p) and IsUnitType(temp,UNIT_TYPE_HERO) and temp != ex then
set c = c + 1
if GetRandomInt(1,c) == 1 then
set ru = temp
endif
endif
endloop
set temp = null
set U = ru
set ru = null
return U
endfunction
function GetRandomHeroInAreaExcept takes player p, real x, real y, real range, unit ex returns unit
local unit ru = null
local unit temp
local integer c = 0
call GroupClear(TEMP_GROUP)
call GroupEnumUnitsInRange(TEMP_GROUP,x,y,range,null)
loop
set temp = FirstOfGroup(TEMP_GROUP)
exitwhen temp == null
call GroupRemoveUnit(TEMP_GROUP,temp)
if FILT_VALID_UNIT(temp) and IsUnitType(temp,UNIT_TYPE_HERO) and temp != ex then
set c = c + 1
if GetRandomInt(1,c) == 1 then
set ru = temp
endif
endif
endloop
set temp = null
set U = ru
set ru = null
return U
endfunction
function GetRandomAllyInArea takes player p, real x, real y, real range returns unit
local unit ru = null
local unit temp
local integer c = 0
call GroupClear(TEMP_GROUP)
call GroupEnumUnitsInRange(TEMP_GROUP,x,y,range,null)
loop
set temp = FirstOfGroup(TEMP_GROUP)
exitwhen temp == null
call GroupRemoveUnit(TEMP_GROUP,temp)
if IsUnitAlly(temp,p) and UnitAlive(temp) and not IsUnitType(temp,UNIT_TYPE_STRUCTURE) and not IsUnitHidden(temp) then
set c = c + 1
if GetRandomInt(1,c) == 1 then
set ru = temp
endif
endif
endloop
set temp = null
set U = ru
set ru = null
return U
endfunction
function GetRandomEnemyInAreaExcept takes player p, real x, real y, real range, unit ex returns unit
local unit ru = null
local unit temp
local integer c = 0
call GroupClear(TEMP_GROUP)
call GroupEnumUnitsInRange(TEMP_GROUP,x,y,range,null)
loop
set temp = FirstOfGroup(TEMP_GROUP)
exitwhen temp == null
call GroupRemoveUnit(TEMP_GROUP,temp)
if IsUnitEnemy(temp,p) and UnitAlive(temp) and not IsUnitType(temp,UNIT_TYPE_STRUCTURE) and not IsUnitHidden(temp) and temp != ex then
set c = c + 1
if GetRandomInt(1,c) == 1 then
set ru = temp
endif
endif
endloop
set temp = null
set U = ru
set ru = null
return U
endfunction
function GetRandomEnemyInArea takes player p, real x, real y, real range returns unit
local unit ru = null
local unit temp
local integer c = 0
call GroupClear(TEMP_GROUP)
call GroupEnumUnitsInRange(TEMP_GROUP,x,y,range,null)
loop
set temp = FirstOfGroup(TEMP_GROUP)
exitwhen temp == null
call GroupRemoveUnit(TEMP_GROUP,temp)
if IsUnitEnemy(temp,p) and UnitAlive(temp) and not IsUnitType(temp,UNIT_TYPE_STRUCTURE) and not IsUnitHidden(temp) then
set c = c + 1
if GetRandomInt(1,c) == 1 then
set ru = temp
endif
endif
endloop
set temp = null
set U = ru
set ru = null
return U
endfunction
endlibrary
library MiscLibrary initializer init uses UnitData, UnitStats, HeroAttributes
globals
private location Loc = Location(0,0)
unit EVENT_SPELL_UNIT
group BUFF_GROUP = CreateGroup()
group TEMP_GROUP = CreateGroup()
private Event EVENT_UNIT_SPELL_REFLECT
private Event EVENT_UNIT_SPELL_NEGATE
endglobals
function MakeFly takes unit u returns nothing
if UnitAddAbility(u, 'Amrf') then
call UnitRemoveAbility(u, 'Amrf')
endif
endfunction
/*function IsUnitBehindUnit takes unit u2, unit u1 returns boolean
local real face = GetUnitFacing(u1)
local real rangle = bj_RADTODEG*Atan2(GetUnitY(u2)-GetUnitY(u1),GetUnitX(u2)-GetUnitX(u1))
return not (RAbsBJ(face-rangle) < 90 or RAbsBJ(face-rangle-360) < 90)
endfunction
function IsPointInCone takes real x1, real y1, real x2, real y2, real f, real a returns boolean
return Cos(Atan2(y2-y1,x2-x1)-f) > Cos(a)
endfunction*/
//x1,y1: coordinates of the cone origin
//x2,y2: coordinates tested against the cone
//f: orientation of the cone in radians
//a: halved opening angle of the cone in radians (90° cone: bj_DEGTORAD*45)
// a = Width
// b = Tall
// w = Angle
// t = Some constant that ingreases to move the unit.
function GetUnitAttackDamage takes unit u returns integer
local real baseDamage = BlzGetUnitBaseDamage(u,0) + 1
local real addDamage = BonusStruct.GetTotalBonus(BONUS_TYPE_DAMAGE,u)
local integer dmg = 0
local real percent = 0
local integer alvl = GetUnitAbilityLevel(u,'A04W')
local Hero h
if alvl != 0 then
set percent = percent + 0.03 + 0.04 * alvl
endif
return R2I(baseDamage + ((baseDamage * percent) + 0.5)) + R2I(addDamage)
endfunction
function GetIconDisabledPath takes string s returns string
local integer i = StringLength(s)
local string p = SubString(s,0,34)
set s = SubString(s,35,i - 4)
set s = p + "Disabled\\DIS" + s
return s
endfunction
function IsPointInEllipse takes real xCenter, real yCenter, real x, real y, real a, real b, real angle returns boolean
local real cos = Cos(angle)
local real sin = Sin(angle)
local real dx = (x - xCenter)
local real dy = (y - yCenter)
local real tdx = cos * dx + sin * dy
local real tdy = sin * dx - cos * dy
return (tdx * tdx) / (a * a) + (tdy * tdy) / (b * b) <= 1
endfunction
function ParabolaZ takes real h, real d, real x returns real
return (4 * h / d) * (d - x) * (x / d)
endfunction
function IsDestructableTree takes integer id returns boolean
return id == 'B001' or id == 'B002' or id == 'B003' or id == 'B004' or id == 'B005' or id == 'B007' or id == 'B00C'
endfunction
function ParametricX takes real t, real a, real b, real w returns real
return a * Cos(t) * Cos(w) - b * Sin(t) * Sin(w)
endfunction
function ParametricY takes real t, real a, real b, real w returns real
return a * Cos(t) * Sin(w) + b * Sin(t) * Cos(w)
endfunction
function GetLocZ takes real x, real y returns real
call MoveLocation(Loc,x,y)
return GetLocationZ(Loc)
endfunction
function GetUnitZ takes unit u returns real
return GetLocZ(GetUnitX(u),GetUnitY(u)) + GetUnitFlyHeight(u)
endfunction
function Distance takes real xa, real ya, real xb, real yb returns real
local real dx = xb - xa
local real dy = yb - ya
return SquareRoot(dx * dx + dy * dy)
endfunction
function DistanceBetweenUnits takes unit a, unit b returns real
local real dx = GetUnitX(b) - GetUnitX(a)
local real dy = GetUnitY(b) - GetUnitY(a)
return SquareRoot(dx * dx + dy * dy)
endfunction
function Angle takes real x1,real y1,real x2, real y2 returns real
return Atan2(y2 - y1, x2 - x1)
endfunction
function AngleBetweenUnits takes unit a, unit b returns real
return Atan2(GetUnitY(b) - GetUnitY(a), GetUnitX(b) - GetUnitX(a))
endfunction
function IsUnitBehindOfTarget takes unit u, unit t returns boolean
local real r1 = Angle(GetUnitX(t),GetUnitY(t),GetUnitX(u),GetUnitY(u))
local real r2 = GetUnitFacing(t) * bj_DEGTORAD
local real r3 = Acos(Cos(r1-r2)) * bj_RADTODEG
return r3 > 105
endfunction
function SetBuildingFacing takes unit build, real angle returns nothing
call SetUnitTurnSpeed(build,1)
call SetUnitFacing(build,angle)
call SetUnitTurnSpeed(build,0)
endfunction
function UnitResetAbilityCooldown takes unit u, integer id returns nothing
local integer l = GetUnitAbilityLevel(u,id)
call UnitRemoveAbility(u,id)
call UnitAddAbility(u,id)
call SetUnitAbilityLevel(u,id,l)
call UnitMakeAbilityPermanent(u,true,id)
endfunction
function SelectUnitForPlayer takes unit u, player p, boolean flag returns nothing
if Game.LocalPlayer == p then
call ClearSelection()
call SelectUnit(u,flag)
endif
endfunction
function CreateTextTagBounty takes player p, real x, real y, string txt, real size returns nothing
local texttag t = null
local real angle = 90 * bj_DEGTORAD
local real r = GetRandomReal(-30,30)
if Game.LocalPlayer == p then
set t = CreateTextTag()
call SetTextTagPermanent(t,false)
call SetTextTagPos(t,x + r,y,0)
call SetTextTagText(t,txt,TextTagSize2Height(size))
call SetTextTagVelocity(t,TextTagSpeed2Velocity(55.00) * Cos(angle),TextTagSpeed2Velocity(55.00) * Sin(angle))
call SetTextTagLifespan(t,2.0)
call SetTextTagFadepoint(t,1.0)
call SetTextTagVisibility(t,true)
set t = null
endif
endfunction
function AddPlayerGold takes player p, integer amount returns nothing
local integer cg = GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD)
local PlayerBounty pb = PlayerBounty[GetPlayerId(p)]
if amount > 0 then
set amount = R2I(amount * pb.bountyPercent / 100)
endif
set cg = cg + amount
call SetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD,cg)
if amount > 0 then
set Players[GetPlayerId(p)].totalGold = Players[GetPlayerId(p)].totalGold + amount
endif
endfunction
function AddPlayersGold takes Team t, integer g, boolean toDead, player ex returns nothing
local integer i
local integer j
local integer exid = GetPlayerId(ex)
if t == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
exitwhen i > j
if Players[i].isPlaying and i != exid then
if UnitAlive(Players[i].hero.hero) or toDead then
call CreateTextTagForPlayer.evaluate(Player(i),GetUnitX(Players[i].hero.hero),GetUnitY(Players[i].hero.hero),GOLD_COLOR+"+"+I2S(g)+"|r",14)
call AddPlayerGold(Player(i),g)
endif
endif
set i = i + 1
endloop
endfunction
function AddTeamGold takes Team team, integer amount returns nothing
local integer i
local integer j
if team == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
exitwhen i > j
if Players[i].isPlaying then
call AddPlayerGold(Player(i),amount)
endif
set i = i + 1
endloop
endfunction
function AddTeamExp takes Team team, integer amount returns nothing
local integer i
local integer j
local PlayerBounty pb
if team == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
exitwhen i > j
set pb = PlayerBounty[i]
call pb.ExpBountyFixed(amount * pb.expPercent / 100)
set i = i + 1
endloop
endfunction
function AddHeroBarPercentExp takes unit u, integer flat, integer percent returns nothing
local integer exp = 100 + (100 * GetHeroLevel(u))
local PlayerBounty pb = PlayerBounty[GetPlayerId(GetOwningPlayer(u))]
set exp = exp * percent / 100
call pb.ExpBountyFixed(flat + exp)
endfunction
function AddHeroPercentExp takes unit u, integer flat, integer percent returns nothing
local integer lvl = GetHeroLevel(u)
local integer exp = 0
local PlayerBounty pb = PlayerBounty[GetPlayerId(GetOwningPlayer(u))]
loop
exitwhen lvl == 0
set exp = exp + (100 + (100 * lvl))
set lvl = lvl - 1
endloop
set exp = exp * percent / 100
call pb.ExpBountyFixed(flat + exp)
endfunction
function AddTeamBarPercentExp takes Team team, integer bonus, integer amount returns nothing
local integer i
local integer j
local Hero h
if team == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
exitwhen i > j
set h = Players[i].hero
if h != 0 then
call AddHeroBarPercentExp(h.hero,bonus,amount)
endif
set i = i + 1
endloop
endfunction
function GetUnitTeam takes unit u returns Team
local player p = GetOwningPlayer(u)
local integer i = GetPlayerId(p)
if (i >= 2 and i <= 6) or i == 0 then
set p = null
return Team[1]
endif
if (i >= 7 and i <= 11) or i == 1 then
set p = null
return Team[2]
endif
set p = null
return 0
endfunction
function UnitAddMp takes unit u, real amount returns nothing
if GetUnitState(u,UNIT_STATE_MAX_MANA) == 0 then
return
endif
call SetUnitState(u,UNIT_STATE_MANA,GetUnitState(u,UNIT_STATE_MANA) + amount)
endfunction
function UnitRemoveMp takes unit u, real amount returns nothing
if GetUnitState(u,UNIT_STATE_MAX_MANA) == 0 then
return
endif
call SetUnitState(u,UNIT_STATE_MANA,GetUnitState(u,UNIT_STATE_MANA) - amount)
endfunction
function UnitAddHp takes unit u, real amount returns nothing
call SetWidgetLife(u,GetWidgetLife(u) + amount)
endfunction
function UnitRemoveHp takes unit u, real amount returns nothing
local real l = GetWidgetLife(u) - amount
if l < 0.405 then
set l = 1
endif
call SetWidgetLife(u,l)
endfunction
function PlayerPingMinimap takes player p, real x, real y, real d, integer r, integer g, integer b returns nothing
if Game.LocalPlayer == p then
call PingMinimapEx(x,y,d,r,g,b,false)
call StartSound(gg_snd_Ping)
endif
endfunction
function TeamPingMinimap takes Team t, real x, real y, real d, integer r, integer g, integer b returns nothing
if IsPlayerInForce(Game.LocalPlayer,t.forceP) then
call PingMinimapEx(x,y,d,r,g,b,false)
call StartSound(gg_snd_Ping)
endif
endfunction
function PlayerHasResources takes player p, integer g, integer h returns boolean
if GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD) >= g then
if GetPlayerState(p,PLAYER_STATE_RESOURCE_LUMBER) >= h then
return true
endif
endif
return false
endfunction
function CastDummyWave takes unit d, integer order, real x, real y returns nothing
local real cx = GetUnitX(d)
local real cy = GetUnitY(d)
local real a = Angle(cx,cy,x,y)
local real cosa = 20 * Cos(a)
local real sina = 20 * Sin(a)
local integer i = 0
loop
exitwhen IssuePointOrderById(d,order,x,y) or i > 20
call SetUnitX(d,GetUnitX(d) + cosa)
call SetUnitY(d,GetUnitY(d) + sina)
set x = x + cosa
set y = y + sina
set i = i + 1
endloop
if i > 20 then
call UnitRemoveAbility(d,'Avul')
call IssueTargetOrderById(d,order,d)
call UnitAddAbility(d,'Avul')
endif
endfunction
function PlaySoundForTeam takes Team t, sound s returns nothing
if t.isPlayerInTeam(Game.LocalPlayer) then
call StartSound(s)
endif
endfunction
function PlaySoundForPlayer takes player p, sound s returns nothing
if p == Game.LocalPlayer then
call StartSound(s)
endif
endfunction
function CreateTextTagForAll takes real x, real y, string txt, real size returns nothing
local texttag t = CreateTextTag()
local real angle = 90 * bj_DEGTORAD
local real offset = 1.00 * (StringLength(txt)/2)
call SetTextTagPermanent(t,false)
call SetTextTagPos(t,x-offset,y,120.00)
call SetTextTagText(t,txt,TextTagSize2Height(size))
call SetTextTagVelocity(t,TextTagSpeed2Velocity(45.00) * Cos(angle),TextTagSpeed2Velocity(45.00) * Sin(angle))
call SetTextTagLifespan(t,3.0)
call SetTextTagFadepoint(t,1.5)
call SetTextTagVisibility(t,true)
set t = null
endfunction
function AddStatusNegation takes unit u returns nothing
local integer ins = GetUnitData(u,"StatusNegation") + 1
if ins == 1 then
call UnitAddAbility(u,'A066')
call UnitMakeAbilityPermanent(u,true,'A066')
endif
call SetUnitData(u,"StatusNegation",ins)
endfunction
function AddSpellNegation takes unit u returns nothing
local integer ins = GetUnitData(u,"SpellNegation") + 1
if ins == 1 then
call UnitAddAbility(u,'A028')
call UnitMakeAbilityPermanent(u,true,'A028')
endif
call SetUnitData(u,"SpellNegation",ins)
endfunction
function AddSpellReflection takes unit u returns nothing
local integer ins = GetUnitData(u,"SpellReflection") + 1
if ins == 1 then
call UnitAddAbility(u,'A04E')
call UnitMakeAbilityPermanent(u,true,'A04E')
endif
call SetUnitData(u,"SpellReflection",ins)
endfunction
function RemoveSpellReflection takes unit u returns nothing
local integer ins = GetUnitData(u,"SpellReflection") - 1
if ins <= 0 then
set ins = 0
call UnitRemoveAbility(u,'A04E')
call UnitRemoveAbility(u,'B01M')
endif
call SetUnitData(u,"SpellReflection",ins)
endfunction
function RemoveSpellNegation takes unit u returns nothing
local integer ins = GetUnitData(u,"SpellNegation") - 1
if ins <= 0 then
set ins = 0
call UnitRemoveAbility(u,'A028')
call UnitRemoveAbility(u,'B016')
endif
call SetUnitData(u,"SpellNegation",ins)
endfunction
function RemoveStatusNegation takes unit u returns nothing
local integer ins = GetUnitData(u,"StatusNegation") - 1
if ins <= 0 then
set ins = 0
call UnitRemoveAbility(u,'A066')
call UnitRemoveAbility(u,'B02B')
endif
call SetUnitData(u,"StatusNegation",ins)
endfunction
function TriggerSpellNegation takes unit u returns boolean
local integer ins = GetUnitData(u,"SpellNegation")
local Item it
if ins > 0 then
call StartSound(gg_snd_SpellNegate)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\SpellShieldAmulet\\SpellShieldCaster.mdl",u,"chest"))
call CreateTextTagForAll(GetUnitX(u),GetUnitY(u),"|c0012ebe6[Spell Negated]|r",15)
set it = GetUnitItemOfType.evaluate(u,'bzbf')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(it.wielder,'A068') == 0 then
call ArmorBuffs_AntiMageCD.evaluate(it)
endif
endif
set EVENT_SPELL_UNIT = u
call EVENT_UNIT_SPELL_NEGATE.fire()
call RemoveSpellNegation(u)
return true
endif
return false
endfunction
function TriggerSpellReflection takes unit u returns boolean
local integer ins = GetUnitData(u,"SpellReflection")
local Buff b
if ins > 0 then
call StartSound(gg_snd_SpellReflect)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\SpellShieldAmulet\\SpellShieldCaster.mdl",u,"chest"))
call CreateTextTagForAll(GetUnitX(u),GetUnitY(u),"|c0012ebe6[Spell Reflected]|r",15)
set b = GetUnitBuff(u,Reflect.buff)
if b != 0 then
set b.int = 1
call UnitRemoveBuff(u,Reflect.buff)
endif
set EVENT_SPELL_UNIT = u
call EVENT_UNIT_SPELL_REFLECT.fire()
call RemoveSpellReflection(u)
return true
endif
return false
endfunction
function TriggerStatusNegation takes integer st, unit u returns boolean
local integer ins = GetUnitData(u,"StatusNegation")
local Item it
if ins > 0 then
call StartSound(gg_snd_StatusNegate)
call DestroyEffect(AddSpecialEffectTarget("Units\\NightElf\\Wisp\\WispExplode.mdl",u,"overhead"))
call RemoveStatusNegation(u)
set it = GetUnitItemOfType.evaluate(u,'rde1')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(it.wielder,'A061') == 0 then
call TrinketBuffs_DefibrillatorCD.evaluate(st,it)
endif
endif
return true
endif
return false
endfunction
function CreateTextTagForPlayer takes player p, real x, real y, string txt, real size returns nothing
local texttag t = null
local real angle = 90 * bj_DEGTORAD
local real offset = 1.00 * (StringLength(txt)/2)
if Game.LocalPlayer == p then
set t = CreateTextTag()
call SetTextTagPermanent(t,false)
call SetTextTagPos(t,x-offset,y,120.00)
call SetTextTagText(t,txt,TextTagSize2Height(size))
call SetTextTagVelocity(t,TextTagSpeed2Velocity(45.00) * Cos(angle),TextTagSpeed2Velocity(45.00) * Sin(angle))
call SetTextTagLifespan(t,3.0)
call SetTextTagFadepoint(t,1.5)
call SetTextTagVisibility(t,true)
set t = null
endif
endfunction
function AddDummyAttackCounter takes unit u, integer c returns nothing
local real hp = GetWidgetLife(u)
local integer hits = c * 2
if GetUnitAbilityLevel(u,'A09X') == 0 then
return
endif
set hp = hp + hits
if hp > BlzGetUnitMaxHP(u) then
call BlzSetUnitMaxHP(u,R2I(hp))
endif
call SetUnitState(u,UNIT_STATE_LIFE,hp)
endfunction
function IsUnitDisabled takes unit u returns boolean
return GetUnitAbilityLevel(u,Game.FLAG_DISABLED) > 1
endfunction
function IsUnitMagicImmune takes unit u returns boolean
return Status.UnitHasStatus(STATUS_SPELL_IMMUNITY,u) or GetUnitAbilityLevel(u,'ACmi') != 0
endfunction
function GetUnitMissingLife takes unit u returns real
return GetUnitState(u,UNIT_STATE_MAX_LIFE) - GetUnitState(u,UNIT_STATE_LIFE)
endfunction
function GetUnitMissingMana takes unit u returns real
return GetUnitState(u,UNIT_STATE_MAX_MANA) - GetUnitState(u,UNIT_STATE_MANA)
endfunction
function RecoverArea takes unit u, real area, real amountL, real amountM, boolean life, boolean mana, string sfx, string at returns nothing
local player p = GetOwningPlayer(u)
local unit temp
call GroupEnumUnitsInRange(TEMP_GROUP,GetUnitX(u),GetUnitY(u),area,null)
loop
set temp = FirstOfGroup(TEMP_GROUP)
exitwhen temp == null
call GroupRemoveUnit(TEMP_GROUP,temp)
if FILT_UNIT_ALLIED(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(sfx,temp,at))
if life then
call UnitAddHp(temp,amountL)
endif
if mana then
call UnitAddMp(temp,amountM)
endif
endif
endloop
call GroupClear(TEMP_GROUP)
set p = null
endfunction
function DamageArea takes unit u, real area, real amount, integer dmgType, boolean allies, boolean enemies, string sfx, string at returns nothing
local player p = GetOwningPlayer(u)
local unit temp
call GroupEnumUnitsInRange(TEMP_GROUP,GetUnitX(u),GetUnitY(u),area,null)
loop
set temp = FirstOfGroup(TEMP_GROUP)
exitwhen temp == null
call GroupRemoveUnit(TEMP_GROUP,temp)
if allies then
if FILT_UNIT_ALLIED(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(sfx,temp,at))
call CodeDamage.Damage(u,temp,amount,dmgType,"",0,0)
endif
endif
if enemies then
if FILT_UNIT_ENEMY(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(sfx,temp,at))
call CodeDamage.Damage(u,temp,amount,dmgType,"",0,0)
endif
endif
endloop
call GroupClear(TEMP_GROUP)
set p = null
endfunction
function ApplyBuffArea takes unit u, real area, real duration, BuffData b, boolean allies, boolean enemies, integer d returns nothing
local player p = GetOwningPlayer(u)
local unit temp
call GroupEnumUnitsInRange(BUFF_GROUP,GetUnitX(u),GetUnitY(u),area,null)
loop
set temp = FirstOfGroup(BUFF_GROUP)
exitwhen temp == null
call GroupRemoveUnit(BUFF_GROUP,temp)
if allies then
if FILT_UNIT_ALLIED(temp,p) then
call UnitAddBuff(temp,u,duration,b,d,0)
endif
endif
if enemies then
if FILT_UNIT_ENEMY(temp,p) then
call UnitAddBuff(temp,u,duration,b,d,0)
endif
endif
endloop
call GroupClear(BUFF_GROUP)
set p = null
endfunction
function RefreshHeroInfo takes unit u returns nothing
local real b = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_BLOCK,u)
local real e = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_EVASION,u)
local real r = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,u)
local real bp = UnitStat.GetStat(STAT_BLOCK_CHANCE,u)
local real ep = UnitStat.GetStat(STAT_EVASION,u)
local real rp = UnitStat.GetStat(STAT_RESISTANCE,u)
local real asr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_ATTACK_STRENGTH,u)
local real spr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,u)
local real asb = UnitStat.GetStat(STAT_ATTACK_STRENGTH,u)
local real ssr = UnitStat.GetStat(STAT_SPELL_STRENGTH,u)
local real lrr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_LIFE_REGEN,u)
local real mrr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_MANA_REGEN,u)
local Hero h
local real aas
local real ams
local real im
local real imr
local real sl
local real slr
local real ma
local real ar
local string s = ""
local integer pid = GetPlayerId(GetOwningPlayer(u))
if IsUnitType(u,UNIT_TYPE_HERO) then
set h = GetUnitData(u,"HeroIndex")
set aas = GetHeroAgiAttackSpeed(h)
set ams = GetHeroAgiMoveSpeed(h)
set im = GetHeroIntMana(h)
set imr = GetHeroIntRegen(h)
set sl = GetHeroStrLife(h)
set slr = GetHeroStrRegen(h)
set ma = GetHeroAttArmor(h)
set ar = Formula.CalcArmorReduction(BlzGetUnitArmor(u)) * 100
set s = "|c00f4a460Bonus of Attributes:|r|n"
set s = s + "|cff6495ed - Agility AS:|r "+R2SW(aas,0,2)+"|n"
set s = s + "|cff6495ed - Agility MS:|r "+R2SW(ams,0,2)+"|n"
set s = s + "|cff6495ed - Intelligence MP Bonus:|r "+R2SW(im,0,2)+"|n"
set s = s + "|cff6495ed - Intelligence Mana Regen:|r "+R2SW(imr,0,2)+"|n"
set s = s + "|cff6495ed - Strength HP Bonus:|r "+R2SW(sl,0,2)+"|n"
set s = s + "|cff6495ed - Strength Life Regen:|r "+R2SW(slr,0,2)+"|n"
set s = s + "|cff6495ed - Main Attribute Armor Bonus:|r "+R2SW(ma,0,2)+"|n"
set s = s + "|cff6495ed - Armor Damage Reduction:|r "+R2SW(ar,0,2)+"%|n"
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(u,'A01M'),ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,s)
endif
set s = ""
set s = s + "|c00f4a460Bonus of Special Stats:|r|n"
set s = s + "|cff6495ed - Block Rating:|r "+R2SW(b,0,2)+" ("+R2SW(bp,0,2)+"%)|n"
set s = s + "|cff6495ed - Evasion Rating:|r "+R2SW(e,0,2)+" ("+R2SW(ep,0,2)+"%)|n"
set s = s + "|cff6495ed - Resistance Rating:|r "+R2SW(r,0,2)+" ("+R2SW(rp*100,0,2)+"%)|n"
set s = s + "|cff6495ed - Attack Strength Rating:|r "+R2SW(asr,0,2)+" (-"+R2SW(asb,0,2)+"%) Reduction|n"
set s = s + "|cff6495ed - Spell Strength Rating:|r "+R2SW(spr,0,2)+" (-"+R2SW(ssr,0,2)+"%) Reduction|n"
set s = s + "|cff6495ed - Life Regen:|r "+R2SW(lrr,0,2)+" Hp every second|n"
set s = s + "|cff6495ed - Mana Regen:|r "+R2SW(mrr,0,2)+" Mp every second|n"
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(u,'A04C'),ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,s)
call UnitAddAbility(u,'Asph')
call UnitRemoveAbility(u,'Asph')
endfunction
function UpdatePerkIcon takes unit u, integer lvl, string bonus returns nothing
local string s = BlzGetAbilityStringLevelField(BlzGetUnitAbility(u,'A01N'),ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0)
set s = s + "|n" + "|cff6495ed - Level "+I2S(lvl)+"|r"+" "+bonus
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(u,'A01N'),ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,s)
endfunction
function RegisterSpellReflectEvent takes code c returns nothing
call EVENT_UNIT_SPELL_REFLECT.register(Filter(c))
endfunction
function RegisterSpellNegateEvent takes code c returns nothing
call EVENT_UNIT_SPELL_NEGATE.register(Filter(c))
endfunction
private function init takes nothing returns nothing
set EVENT_UNIT_SPELL_REFLECT = Event.create()
set EVENT_UNIT_SPELL_NEGATE = Event.create()
endfunction
endlibrary
library HeroRegen uses InCombat, MiscLibrary
globals
private constant real REGEN_PERIOD = 0.10
endglobals
function DisableHeroRegen takes unit u, boolean life, boolean mana returns nothing
local integer i = GetUnitData(u,"RLife")
local integer j = GetUnitData(u,"RMana")
if life then
call SetUnitData(u,"RLife",i + 1)
elseif i != 0 then
call SetUnitData(u,"RLife",i - 1)
endif
if mana then
call SetUnitData(u,"RMana",j + 1)
elseif j != 0 then
call SetUnitData(u,"RMana",j - 1)
endif
endfunction
struct HeroRegenPeriod extends array
private static integer array UnitsID
private static integer Count = 0
private static timer TIMER
private static real time = 0
private static method Loop takes nothing returns nothing
local real regenadd
local real life
local real mana
local unit u
local integer i = 0
local integer cr
set time = time + REGEN_PERIOD
loop
exitwhen i == Count
set u = Index[UnitsID[i]].u
if time >= 0.50 then
call RefreshHeroInfo(u)
endif
if UnitAlive(u) then
if GetUnitData(u,"RLife") == 0 then
set regenadd = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_LIFE_REGEN,u)
if regenadd < 0 then
call UnitRemoveHp(u,-regenadd / 10)
else
call UnitAddHp(u,regenadd / 10)
endif
endif
if GetUnitData(u,"RMana") == 0 then
set regenadd = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_MANA_REGEN,u)
if regenadd < 0 then
call UnitRemoveMp(u,-regenadd / 10)
else
call UnitAddMp(u,regenadd / 10)
endif
endif
endif
set i = i + 1
endloop
if time >= 0.50 then
set time = 0.00
endif
set u = null
endmethod
public static method AddUnit takes integer id returns nothing
set UnitsID[Count] = id
set Count = Count + 1
if Count == 1 then
set TIMER = CreateTimer()
call TimerStart(TIMER,REGEN_PERIOD,true,function thistype.Loop)
endif
endmethod
endstruct
endlibrary
library UnitStats uses Table
globals
constant real BLOCK_DAMAGE_HEAL = 0.04
constant real BLOCK_DAMAGE_PERCENT = 0.70
private constant real BLOCK_CHANCE_RATING2POINT = 8
private constant real BLOCK_CHANCEXPOINT = 1.25
private constant real EVASION_CHANCE_RATING2POINT = 8
private constant real EVASION_CHANCEXPOINT = 1.25
private constant real MAGIC_RESISTANCE_RATING2POINT = 8
private constant real MAGIC_RESISTANCEXPOINT = 1.25
private constant real SPELLSTR_RATING2POINT = 8
private constant real SPELLSTR_MAGIC_REDUCTIONXPOINT = 1.25
private constant real ATTACKSTR_RATING2POINT = 8
private constant real ATTACKSTR_EVASION_REDUCTIONXPOINT = 1.25
private constant real ATTACKSTR_BLOCK_REDUCTIONXPOINT = 1.25
//max values
public constant real MAX_BLOCK_CHANCE = 90.00
public constant real MAX_EVASION_CHANCE = 70.00
public constant real MAX_RESISTANCE = 80.00
endglobals
globals
constant integer STAT_BLOCK_CHANCE = 10
constant integer STAT_EVASION = 11
constant integer STAT_RESISTANCE = 12
constant integer STAT_ATTACK_STRENGTH = 13
constant integer STAT_SPELL_STRENGTH = 14
endglobals
private module Formulas
public static method GetBlockChance takes real block returns real
return block / BLOCK_CHANCE_RATING2POINT * BLOCK_CHANCEXPOINT
endmethod
public static method GetEvasionChance takes real evasion returns real
return evasion / EVASION_CHANCE_RATING2POINT * EVASION_CHANCEXPOINT
endmethod
public static method GetResistancePercent takes real resistance returns real
local real r = resistance / MAGIC_RESISTANCE_RATING2POINT * MAGIC_RESISTANCEXPOINT
return r / 100
endmethod
public static method GetAttackStrReduction takes real attackstr returns real
return attackstr / ATTACKSTR_RATING2POINT * ATTACKSTR_BLOCK_REDUCTIONXPOINT
endmethod
public static method GetSpellStrReduction takes real spellstr returns real
return spellstr / SPELLSTR_RATING2POINT * SPELLSTR_MAGIC_REDUCTIONXPOINT
endmethod
endmodule
struct UnitStat extends array
implement Formulas
public static method GetStat takes integer statID, unit target returns real
if statID == STAT_BLOCK_CHANCE then
return GetBlockChance(BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_BLOCK,target))
elseif statID == STAT_EVASION then
return GetEvasionChance(BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_EVASION,target))
elseif statID == STAT_RESISTANCE then
return GetResistancePercent(BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,target))
elseif statID == STAT_ATTACK_STRENGTH then
return GetAttackStrReduction(BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_ATTACK_STRENGTH,target))
elseif statID == STAT_SPELL_STRENGTH then
return GetSpellStrReduction(BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,target))
endif
return 0.
endmethod
public static method GetModifiedStat takes integer statID, real mod returns real
if statID == STAT_BLOCK_CHANCE then
return GetBlockChance(mod)
elseif statID == STAT_EVASION then
return GetEvasionChance(mod)
elseif statID == STAT_RESISTANCE then
return GetResistancePercent(mod)
elseif statID == STAT_ATTACK_STRENGTH then
return GetAttackStrReduction(mod)
elseif statID == STAT_SPELL_STRENGTH then
return GetSpellStrReduction(mod)
endif
return 0.
endmethod
endstruct
endlibrary
library HeroAttributes
globals
private constant real UPDATE_PERIOD = 0.50
private constant real REGEN_PER_POINT = 0.05
private constant real AS_PER_POINT = 0.50
private constant real ARMOR_PER__MAIN_POINT = 0.10
endglobals
function GetHeroAgiAttackSpeed takes Hero h returns real
return GetHeroAgi(h.hero,true) * 0.50
endfunction
function GetHeroAgiMoveSpeed takes Hero h returns real
return GetHeroAgi(h.hero,true) * 0.10
endfunction
function GetHeroIntMana takes Hero h returns real
return GetHeroInt(h.hero,true) * 15.00
endfunction
function GetHeroIntRegen takes Hero h returns real
return h.heroAtt.intRegen
endfunction
function GetHeroStrLife takes Hero h returns real
return GetHeroStr(h.hero,true) * 20.00
endfunction
function GetHeroStrRegen takes Hero h returns real
return h.heroAtt.strRegen
endfunction
function GetHeroAttArmor takes Hero h returns real
return h.heroAtt.mainArmor
endfunction
struct HeroAtt extends array
implement Alloc
real intRegen
real strRegen
integer agiSpeed
real mainArmor
Hero H
static integer array instances
static integer count = 0
public method recalculate takes nothing returns nothing
local integer p = GetHeroAgi(H.hero,true)
local integer mainA
local real bonus2
local real bonus
local integer bonusi
if H.PrimaryAttribute == 1 then
set mainA = p
endif
set bonusi = R2I(p * AS_PER_POINT)
if bonusi != agiSpeed then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,H.hero,bonusi - agiSpeed,0,false)
set agiSpeed = bonusi
endif
set p = GetHeroInt(H.hero,true)
if H.PrimaryAttribute == 2 then
set mainA = p
endif
set bonus = p * REGEN_PER_POINT
if bonus != intRegen then
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,H.hero,bonus - intRegen,0)
set intRegen = bonus
endif
set p = GetHeroStr(H.hero,true)
if H.PrimaryAttribute == 3 then
set mainA = p
endif
set bonus = p * REGEN_PER_POINT
if bonus != strRegen then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,H.hero,bonus - strRegen,0)
set strRegen = bonus
endif
set bonus = I2R(R2I(mainA * ARMOR_PER__MAIN_POINT))
if bonus != mainArmor then
set bonus2 = BlzGetUnitArmor(H.hero) - H.Armor - mainArmor
call BlzSetUnitArmor(H.hero,H.Armor + bonus + bonus2)
set mainArmor = bonus
endif
endmethod
private static method Update takes nothing returns nothing
local integer i = 0
local thistype att
loop
exitwhen i == thistype.count
set att = thistype.instances[i]
call att.recalculate()
set i = i + 1
endloop
endmethod
public static method create takes Hero h returns thistype
local thistype this = thistype.allocate()
set H = h
set instances[count] = this
set count = count + 1
set intRegen = 0
set strRegen = 0
set mainArmor = 0
call recalculate()
if count == 1 then
call TimerStart(CreateTimer(),UPDATE_PERIOD,true,function thistype.Update)
endif
return this
endmethod
endstruct
endlibrary
library Bonus initializer Init uses PlayerLib
globals
//Dummy Bonuses for Items
constant integer BONUS_TYPE_ALL_STATS = -1
constant integer BONUS_TYPE_MAIN_ATTRIBUTE = 0
//Normal Bonuses
constant integer BONUS_TYPE_STRENGTH = 1
constant integer BONUS_TYPE_AGILITY = 2
constant integer BONUS_TYPE_INTELLIGENCE = 3
constant integer BONUS_TYPE_DAMAGE = 4
constant integer BONUS_TYPE_HP = 5
constant integer BONUS_TYPE_MP = 6
constant integer BONUS_TYPE_SIGHT_RANGE = 7
constant integer BONUS_TYPE_ATTACK_SPEED = 8
constant integer BONUS_TYPE_ARMOR = 9
constant integer BONUS_TYPE_BLOCK = 10
constant integer BONUS_TYPE_EVASION = 11
constant integer BONUS_TYPE_RESISTANCE = 12
constant integer BONUS_TYPE_SPELL_STRENGTH = 13
constant integer BONUS_TYPE_ATTACK_STRENGTH= 14
constant integer BONUS_TYPE_MANA_REGEN = 15
constant integer BONUS_TYPE_LIFE_REGEN = 16
constant integer BONUS_TYPE_LIFESTEAL = 17
constant integer BONUS_TYPE_SPELL_LIFESTEAL = 18
constant integer BONUS_TYPE_CD_REDUCTION = 19
constant integer BONUS_TYPE_CD_REDUCTION_F = 20
//Abilities
private integer array ABILITY_1
private integer array ABILITY_10
private integer array ABILITY_100
private constant integer BONUS_COUNT_ABILITY= 9
private constant integer BONUS_COUNT = 20
private constant integer BONUS_LIMIT_A = 999
private constant integer BONUS_LIMIT_B = 9999
private hashtable T = InitHashtable()
endglobals
struct BonusStruct extends array
public static method ResetAll takes unit u, integer index returns nothing
local integer i = 1
loop
if i < 10 then
if i == BONUS_TYPE_HP or i == BONUS_TYPE_MP or i == BONUS_TYPE_SIGHT_RANGE then
else
call UnitRemoveAbility(u,ABILITY_1[i])
call UnitRemoveAbility(u,ABILITY_10[i])
call UnitRemoveAbility(u,ABILITY_100[i])
endif
call SaveReal(T,i,index * 16 + 1,0)
call SaveReal(T,i,index * 16 + 3,0)
call SaveReal(T,i,index * 16 + 2,0)
call SaveReal(T,i,index * 16 + 4,0)
call SaveReal(T,i,index * 16 + 5,0)
call SaveReal(T,i,index * 16 + 6,0)
else
call SaveReal(T,i,index * 16 + 1,0)
call SaveReal(T,i,index * 16 + 3,0)
call SaveReal(T,i,index * 16 + 2,0)
endif
set i = i + 1
exitwhen i > 21
endloop
endmethod
public static method CopyBonusIllusion takes unit original, unit illusion returns nothing
local integer i = 1
local integer f
local integer p
local integer index = GetUnitUserData(original)
local integer index2 = GetUnitUserData(illusion)
if index != 0 then
loop
call SaveInteger(T,i,index2 * 16 + 1,0)
call SaveInteger(T,i,index2 * 16 + 2,0)
call SaveInteger(T,i,index2 * 16 + 3,0)
call SaveInteger(T,i,index2 * 16 + 4,0)
call SaveInteger(T,i,index2 * 16 + 5,0)
call SaveInteger(T,i,index2 * 16 + 6,0)
if i != 5 and i != 6 then
set f = LoadInteger(T,i,index * 16 + 4)
set p = LoadInteger(T,i,index * 16 + 5)
call BonusStruct.Add(i,illusion,f,p,false)
endif
set i = i + 1
exitwhen i > 9
endloop
endif
endmethod
private static method Limits takes integer current, integer value, integer bonusType returns integer
local integer limitM
local integer limit
local integer nvalue
if bonusType >= 10 and bonusType <= 17 then
set limit = BONUS_LIMIT_B
set nvalue = current + value
endif
if bonusType == BONUS_TYPE_HP or bonusType <= BONUS_TYPE_MP or bonusType == BONUS_TYPE_SIGHT_RANGE then
set limit = BONUS_LIMIT_B
set nvalue = value
else
set limit = BONUS_LIMIT_A
set nvalue = current + value
endif
set limitM = limit * -1
if nvalue > limit then
set nvalue = limit
endif
if nvalue < limitM then
set nvalue = limitM
endif
return nvalue
endmethod
private static method AddBonusM1 takes integer bonusID, integer di, integer flag, integer target returns nothing
local unit u = Index[target].u
local integer lvl = GetUnitAbilityLevel(u,bonusID)
if lvl == 0 and di > 0 then
call UnitAddAbility(u,bonusID)
call UnitMakeAbilityPermanent(u,true,bonusID)
elseif lvl > 0 and di == 0 then
call UnitMakeAbilityPermanent(u,false,bonusID)
call UnitRemoveAbility(u,bonusID)
endif
if flag == 0 then
call SetUnitAbilityLevel(u,bonusID,10+(di-1))
else
call SetUnitAbilityLevel(u,bonusID,di)
endif
set u = null
endmethod
private static method AddBonusM2 takes integer BonusType, integer target, integer flag, integer di, integer b returns nothing
local unit u = Index[target].u
local integer i = 1
local integer bl
if flag == 1 then
set bl = 2
else
set bl = 6
endif
loop
exitwhen i > di
call UnitAddAbility(u,ABILITY_1[BonusType])
call SetUnitAbilityLevel(u,ABILITY_1[BonusType],bl + b)
call UnitRemoveAbility(u,ABILITY_1[BonusType])
set i = i + 1
endloop
set u = null
endmethod
private static method Apply takes integer BonusType, integer value, integer Target returns nothing
local integer m
local integer i = 3
local integer b
local integer di
local integer flag = 1 //Verifica si el bono es positivo o negativo
set b = value
if b < 0 then
set b = b * -1
set flag = 0
endif
loop
set m = R2I(Pow(10 , i))
set di = b / m
set b = ModuloInteger(b,m)
if BonusType == BONUS_TYPE_HP or BonusType == BONUS_TYPE_MP or BonusType == BONUS_TYPE_SIGHT_RANGE and di != 0 then
call AddBonusM2(BonusType,Target,flag,di,i)
else
if m == 100 then
call AddBonusM1(ABILITY_100[BonusType],di,flag,Target)
elseif m == 10 then
call AddBonusM1(ABILITY_10[BonusType],di,flag,Target)
elseif m == 1 then
call AddBonusM1(ABILITY_1[BonusType],di,flag,Target)
endif
endif
set i = i - 1
exitwhen m == 1
endloop
endmethod
public static method AddSpecial takes integer bonusType, unit target, real flat, integer percent returns nothing
local integer index = GetUnitUserData(target)
local real flatbonus = LoadReal(T,bonusType,index * 16 + 1) + flat
local real percbonus = LoadReal(T,bonusType,index * 16 + 3) + percent
local real finalbonus = LoadReal(T,bonusType,index * 16 + 2)
local real p = 0
local real f = 0
local Hero h
if bonusType >= 10 and (IsUnitType(target,UNIT_TYPE_HERO) or GetUnitAbilityLevel(target,Game.FLAG_HERO_CREEP) != 0) then
set p = flatbonus * percbonus / 100
set f = flatbonus + p
call SaveReal(T,bonusType,index * 16 + 3,percbonus)
call SaveReal(T,bonusType,index * 16 + 1,flatbonus)
call SaveReal(T,bonusType,index * 16 + 2,f)
if bonusType == BONUS_TYPE_CD_REDUCTION then
set h = GetUnitData(target,"HeroIndex")
if h != 0 then
call h.updateTooltips()
endif
endif
endif
endmethod
public static method Add takes integer bonusType, unit target, integer flat, integer percent, boolean temp returns nothing
local integer index = GetUnitUserData(target)
local integer flatbonus = LoadInteger(T,bonusType,index * 16 + 1) + flat
local integer percbonus = LoadInteger(T,bonusType,index * 16 + 3) + percent
local integer finalbonus = LoadInteger(T,bonusType,index * 16 + 2)
local integer flatbonusEx = LoadInteger(T,bonusType,index * 16 + 4)
local integer percbonusEx = LoadInteger(T,bonusType,index * 16 + 5)
local integer finalbonusEx = LoadInteger(T,bonusType,index * 16 + 6)
local boolean h = IsUnitType(target,UNIT_TYPE_HERO)
local integer b = 0
local integer ori = 0
local integer p = 0
local integer f = 0
if index == 0 or target == null then
debug call BJDebugMsg("No bonus"+I2S(bonusType)+"de: "+GetUnitName(target))
return
endif
if bonusType < 10 then
if bonusType == BONUS_TYPE_STRENGTH and h then
set ori = GetHeroStr(target,false)
elseif bonusType == BONUS_TYPE_AGILITY and h then
set ori = GetHeroAgi(target,false)
elseif bonusType == BONUS_TYPE_INTELLIGENCE and h then
set ori = GetHeroInt(target,false)
elseif bonusType == BONUS_TYPE_DAMAGE then
set ori = BlzGetUnitBaseDamage(target,0)
elseif bonusType == BONUS_TYPE_HP then
set ori = 700 + flatbonus
elseif bonusType == BONUS_TYPE_MP then
set ori = 300 + flatbonus
elseif bonusType != BONUS_TYPE_SIGHT_RANGE and bonusType != BONUS_TYPE_ATTACK_SPEED and bonusType != BONUS_TYPE_ARMOR then
set ori = flatbonus
endif
set p = R2I(ori * percbonus / 100)
set f = flatbonus + p
set b = f - finalbonus
call SaveInteger(T,bonusType,index * 16 + 3,percbonus)
call SaveInteger(T,bonusType,index * 16 + 1,flatbonus)
call SaveInteger(T,bonusType,index * 16 + 2,f)
if b != 0 then
if bonusType == BONUS_TYPE_HP or bonusType == BONUS_TYPE_MP or bonusType == BONUS_TYPE_SIGHT_RANGE then
call Apply(bonusType,b,index)
if b > 0 then
if bonusType == BONUS_TYPE_HP then
call UnitAddHp(target,b/2)
elseif bonusType == BONUS_TYPE_MP then
call UnitAddMp(target,b/2)
endif
endif
else
call Apply(bonusType,f,index)
endif
endif
if not temp then
set flatbonusEx = flatbonusEx + flat
set percbonusEx = percbonusEx + percent
set p = R2I(ori * percbonusEx / 100)
set f = flatbonusEx + p
call SaveInteger(T,bonusType,index * 16 + 4,flatbonusEx)
call SaveInteger(T,bonusType,index * 16 + 5,percbonusEx)
call SaveInteger(T,bonusType,index * 16 + 6,f)
endif
endif
endmethod
public static method GetFlatBonus takes integer bonusType, unit target returns integer
return LoadInteger(T,bonusType,GetUnitUserData(target) * 16 + 1)
endmethod
public static method GetFlatBonusEx takes integer bonusType, unit target returns integer
return LoadInteger(T,bonusType,GetUnitUserData(target) * 16 + 4)
endmethod
public static method GetTotalBonus takes integer bonusType, unit target returns integer
return LoadInteger(T,bonusType,GetUnitUserData(target) * 16 + 2)
endmethod
public static method GetPercentBonus takes integer bonusType, unit target returns integer
return GetTotalBonus(bonusType,target) - GetFlatBonus(bonusType,target)
endmethod
public static method GetTotalBonusSpecial takes integer bonusType, unit target returns real
return LoadReal(T,bonusType,GetUnitUserData(target) * 16 + 2)
endmethod
endstruct
private function SET_ABILITY takes nothing returns nothing
set ABILITY_1[BONUS_TYPE_STRENGTH] = 'BSR1'
set ABILITY_10[BONUS_TYPE_STRENGTH] = 'BSR2'
set ABILITY_100[BONUS_TYPE_STRENGTH] = 'BSR3'
set ABILITY_1[BONUS_TYPE_AGILITY] = 'BAG1'
set ABILITY_10[BONUS_TYPE_AGILITY] = 'BAG2'
set ABILITY_100[BONUS_TYPE_AGILITY] = 'BAG3'
set ABILITY_1[BONUS_TYPE_INTELLIGENCE] = 'BIN1'
set ABILITY_10[BONUS_TYPE_INTELLIGENCE] = 'BIN2'
set ABILITY_100[BONUS_TYPE_INTELLIGENCE] = 'BIN3'
set ABILITY_1[BONUS_TYPE_DAMAGE] = 'BDM1'
set ABILITY_10[BONUS_TYPE_DAMAGE] = 'BDM2'
set ABILITY_100[BONUS_TYPE_DAMAGE] = 'BDM3'
set ABILITY_1[BONUS_TYPE_ATTACK_SPEED] = 'BAS1'
set ABILITY_10[BONUS_TYPE_ATTACK_SPEED] = 'BAS2'
set ABILITY_100[BONUS_TYPE_ATTACK_SPEED] = 'BAS3'
set ABILITY_1[BONUS_TYPE_ARMOR] = 'BAR1'
set ABILITY_10[BONUS_TYPE_ARMOR] = 'BAR2'
set ABILITY_100[BONUS_TYPE_ARMOR] = 'BAR3'
set ABILITY_1[BONUS_TYPE_HP] = 'BHP5'
set ABILITY_1[BONUS_TYPE_MP] = 'BMP4'
set ABILITY_1[BONUS_TYPE_SIGHT_RANGE] = 'BSG4'
endfunction
private function Init takes nothing returns nothing
local integer i = 1
call SET_ABILITY()
loop
if ABILITY_1[i] != 0 then
call PreloadGen.Add(ABILITY_1[i],PRELOAD_FIRST)
endif
if ABILITY_10[i] != 0 then
call PreloadGen.Add(ABILITY_10[i],PRELOAD_FIRST)
endif
if ABILITY_100[i] != 0 then
call PreloadGen.Add(ABILITY_100[i],PRELOAD_FIRST)
endif
set i = i + 1
exitwhen i > BONUS_COUNT_ABILITY
endloop
endfunction
endlibrary
library Commands initializer init uses HeroLibrary
globals
private trigger CMD_TRIGGER
private string array CMD
private boolean array EXACT
private integer CMD_COUNT = 0
Event EVENT_PLAYER_CHAT_COMMAND
string EventChatCommand = ""
string EventChatValue = ""
player EventChatPlayer = null
endglobals
function AddCommandListener takes string x, boolean exact, code c returns nothing
set CMD[CMD_COUNT] = x
set EXACT[CMD_COUNT] = exact
set CMD_COUNT = CMD_COUNT + 1
call EVENT_PLAYER_CHAT_COMMAND.register(Filter(c))
endfunction
private function OnChatEvent takes nothing returns nothing
local string s = GetEventPlayerChatString()
local integer i = 0
local string sc
if SubString(s,0,1) == "-" then
set s = SubString(s,1,StringLength(s))
loop
if EXACT[i] then
set sc = s
if CMD[i] == sc then
set EventChatCommand = CMD[i]
set EventChatPlayer = GetTriggerPlayer()
call EVENT_PLAYER_CHAT_COMMAND.fire()
exitwhen true
endif
else
set sc = SubString(s,0,StringLength(CMD[i]) + 1)
if CMD[i] + " " == sc then
set EventChatCommand = CMD[i]
set EventChatPlayer = GetTriggerPlayer()
set EventChatValue = SubString(s,StringLength(CMD[i]) + 1,StringLength(s))
call EVENT_PLAYER_CHAT_COMMAND.fire()
exitwhen true
endif
endif
set i = i + 1
exitwhen i == CMD_COUNT
endloop
endif
endfunction
private function init takes nothing returns nothing
local integer i = 2
set CMD_TRIGGER = CreateTrigger()
loop
call TriggerRegisterPlayerChatEvent(CMD_TRIGGER,Player(i),"",false)
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
call TriggerAddCondition(CMD_TRIGGER,function OnChatEvent)
set EVENT_PLAYER_CHAT_COMMAND = Event.create()
endfunction
endlibrary
library DamageMod initializer init uses Event, HeroLibrary, DamageTextTag
globals
private constant real ETHEREALBONUS_HEAL = 0.30
private constant real ETHEREALBONUS_DMG = 0.30
private constant real CRITICAL_BASE_CHANCE = 5.0
private constant real CRITICAL_LVL_CHANCE = 1
private constant real CRITICAL_DMG_CHANCE = 0.04
private constant real CRITICAL_BASE_MULT = 1.10
private constant real CRITICAL_ATR_MULT = 0.10
private constant real ARMOR_CRITICAL_CHANCE = 1.0
private constant real ARMOR_DAMAGE_RED = 0.04
constant string EVASION_SFX = "Abilities\\Weapons\\SorceressMissile\\SorceressMissile.mdl"
constant string BLOCK_SFX = "Abilities\\Spells\\Human\\Defend\\DefendCaster.mdl"
public constant string array COLOR[11]
endglobals
private module m
public static method onInit takes nothing returns nothing
set ON_PRE_CALC = Event.create()
set ON_DAMAGE = Event.create()
set ON_POST_CALC = Event.create()
set ON_DUMMY_DMG = Event.create()
endmethod
endmodule
struct DamageEvent
static Event ON_PRE_CALC
static Event ON_POST_CALC
static Event ON_DAMAGE
static Event ON_DUMMY_DMG
static DamageData EventData
public static method RegisterPostCalculation takes boolexpr c returns nothing
call ON_POST_CALC.register(c)
endmethod
public static method RegisterPreCalculation takes boolexpr c returns nothing
call ON_PRE_CALC.register(c)
endmethod
public static method RegisterDamage takes boolexpr c returns nothing
call ON_DAMAGE.register(c)
endmethod
public static method RegisterDummyDamage takes boolexpr c returns nothing
call ON_DUMMY_DMG.register(c)
endmethod
implement m
endstruct
struct Formula extends array
public static method CalcArmorReduction takes real r returns real
if r < 0 then
set r = 1 - Pow(0.94,-r)
return -r
else
set r = r * ARMOR_DAMAGE_RED / (1 + ARMOR_DAMAGE_RED * r)
return r
endif
return 0.00
endmethod
public static method CalcCriticalArmor takes DamageData data returns real
local real a = BlzGetUnitArmor(data.target)
if a > 0 then
return a * ARMOR_CRITICAL_CHANCE
endif
return 0.0
endmethod
public static method CalcCritical takes DamageData data returns boolean
local real chance
local real chancedmg
local real mult
local real c
if IsUnitType(data.source,UNIT_TYPE_HERO) and IsUnitType(data.target,UNIT_TYPE_HERO) and not data.fixedDamage then
if not data.isMiss and not IsUnitIllusion(data.source) then
set chance = CRITICAL_BASE_CHANCE + GetHeroLevel(data.source) * CRITICAL_LVL_CHANCE
set chancedmg = data.damageMod * CRITICAL_DMG_CHANCE
set chance = chance + chancedmg + data.criticalChanceAdd
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set chance = chance - CalcCriticalArmor(data)
endif
set mult = CRITICAL_BASE_MULT + (GetHeroPrimaryAttribute(data.source,true) * CRITICAL_ATR_MULT / 100)
set c = GetRandomInt(1,100)
if (c <= chance or data.trueCritical) and not data.notCritical then
set data.isCritical = true
set data.damageMod = data.damageMod * mult
return true
endif
endif
endif
return false
endmethod
public static method Magic takes DamageData data returns nothing
local real spellstr
local real resist
local real aux
if IsUnitMagicImmune(data.target) and not data.pierceImmune then
set data.damageMod = 0
else
set spellstr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,data.source) + data.spellStrAdd
set resist = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,data.target) + data.resistanceAdd
if data.hasEthereo then
set data.damageMod = data.damageMod + (data.damageMod * ETHEREALBONUS_DMG)
endif
set aux = UnitStat.GetModifiedStat(STAT_RESISTANCE,resist - spellstr)
set data.damageMod = data.damageMod - (data.damageMod * aux)
endif
endmethod
public static method MagicAoe takes DamageData data returns nothing
local real spellstr
local real resist
local real aux
if IsUnitMagicImmune(data.target) and not data.pierceImmune then
set data.damageMod = 0
else
set spellstr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,data.source) + data.spellStrAdd
set resist = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,data.target) + data.resistanceAdd
if data.hasEthereo then
set data.damageMod = data.damageMod + (data.damageMod * ETHEREALBONUS_DMG)
endif
set aux = UnitStat.GetModifiedStat(STAT_RESISTANCE,resist - spellstr)
set data.damageMod = data.damageMod - (data.damageMod * aux)
endif
endmethod
public static method MagicDot takes DamageData data returns nothing
local real spellstr
local real resist
local real aux
if IsUnitMagicImmune(data.target) and not data.pierceImmune then
set data.damageMod = 0
else
set spellstr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,data.source) + data.spellStrAdd
set resist = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,data.target) + data.resistanceAdd
if data.hasEthereo then
set data.damageMod = data.damageMod + (data.damageMod * ETHEREALBONUS_DMG)
endif
set aux = UnitStat.GetModifiedStat(STAT_RESISTANCE,resist - spellstr)
set data.damageMod = data.damageMod - (data.damageMod * aux)
endif
endmethod
public static method Physical takes DamageData data returns nothing
local real spellstr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,data.source) + data.spellStrAdd
local real resist = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,data.target) + data.resistanceAdd
local real aux = UnitStat.GetModifiedStat(STAT_RESISTANCE,resist - spellstr)
set data.damageMod = data.damageMod - (data.damageMod * aux)
endmethod
public static method PhysicalAoe takes DamageData data returns nothing
local real spellstr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,data.source) + data.spellStrAdd
local real resist = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,data.target) + data.resistanceAdd
local real aux = UnitStat.GetModifiedStat(STAT_RESISTANCE,resist - spellstr)
set data.damageMod = data.damageMod - (data.damageMod * aux)
endmethod
public static method PhysicalDot takes DamageData data returns nothing
local real spellstr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,data.source) + data.spellStrAdd
local real resist = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_RESISTANCE,data.target) + data.resistanceAdd
local real aux = UnitStat.GetModifiedStat(STAT_RESISTANCE,resist - spellstr)
set data.damageMod = data.damageMod - (data.damageMod * aux)
endmethod
public static method Heal takes DamageData data returns nothing
if data.hasEthereo then
set data.damageMod = data.damageMod + (data.damageMod * ETHEREALBONUS_HEAL)
endif
endmethod
public static method Pure takes DamageData data returns nothing
local real spellstr = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_STRENGTH,data.source) + data.spellStrAdd
local real resistper = UnitStat.GetModifiedStat(STAT_RESISTANCE,0 - spellstr)
if data.hasEthereo then
set data.damageMod = data.damageMod + (data.damageMod * ETHEREALBONUS_DMG)
endif
set data.damageMod = data.damageMod - (data.damageMod * resistper)
endmethod
public static method Hot takes DamageData data returns nothing
if data.hasEthereo then
set data.damageMod = data.damageMod + (data.damageMod * ETHEREALBONUS_DMG)
endif
endmethod
public static method Attack takes DamageData data returns nothing
local real armor
local real attkstrR
local real blockR
local real evasionR
local real evasionchance
local real blockchance
if data.hasEthereo then
set data.damageMod = 0
else
set attkstrR = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_ATTACK_STRENGTH,data.source) + data.attkStrAdd
if not data.trueAttack then
set evasionR = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_EVASION,data.target) + data.evasionAdd
set evasionchance = UnitStat.GetModifiedStat(STAT_EVASION,evasionR - attkstrR) + data.evasionPercentAdd
if GetRandomInt(1,100) <= evasionchance or data.trueEvasion then
set data.isMiss = true
set data.damageMod = 0
set data.isAbsorbed = true
call DestroyEffect(AddSpecialEffectTarget(EVASION_SFX,data.target,"overhead"))
else
set blockR = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_BLOCK,data.target) + data.blockAdd
set blockchance = UnitStat.GetModifiedStat(STAT_BLOCK_CHANCE,blockR - attkstrR)
if GetRandomInt(1,100) <= blockchance or data.trueBlock then
set data.isBlock = true
//call UnitAddHp(data.target,GetUnitState(data.target,UNIT_STATE_MAX_LIFE) * BLOCK_DAMAGE_HEAL)
set data.damageMod = data.damageMod * BLOCK_DAMAGE_PERCENT
call DestroyEffect(AddSpecialEffectTarget(BLOCK_SFX,data.target,"chest"))
endif
endif
endif
if not data.ignoreAllArmor and not data.isMiss then
set armor = BlzGetUnitArmor(data.target)
if armor > 0 then
set armor = armor - data.ignoreArmor
endif
set data.damageMod = data.damageMod - (data.damageMod * CalcArmorReduction(armor))
endif
endif
endmethod
endstruct
struct DamageData extends array
implement Alloc
unit source
unit target
readonly CodeDamage codeDmg
readonly boolean isSpell
integer dmgType
real damageReal
real damageMod
boolean isMiss //ataque esquivado
boolean isBlock //ataque bloqueado
boolean isCritical //daño critico
boolean isAbsorbed //daño absorbido o 0
boolean trueEvasion //100% evade attacks
boolean trueBlock //100% block attacks
boolean trueAttack //100% attacks effect ignore block and miss
boolean trueCritical //daño que es siempre critico.
boolean notCritical //daño que no puede ser critico.
boolean ignoreAllArmor //Ignora todo la armadura.
boolean pierceImmune //daño que perfora inmunidad magica.
boolean fixedDamage //daño fijo que no recibe bonus ni puede ser critico.
boolean allowOrbs //daño tipo ataque que no detona efectos de ataque.
boolean mainAttack //daño de ataque de autoattack
integer ignoreArmor
real spellBonusAdd
real spellStrAdd
real attkStrAdd
real blockAdd
real evasionAdd
real evasionPercentAdd
real resistanceAdd
real criticalChanceAdd
real lifestealAdd
real slifestealAdd
real bashChanceAdd
real add
real mult
boolean hasEthereo
integer prev
public method destroy takes nothing returns nothing
set source = null
set target = null
set hasEthereo = false
set allowOrbs = false
set mainAttack = false
set isMiss = false
set isBlock = false
set isCritical = false
set isAbsorbed = false
set trueAttack = false
set trueEvasion = false
set trueBlock = false
set trueCritical = false
set notCritical = false
set pierceImmune = false
set fixedDamage = false
set ignoreAllArmor = false
set ignoreArmor = 0
set spellBonusAdd = 0
set spellStrAdd = 0
set attkStrAdd = 0
set blockAdd = 0
set evasionAdd = 0
set evasionPercentAdd = 0
set resistanceAdd = 0
set criticalChanceAdd = 0
set lifestealAdd = 0
set slifestealAdd = 0
set bashChanceAdd = 0
set prev = 0
//call BJDebugMsg("Deallocating DMG: "+I2S(this))
call this.deallocate()
endmethod
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
//call BJDebugMsg("allocating DMG: "+I2S(this))
set damageReal = udg_DamageEventAmount
set dmgType = udg_DamageEventType
set source = udg_DamageEventSource
set target = udg_DamageEventTarget
set codeDmg = udg_DamageEventCode
set isSpell = udg_IsDamageSpell
set damageMod = damageReal
set add = 0.0
set mult = 1.0
if codeDmg != 0 then
set source = codeDmg.source
if codeDmg.options != 0 then
set trueEvasion = codeDmg.options.trueEvasion
set trueBlock = codeDmg.options.trueBlock
set trueAttack = codeDmg.options.trueAttack
set trueCritical = codeDmg.options.trueCritical
set notCritical = codeDmg.options.notCritical
set ignoreAllArmor = codeDmg.options.ignoreAllArmor
set pierceImmune = codeDmg.options.pierceImmune
set fixedDamage = codeDmg.options.fixedDamage
set allowOrbs = codeDmg.options.allowOrbs
if codeDmg.codeName == "Lifesteal" then
set notCritical = true
endif
if codeDmg.options.mainAttack then
set allowOrbs = true
set mainAttack = true
endif
endif
if GetUnitAbilityLevel(target,'BSBN') > 0 then
set hasEthereo = true
set damageReal = codeDmg.damage
endif
elseif not isSpell then
set dmgType = udg_DamageTypeAttack
if GetUnitAbilityLevel(source,'A09Q') != 0 and target == Index[GetUnitData(source,"Target")].u then
set allowOrbs = true
set mainAttack = true
endif
if GetUnitAbilityLevel(source,'A01G') != 0 then
set trueAttack = true
endif
endif
return this
endmethod
endstruct
private struct DamageMod
public static trigger Pre_Trigger
public static trigger Post_Trigger
static DamageData lastData = 0
static boolean IgnoreNextDamage = false
public static method OnDamage takes nothing returns nothing
local DamageData d = lastData
local player sourcePlayer
local player targetPlayer
local boolean isHeroS
local boolean isHeroT
local integer dmgInt
local Players ps
local Players pt
local real sx
local real sy
local real tx
local real ty
local string dmgText
if IgnoreNextDamage then
set IgnoreNextDamage = false
return
endif
if d != 0 then
set sourcePlayer = GetOwningPlayer(d.source)
set targetPlayer = GetOwningPlayer(d.target)
set ps = Players[GetPlayerId(sourcePlayer)]
set pt = Players[GetPlayerId(targetPlayer)]
set isHeroS = IsUnitType(d.source,UNIT_TYPE_HERO)
set isHeroT = IsUnitType(d.target,UNIT_TYPE_HERO)
set sx = GetUnitX(d.source)
set sy = GetUnitY(d.source)
set tx = GetUnitX(d.target)
set ty = GetUnitY(d.target)
set dmgText = I2S(R2I(d.damageMod))
set dmgInt = R2I(d.damageMod)
if R2I(d.damageMod) > 0 or d.isBlock or d.isMiss or d.isAbsorbed and (not d.isSpell and d.codeDmg.codeName != "KillBlow") then
if d.isCritical then
set dmgText = dmgText + "!"
if dmgInt > 0 then
if isHeroS and isHeroT and ps >= 2 and ps <= 11 and pt >= 2 and pt <= 11 then
if dmgInt > ps.maxCritD then
set ps.maxCritD = dmgInt
set ps.maxCritDTarget = pt
set ps.maxCritDType = d.dmgType
endif
if dmgInt > pt.maxCritT and d.dmgType != 9 and d.dmgType != 10 then
set pt.maxCritT = dmgInt
set pt.maxCritTSource = ps
set pt.maxCritTType = d.dmgType
endif
endif
endif
endif
if isHeroT and ps <= 11 then
if d.dmgType <= 6 or d.dmgType == 8 then
set ps.spellDmgD = ps.spellDmgD + dmgInt
set pt.spellDmgT = pt.spellDmgT + dmgInt
set ps.totalDmgD = ps.totalDmgD + dmgInt
set pt.totalDmgT = pt.totalDmgT + dmgInt
else
if d.dmgType == 9 or d.dmgType == 10 then
set ps.healD = ps.healD + dmgInt
//set pt.healT = pt.healT + d.damageMod
else
set ps.attDmgD = ps.attDmgD + dmgInt
set ps.totalDmgD = ps.totalDmgD + dmgInt
if isHeroS then
set pt.attDmgT = pt.attDmgT + dmgInt
set pt.totalDmgT = pt.totalDmgT + dmgInt
endif
endif
endif
endif
set DamageEvent.EventData = d
call DamageEvent.ON_DAMAGE.fire()
if d.isMiss or d.isBlock or d.isAbsorbed then
if d.isMiss then
call CreateDamageTextForPlayer(sourcePlayer,COLOR[11]+"MISS"+"|r",d.source,d.target,false,true)
else
if d.isCritical then
if d.isBlock then
call CreateDamageTextForPlayer(sourcePlayer,COLOR[11]+"BLOCK"+"("+ I2S(R2I(d.damageMod)) +")"+"|r",d.source,d.target,true,true)
call CreateDamageTextForPlayer(targetPlayer,COLOR[11]+"BLOCK"+"("+ I2S(R2I(d.damageMod)) +")"+"|r",d.source,d.target,true,true)
elseif d.isAbsorbed then
call CreateDamageTextForPlayer(sourcePlayer,COLOR[11]+"ABSORBED"+"|r",d.source,d.target,true,true)
call CreateDamageTextForPlayer(targetPlayer,COLOR[11]+"ABSORBED"+"|r",d.source,d.target,true,true)
endif
else
if d.isBlock then
call CreateDamageTextForPlayer(sourcePlayer,COLOR[11]+"BLOCK"+"("+ I2S(R2I(d.damageMod)) +")"+"|r",d.source,d.target,false,true)
elseif d.isAbsorbed then
call CreateDamageTextForPlayer(sourcePlayer,COLOR[11]+"ABSORBED"+"|r",d.source,d.target,false,true)
endif
endif
endif
else
if pt.damageTextMode != 2 then
if pt.damageTextMode == 3 then
if d.isCritical then
if d.dmgType == udg_DamageTypeHeal or d.dmgType == udg_DamageTypeHealOverTime then
call CreateDamageTextForPlayer(targetPlayer,COLOR[d.dmgType]+"+"+dmgText+"|r",d.source,d.target,d.isCritical,false)
else
call CreateDamageTextForPlayer(targetPlayer,COLOR[d.dmgType]+"-"+dmgText+"|r",d.source,d.target,d.isCritical,false)
endif
endif
else
if d.dmgType == udg_DamageTypeHeal or d.dmgType == udg_DamageTypeHealOverTime then
if d.codeDmg.codeName != "Lifesteal" then
call CreateDamageTextForPlayer(targetPlayer,COLOR[d.dmgType]+"+"+dmgText+"|r",d.source,d.target,d.isCritical,false)
endif
else
call CreateDamageTextForPlayer(targetPlayer,COLOR[d.dmgType]+"-"+dmgText+"|r",d.source,d.target,d.isCritical,false)
endif
endif
endif
if sourcePlayer != targetPlayer then
if ps.damageTextMode != 2 then
if ps.damageTextMode == 3 then
if d.isCritical then
if d.dmgType == udg_DamageTypeHeal or d.dmgType == udg_DamageTypeHealOverTime then
call CreateDamageTextForPlayer(sourcePlayer,COLOR[d.dmgType]+"+"+dmgText+"|r",d.source,d.target,d.isCritical,false)
else
call CreateDamageTextForPlayer(sourcePlayer,COLOR[d.dmgType]+dmgText+"|r",d.source,d.target,d.isCritical,false)
endif
endif
else
if d.dmgType == udg_DamageTypeHeal or d.dmgType == udg_DamageTypeHealOverTime then
if d.codeDmg.codeName != "Lifesteal" then
call CreateDamageTextForPlayer(sourcePlayer,COLOR[d.dmgType]+"+"+dmgText+"|r",d.source,d.target,d.isCritical,false)
endif
else
call CreateDamageTextForPlayer(sourcePlayer,COLOR[d.dmgType]+dmgText+"|r",d.source,d.target,d.isCritical,false)
endif
endif
endif
endif
endif
endif
if d.codeDmg != 0 then
call d.codeDmg.destroy()
endif
set DamageEvent.EventData = d.prev
call d.destroy()
set sourcePlayer = null
set targetPlayer = null
endif
endmethod
public static method OnPreDamage takes nothing returns nothing
local DamageData d
if udg_DamageEventAmount <= 0 and not udg_IsDamageSpell then
set IgnoreNextDamage = true
return
endif
if GetUnitAbilityLevel(udg_DamageEventTarget,'A09X') != 0 and not udg_IsDamageSpell then
if IsUnitType(udg_DamageEventSource,UNIT_TYPE_HERO) then
set udg_DamageEventAmount = 2
else
set udg_DamageEventAmount = 1
endif
set IgnoreNextDamage = true
return
endif
set d = DamageData.create()
if not d.isSpell and d.codeDmg.codeName != "KillBlow" then
set d.prev = lastData
set lastData = d
//Modificaciones/Reducciones/Ampliaciones
set DamageEvent.EventData = d
call DamageEvent.ON_PRE_CALC.fire()
if d.isAbsorbed then
set d.damageMod = 0
else
set d.damageMod = (d.damageMod + d.add) * d.mult
endif
set lastData = d
if d.damageMod > 0 then
if d.dmgType == udg_DamageTypeMagic then
call Formula.Magic(d)
elseif d.dmgType == udg_DamageTypeMagicAoe then
call Formula.MagicAoe(d)
elseif d.dmgType == udg_DamageTypeMagicOverTime then
call Formula.MagicDot(d)
elseif d.dmgType == udg_DamageTypePhysical then
call Formula.Physical(d)
elseif d.dmgType == udg_DamageTypePhysicalAoe then
call Formula.PhysicalAoe(d)
elseif d.dmgType == udg_DamageTypePhysicalOverTime then
call Formula.PhysicalDot(d)
elseif d.dmgType == udg_DamageTypeHeal then
call Formula.Heal(d)
elseif d.dmgType == udg_DamageTypeHealOverTime then
call Formula.Hot(d)
elseif d.dmgType == udg_DamageTypePure then
call Formula.Pure(d)
else
call Formula.Attack(d)
endif
call Formula.CalcCritical(d)
//Absorciones
if d.fixedDamage then
set d.damageMod = d.damageReal
endif
call DamageEvent.ON_POST_CALC.fire()
set lastData = d
endif
if d.dmgType == udg_DamageTypeHeal or d.dmgType == udg_DamageTypeHealOverTime then
set udg_DamageEventAmount = d.damageMod * -1
else
set udg_DamageEventAmount = d.damageMod
endif
else
if d.codeDmg.codeName != "KillBlow" then
set d.prev = lastData
set DamageEvent.EventData = d
call DamageEvent.ON_DUMMY_DMG.fire()
set udg_DamageEventAmount = 0
set lastData = d
endif
endif
endmethod
endstruct
struct DamageOptions extends array
implement Alloc
boolean trueEvasion
boolean trueBlock
boolean trueAttack
boolean trueCritical
boolean notCritical
boolean ignoreAllArmor
boolean pierceImmune
boolean fixedDamage
boolean allowOrbs
boolean mainAttack
public method destroy takes nothing returns nothing
call this.deallocate()
endmethod
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set trueEvasion = false
set trueBlock = false
set trueAttack = false
set trueCritical = false
set notCritical = false
set ignoreAllArmor = false
set pierceImmune = false
set fixedDamage = false
set allowOrbs = false
return this
endmethod
endstruct
struct CodeDamage extends array
implement Alloc
string codeName
real damage
unit source
integer data
DamageOptions options
public method destroy takes nothing returns nothing
set source = null
set codeName = ""
set damage = 0.00
set data = 0
if options != 0 then
call options.destroy()
set options = 0
endif
//call BJDebugMsg("Deallocating CodeDMG: "+I2S(this))
call this.deallocate()
endmethod
public static method Damage takes unit source, unit target, real damage, integer dmgtype, string name, integer d, integer op returns nothing
local thistype this
if UnitAlive(target) then
set this = thistype.allocate()
//call BJDebugMsg("Allocating CodeDMG: "+I2S(this))
set .source = source
set .damage = damage
set .codeName = name
set .data = d
set .options = op
if name == "KillBlow" then
set damage = 9999999
set udg_NextDamageType = dmgtype
set udg_NextDamageCode = this
call UnitDamageTarget(GetPlayerDummy(GetOwningPlayer(source)),target,damage,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_UNIVERSAL,null)
call ConditionalTriggerExecute( udg_ClearDamageEvent )
else
if GetUnitAbilityLevel(target,'BSBN') == 0 then
set udg_NextDamageType = dmgtype
set udg_NextDamageCode = this
call UnitDamageTarget(GetPlayerDummy(GetOwningPlayer(source)),target,damage,false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,null)
call ConditionalTriggerExecute( udg_ClearDamageEvent )
else
if dmgtype != udg_DamageTypePhysical and dmgtype != udg_DamageTypePhysicalAoe and dmgtype != udg_DamageTypePhysicalOverTime then
set udg_NextDamageType = dmgtype
set udg_NextDamageCode = this
call UnitDamageTarget(GetPlayerDummy(GetOwningPlayer(source)),target,damage,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_UNIVERSAL,null)
call ConditionalTriggerExecute( udg_ClearDamageEvent )
else
call this.destroy()
endif
endif
endif
endif
endmethod
endstruct
private function SetColors takes nothing returns nothing
set COLOR[1] = "|c000080ff" //magic
set COLOR[2] = "|c00ff2b2b" //physical
set COLOR[3] = "|c000080ff" //magicdot
set COLOR[4] = "|c00ff2b2b" //physicaldot
set COLOR[5] = "|c000080ff" //magicaoe
set COLOR[6] = "|c00ff2b2b" //physicalaoe
set COLOR[7] = "|c00d1d1d1" //attack
set COLOR[8] = "|c00ee82ee" //pure
set COLOR[9] = "|c0000ff00" //heal
set COLOR[10] = "|c0000ff00" //healot
set COLOR[11] = "|c00ff8080" //MISS BLOCK
set CodeDamage(0).codeName = " "
set CodeDamage(0).data = 0
set CodeDamage(0).source = null
set CodeDamage(0).damage = 0.00
set CodeDamage(0).options = 0
set DamageOptions.allocName = "DamageOptions"
set DamageData.allocName = "DamageData"
set CodeDamage.allocName = "CodeDamage"
endfunction
private function init takes nothing returns nothing
set DamageMod.Pre_Trigger = CreateTrigger()
set DamageMod.Post_Trigger = CreateTrigger()
call TriggerRegisterVariableEvent( DamageMod.Post_Trigger, "udg_AfterDamageEvent", EQUAL, 1.00 )
call TriggerRegisterVariableEvent( DamageMod.Pre_Trigger, "udg_DamageModifierEvent", EQUAL, 1.00 )
call TriggerAddCondition(DamageMod.Post_Trigger,Condition(function DamageMod.OnDamage))
call TriggerAddCondition(DamageMod.Pre_Trigger,Condition(function DamageMod.OnPreDamage))
call SetColors()
endfunction
endlibrary
scope Teleport
globals
private constant integer SPELL_ID = 'A00A'
private constant string TP_SFX_CASTER = "war3mapImported\\MASSTeleportTo.mdx"
private constant string TP_SFX_DONE = "war3mapImported\\MassTeleportCaster.mdx"
private constant string TP_SFX_TARGET = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTo.mdl"
constant integer TP_TO_TOWER = 0
constant integer TP_TO_MINE = 1
constant integer TP_TO_POINT = 3
constant integer TP_TO_UNIT = 4
constant integer TP_TO_OBELISK = 5
private constant real SEARCH_AREA = 1200.00
private constant real DELAY_ONCOMBAT = 3.00
private constant real DELAY_OUTCOMBAT= 2.00
unit TELEPORT_UNIT
integer TELEPORT_SUCCESS
Event ON_TELEPORT_END
endglobals
function RegisterTeleportEvent takes code c returns nothing
call ON_TELEPORT_END.register(Filter(c))
endfunction
private struct Init
implement mt
endstruct
module mt
public static method onInit takes nothing returns nothing
set ON_TELEPORT_END = Event.create()
endmethod
endmodule
struct Teleport extends array
implement Alloc
unit caster
unit target
real xt
real yt
boolean channeling
real time
integer option
integer data
effect sfx1
effect sfx2
private static method Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local player p = GetOwningPlayer(caster)
local Team te
local integer sw = 0
local Base b
local GoldMine g
set time = time - 0.03125
if time <= 0 then
call DestroyEffect(AddSpecialEffect(TP_SFX_DONE,GetUnitX(caster),GetUnitY(caster)))
if option == TP_TO_UNIT then
call SetUnitX(caster,GetUnitX(target) + GetRandomReal(150,175) * Cos(GetRandomReal(1,360) * bj_DEGTORAD) )
call SetUnitY(caster,GetUnitY(target) + GetRandomReal(150,175) * Sin(GetRandomReal(1,360) * bj_DEGTORAD) )
else
call SetUnitX(caster,xt)
call SetUnitY(caster,yt)
endif
set sw = 1
else
if channeling then
if GetUnitCurrentOrder(caster) != ORDER_massteleport then
set sw = 2
endif
endif
if not UnitAlive(caster) then
set sw = 2
endif
if option == TP_TO_UNIT then
if not UnitAlive(target) then
set sw = 2
endif
else
set te = GetPlayerTeamEx(p)
if option == TP_TO_TOWER then
set b = Base[data]
if b.owner != te then
set sw = 2
endif
elseif option == TP_TO_MINE then
set g = GoldMine[data]
if g.owner != te then
set sw = 2
endif
elseif option == TP_TO_OBELISK then
if AncientObelisk.owner != te then
set sw = 2
endif
endif
endif
endif
if sw != 0 then
set TELEPORT_UNIT = caster
if sw == 1 then
set TELEPORT_SUCCESS = 1
else
set TELEPORT_SUCCESS = 0
endif
if sw != 2 then
if option == TP_TO_TOWER then
set b = Base[data]
set b.angle = b.angle - 72
elseif option == TP_TO_MINE then
set g = GoldMine[data]
set g.angle = g.angle - 72
endif
endif
call ON_TELEPORT_END.fire()
call ReleaseTimer(t)
call this.destroy()
endif
set p = null
set t = null
endmethod
private method start takes nothing returns nothing
local timer t = NewTimerEx(this)
call TimerStart(t,0.03125,true,function thistype.Callback)
set t = null
endmethod
public static method create takes unit u, unit t, real x, real y, boolean c, real ti, integer op returns thistype
local thistype this = thistype.allocate()
set caster = u
set target = t
set xt = x
set yt = y
set channeling = c
set time = ti
set sfx1 = AddSpecialEffectTarget(TP_SFX_CASTER,caster,"origin")
if time == 3.00 then
call BlzSetSpecialEffectTimeScale(sfx1,0.85)
elseif time == 2.00 then
call BlzSetSpecialEffectTime(sfx1,1.0)
call BlzSetSpecialEffectTimeScale(sfx1,1.0)
endif
set option = op
if op == TP_TO_UNIT then
set sfx2 = AddSpecialEffectTarget(TP_SFX_TARGET,target,"origin")
else
set sfx2 = AddSpecialEffect(TP_SFX_TARGET,x,y)
endif
call BlzSetSpecialEffectScale(sfx2,0.75)
call start()
return this
endmethod
public method destroy takes nothing returns nothing
set caster = null
set target = null
set xt = 0
set yt = 0
set channeling = false
set time = 0
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
set sfx1 = null
set sfx2 = null
call this.deallocate()
endmethod
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local player p = GetTriggerPlayer()
local Teleport tp
local Base b
local GoldMine gn
local integer id
local real x
local real y
local group g
local unit temp
local real time
local integer sw = 1
if Game.Mode != GAME_MODE_NORMAL then
set u = null
set t = null
set p = null
return
endif
if IsUnitInCombat(u) then
set time = DELAY_ONCOMBAT
else
set time = DELAY_OUTCOMBAT
endif
if t == null then
set x = GetSpellTargetX()
set y = GetSpellTargetY()
set g = NewGroup()
call GroupEnumUnitsInRange(g,x,y,SEARCH_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if GetUnitAbilityLevel(temp,'A01U') == 1 and IsUnitAlly(temp,p) then
exitwhen true
endif
endloop
if temp != null then
set t = temp
set temp = null
else
call Message.ShowToPlayer(p,"There is no valid structure to Teleport",MESSAGE_STYLE_ERROR)
call UnitResetAbilityCooldown(u,SPELL_ID)
set sw = 0
endif
call ReleaseGroup(g)
set g = null
endif
if sw == 1 then
set id = GetUnitTypeId(t)
if id == 'n006' or id == 'n009' then
set b = Base.GetBaseFromTower(t)
set x = b.x + 150 * Cos(b.angle * bj_DEGTORAD)
set y = b.y + 150 * Sin(b.angle * bj_DEGTORAD)
set b.angle = b.angle + 72
set tp = Teleport.create(u,null,x,y,true,time,TP_TO_TOWER)
set tp.data = b
elseif id == 'n00N' then
set gn = GoldMine.GetGoldMineFromUnit(t)
set x = GetUnitX(gn.gold) + 200 * Cos(gn.angle * bj_DEGTORAD)
set y = GetUnitY(gn.gold) + 200 * Sin(gn.angle * bj_DEGTORAD)
set gn.angle = gn.angle + 72
set tp = Teleport.create(u,null,x,y,true,time,TP_TO_MINE)
set tp.data = gn
elseif id == 'n00C' then
set x = AncientObelisk.x + 200 * Cos(AncientObelisk.angle * bj_DEGTORAD)
set y = AncientObelisk.y + 200 * Sin(AncientObelisk.angle * bj_DEGTORAD)
set AncientObelisk.angle = AncientObelisk.angle + 72
set tp = Teleport.create(u,null,x,y,true,time,TP_TO_OBELISK)
else
call Teleport.create(u,t,0,0,true,time,TP_TO_UNIT)
endif
endif
set t = null
set u = null
set p = null
endfunction
public function Setup takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(TP_SFX_CASTER)
call Preload(TP_SFX_TARGET)
call Preload(TP_SFX_DONE)
endfunction
endscope
library AuraSystem uses LinkedList, UnitData
globals
private constant real DEFAULT_PERIOD = 0.5
private trigger CORE
group AURA_ENUM = CreateGroup()
endglobals
struct Aura extends array
implement Alloc
integer buffID
integer auraID
unit owner
real aoe
integer level
integer newLevel
LinkedList affectedUnits
integer allocData
boolean remove
public static method create takes unit u, integer id, integer bid, real a, integer lvl returns thistype
local thistype this = thistype.allocate()
set auraID = id
set buffID = bid
set owner = u
set aoe = a
set remove = false
set affectedUnits = LinkedList.create()
call SetUnitData(u,I2S(auraID),this)
set level = lvl
set newLevel = lvl
return this
endmethod
public method destroy takes nothing returns nothing
call SetUnitData(owner,I2S(auraID),0)
set buffID = 0
set auraID = 0
set owner = null
set aoe = 0
call affectedUnits.destroy()
call deallocate()
endmethod
endstruct
struct AuraCore extends array
static boolexpr array B
static triggercondition array Cond
static integer Count = 0
static timer Loop
private static method LoopMain takes nothing returns nothing
call TriggerEvaluate(CORE)
endmethod
public static method registerAuraType takes integer id, code c returns nothing
if Count == 0 then
set Loop = CreateTimer()
set CORE = CreateTrigger()
call TimerStart(Loop,DEFAULT_PERIOD,true,function thistype.LoopMain)
endif
set Count = Count + 1
set B[id] = Condition(c)
set Cond[id] = TriggerAddCondition(CORE,B[id])
endmethod
public static method removeAuraType takes integer id returns nothing
if B[id] != null then
call TriggerRemoveCondition(CORE,Cond[id])
set B[id] = null
set Count = Count - 1
if Count == 0 then
call PauseTimer(Loop)
endif
endif
endmethod
endstruct
module AuraCore
static LinkedList Instances
public static method UpdateAuraLevel takes unit u, integer id, integer newLevel returns nothing
local Aura a = GetUnitData(u,I2S(id))
if a != 0 then
set a.newLevel = newLevel
endif
endmethod
private static method AuraAccions takes Aura a returns nothing
local real x = GetUnitX(a.owner)
local real y = GetUnitY(a.owner)
local Link node = a.affectedUnits.head
local Link ntemp
local unit temp
local integer aid
loop
exitwhen node == 0
set temp = Index[node.data].u
set ntemp = node.next
set aid = GetUnitAbilityLevel(temp,a.buffID)
if not UnitAlive(temp) or aid == 0 then
call a.affectedUnits.remove(node)
call SetUnitData(temp,"A"+I2S(a.buffID),0)
static if thistype.OnEndEffect.exists then
call thistype.OnEndEffect(temp,a)
endif
else
if a.newLevel != a.level and not a.remove then
static if thistype.OnEndEffect.exists then
call thistype.OnEndEffect(temp,a)
endif
set a.level = a.newLevel
static if thistype.OnEffect.exists then
call thistype.OnEffect(temp,a)
endif
endif
endif
set node = ntemp
endloop
if not a.remove then
call GroupEnumUnitsInRange(AURA_ENUM,x,y,a.aoe,null)
loop
set temp = FirstOfGroup(AURA_ENUM)
exitwhen temp == null
call GroupRemoveUnit(AURA_ENUM,temp)
set aid = GetUnitUserData(temp)
if GetUnitAbilityLevel(temp,a.buffID) != 0 and GetUnitData(temp,"A"+I2S(a.buffID)) == 0 and aid != 0 then
call a.affectedUnits.add(aid)
call SetUnitData(temp,"A"+I2S(a.buffID),a)
static if thistype.OnEffect.exists then
call thistype.OnEffect(temp,a)
endif
endif
endloop
else
debug call BJDebugMsg(I2S(a.affectedUnits.size))
if a.affectedUnits.size == 0 then
debug call BJDebugMsg("affected units 0 destroying")
call Instances.remove(a.allocData)
call a.destroy()
endif
endif
call GroupClear(AURA_ENUM)
set temp = null
endmethod
private static method Loop takes nothing returns nothing
local Link node = Instances.head
local Link temp
loop
exitwhen node == 0
set temp = node.next
call AuraAccions(node.data)
set node = temp
endloop
endmethod
public static method Create takes unit u, integer id, integer bid, real area, integer lvl returns Aura
local Aura a = 0
if GetUnitData(u,I2S(id)) == 0 and GetUnitAbilityLevel(u,id) != 0 then
set a = Aura.create(u,id,bid,area,lvl)
set a.allocData = Instances.add(a)
else
debug call BJDebugMsg("Error - unit already has aura or not has the ability")
endif
return a
endmethod
public static method Destroy takes unit u, integer id returns nothing
local Aura a
if GetUnitAbilityLevel(u,id) == 0 then
debug call BJDebugMsg("remueve aura")
set a = GetUnitData(u,I2S(id))
set a.remove = true
endif
endmethod
public static method Initialize takes nothing returns nothing
call AuraCore.registerAuraType(thistype.typeid,function thistype.Loop)
set Instances = LinkedList.create()
endmethod
endmodule
endlibrary
library DummyCasterRecycler uses UnitData
globals
private constant integer DUMMY_ID = 'u001'
endglobals
struct Dummy
private static unit array Recycler
private static unit array Delayed
private static integer array DelayedAbility
private static integer DelayCount = 0
private static integer Count = 0
public static method GetRecycled takes player p, real x, real y returns unit
if Count == 0 then
return CreateUnit(p,DUMMY_ID,x,y,0)
endif
set Count = Count - 1
call SetUnitX(Recycler[Count],x)
call SetUnitY(Recycler[Count],y)
call SetUnitOwner(Recycler[Count],p,false)
return Recycler[Count]
endmethod
public static method Recycle takes unit u returns nothing
if GetUnitTypeId(u) == DUMMY_ID then
set Recycler[Count] = u
set Count = Count + 1
call flushDummyData(u)
call SetUnitX(u,Game.HIDE_X)
call SetUnitY(u,Game.HIDE_Y)
endif
endmethod
private static method Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
call thistype.Recycle(Delayed[GetTimerData(t)])
set DelayCount = DelayCount - 1
set Delayed[GetTimerData(t)] = null
set Delayed[GetTimerData(t)] = Delayed[DelayCount]
call UnitRemoveAbility(Delayed[GetTimerData(t)],DelayedAbility[GetTimerData(t)])
call ReleaseTimer(t)
set t = null
endmethod
public static method RecycleDelayed takes unit u, real time, integer ar returns nothing
local timer t
if GetUnitTypeId(u) == DUMMY_ID then
set Delayed[DelayCount] = u
set DelayedAbility[DelayCount] = ar
set t = NewTimerEx(DelayCount)
set DelayCount = DelayCount + 1
call TimerStart(t,time,false,function thistype.Callback)
set t = null
endif
endmethod
endstruct
endlibrary
library DummySFX initializer init uses Table,MissileRecycler
globals
private constant integer DUMMY_UP_ID = 'dum2'
private constant integer DUMMY_DOWN_ID = 'dum3'
constant integer DUMMYSFX_TYPE_NORMAL = 0
constant integer DUMMYSFX_TYPE_UP = 1
constant integer DUMMYSFX_TYPE_DOWN = 2
private TableArray RECYCLER
endglobals
struct Recycle extends array
private static integer array count[3]
public static method getRecycledDummy takes integer id, real x, real y, real a, integer t returns unit
if 0 == count[t] then
return CreateUnit(Player(15),id,x,y,a)
endif
set count[t] = count[t] - 1
call ShowUnit(RECYCLER[t].unit[count[t]],true)
call SetUnitFacing(RECYCLER[t].unit[count[t]],a)
return RECYCLER[t].unit[count[t]]
endmethod
public static method recycleDummy takes unit u, integer t returns nothing
set RECYCLER[t].unit[count[t]] = u
set count[t] = count[t] + 1
call SetUnitX(u,Game.HIDE_X)
call SetUnitY(u,Game.HIDE_Y)
call ShowUnit(u,false)
endmethod
endstruct
struct DummySFX extends array
implement Alloc
unit dummy
real scale
real animationScale
effect effectsfx
integer dummytype
string model
public method operator SFX= takes string e returns nothing
if effectsfx != null then
call DestroyEffect(effectsfx)
endif
set effectsfx = AddSpecialEffectTarget(e,dummy,"origin")
set model = e
endmethod
public method operator Scale= takes real s returns nothing
call SetUnitScale(dummy,s,s,s)
endmethod
public method operator TimeScale= takes real s returns nothing
call SetUnitTimeScale(dummy,s)
endmethod
public method makeSelectable takes boolean flag returns nothing
if flag then
call UnitRemoveAbility(dummy,'Aloc')
call SetUnitInvulnerable(dummy,true)
endif
endmethod
public method setColor takes integer r, integer g, integer b, integer alpha returns nothing
call SetUnitVertexColor(dummy,r,g,b,alpha)
endmethod
public method destroy takes nothing returns nothing
call DestroyEffect(effectsfx)
if dummytype == DUMMYSFX_TYPE_NORMAL then
call RecycleMissile(dummy)
else
call Recycle.recycleDummy(dummy,dummytype)
endif
set dummy = null
set effectsfx = null
set dummytype = 0
call this.deallocate()
endmethod
public static method create takes real x, real y, real z, real angle, integer Type returns thistype
local thistype this = thistype.allocate()
if Type == DUMMYSFX_TYPE_NORMAL then
set dummy = GetRecycledMissile(x,y,0,angle)
elseif Type == DUMMYSFX_TYPE_UP then
set dummy = Recycle.getRecycledDummy(DUMMY_UP_ID,x,y,angle,DUMMYSFX_TYPE_UP)
elseif Type == DUMMYSFX_TYPE_DOWN then
set dummy = Recycle.getRecycledDummy(DUMMY_DOWN_ID,x,y,angle,DUMMYSFX_TYPE_DOWN)
endif
call SetUnitTimeScale(dummy,1)
call SetUnitScale(dummy,1,1,1)
call SetUnitVertexColor(dummy,255,255,255,255)
call SetUnitFlyHeight(dummy,z,0)
set scale = 1
set animationScale = 1
set dummytype = Type
return this
endmethod
public static method createEx takes string sfx, real x, real y, real z, real angle, integer Type returns thistype
local thistype this = thistype.create(x,y,z,angle,Type)
set this.SFX = sfx
return this
endmethod
endstruct
private function init takes nothing returns nothing
set RECYCLER = TableArray[3]
endfunction
endlibrary
library Texttag
struct Texttag extends array
implement Alloc
texttag tag
real size
integer sw
string txt
player owner
integer count
static method create takes player p returns thistype
local thistype this = thistype.allocate()
set tag = null
set owner = p
set sw = 0
set size = 0
set txt = ""
set count = 0
if Game.LocalPlayer == p or IsPlayerObserver(Game.LocalPlayer) then
set tag = CreateTextTag()
endif
return this
endmethod
method destroy takes nothing returns nothing
set tag = null
set owner = null
call .deallocate()
endmethod
endstruct
endlibrary
library DamageTextTag uses UnitData, LinkedList
globals
private constant integer TEXTTAG_TYPE_NORMAL = 0
private constant integer TEXTTAG_TYPE_SPECIAL = 1
private constant real TEXTTAG_NORMAL_ANGLE_COS = Cos(270 * bj_DEGTORAD)
private constant real TEXTTAG_NORMAL_ANGLE_SIN = Sin(270 * bj_DEGTORAD)
private constant real TEXTTAG_SPECIAL_ANGLE_COS = Cos(90 * bj_DEGTORAD)
private constant real TEXTTAG_SPECIAL_ANGLE_SIN = Sin(90 * bj_DEGTORAD)
private constant real TEXTTAG_NORMAL_LIFETIME = 0.50
private constant real TEXTTAG_NORMAL_FADETIME = 0.30
private constant real TEXTTAG_CRITICAL_LIFETIME = 2.30
private constant real TEXTTAG_CRITICAL_FADETIME = 1.30
private constant real TEXTTAG_NORMAL_SIZE = 9.00 * 0.023 / 10
private constant real TEXTTAG_CRITICAL_SIZE_INI = 9.00 * 0.023 / 10
private constant real TEXTTAG_CRITICAL_SIZE_INC = 0.65
private constant real TEXTTAG_CRITICAL_SIZE_DEC = 0.65
private constant real TEXTTAG_CRITICAL_HEIGHT = 200
private constant real TEXTTAG_NORMAL_SPEED = 100.00 * 0.071 / 128
endglobals
struct DamageTT extends array
Table tb
static timer time
static LinkedList datas
private static method Periodic takes nothing returns nothing
local Link node = datas.head
local Link temp
local Texttag tt
local integer sw
loop
exitwhen node == 0
set tt = node.data
set sw = 0
set tt.count = tt.count + 1
if tt.count < 20 then
set tt.size = tt.size + TEXTTAG_CRITICAL_SIZE_INC
elseif tt.count <= 30 then
set tt.size = tt.size - TEXTTAG_CRITICAL_SIZE_DEC
endif
if tt.count > 30 then
set sw = 1
else
call SetTextTagText(tt.tag,tt.txt,TextTagSize2Height(tt.size))
endif
if sw == 1 then
call SetTextTagLifespan(tt.tag,TEXTTAG_CRITICAL_LIFETIME)
call SetTextTagFadepoint(tt.tag,TEXTTAG_CRITICAL_FADETIME)
call tt.destroy()
set temp = node.next
call datas.remove(node)
set node = temp
else
set node = node.next
endif
endloop
if datas.size == 0 then
call PauseTimer(time)
endif
endmethod
public method addTextCritical takes unit target, string txt, boolean special returns nothing
local Texttag t = Texttag.create(Player(this))
local integer id = GetUnitUserData(target)
local real off = tb.real[id] - 200
if special then
set t.size = 6.00
else
set t.size = 7.00
endif
set t.txt = txt
call SetTextTagPermanent(t.tag,false)
call SetTextTagPos(t.tag,GetUnitX(target) + off,GetUnitY(target),TEXTTAG_CRITICAL_HEIGHT)
call SetTextTagText(t.tag,txt,TEXTTAG_CRITICAL_SIZE_INI)
call SetTextTagVisibility(t.tag,true)
if off == -200 then
set tb.real[id] = 150
elseif off == -50 then
set tb.real[id] = 300
elseif off == 100 then
set tb.real[id] = 0
endif
call datas.add(t)
if datas.size == 1 then
call TimerStart(time,0.01,true,function thistype.Periodic)
endif
endmethod
public method addTextDamage takes unit target, string txt, integer ttype returns nothing
local integer id = GetUnitUserData(target)
local texttag t = null
local real size = TEXTTAG_NORMAL_SIZE
local real cos
local real sin
local integer count = tb.integer[id]
if ttype == TEXTTAG_TYPE_NORMAL then
set cos = TEXTTAG_NORMAL_ANGLE_COS
set sin = TEXTTAG_NORMAL_ANGLE_SIN
if Game.LocalPlayer == Player(this) then
set t = CreateTextTag()
endif
elseif ttype == TEXTTAG_TYPE_SPECIAL then
set cos = TEXTTAG_SPECIAL_ANGLE_COS
set sin = TEXTTAG_SPECIAL_ANGLE_SIN
set t = CreateTextTag()
endif
call SetTextTagPermanent(t,false)
call SetTextTagPos(t,GetUnitX(target)-20,GetUnitY(target),60 - (40 - 10 * count))
set count = count + 1
if count == 4 then
set count = 0
endif
set tb.integer[id] = count
call SetTextTagText(t,txt,size)
call SetTextTagVelocity(t,TEXTTAG_NORMAL_SPEED * cos,TEXTTAG_NORMAL_SPEED * sin)
call SetTextTagLifespan(t,TEXTTAG_NORMAL_LIFETIME)
call SetTextTagFadepoint(t,TEXTTAG_NORMAL_FADETIME)
call SetTextTagVisibility(t,true)
set t = null
endmethod
public method setup takes nothing returns nothing
set tb = Table.create()
endmethod
endstruct
function CreateDamageTextForPlayer takes player p, string txt, unit source, unit target, boolean critical, boolean special returns nothing
local DamageTT dtt = DamageTT[GetPlayerId(p)]
if not IsUnitFogged(target,p) then
if critical then
call dtt.addTextCritical(target,txt,special)
else
if special then
call dtt.addTextDamage(target,txt,TEXTTAG_TYPE_SPECIAL)
elseif GetPlayerController(p) == MAP_CONTROL_USER then
call dtt.addTextDamage(target,txt,TEXTTAG_TYPE_NORMAL)
endif
endif
endif
endfunction
public function Setup takes nothing returns nothing
set DamageTT.datas = LinkedList.create()
set DamageTT.time = CreateTimer()
endfunction
endlibrary
scope RocketLaunch initializer init
globals
private constant integer GOLD_COST = 200
endglobals
struct RockeLauncherMissile extends array
unit dummyVision
private static method onPeriod takes Missile missile returns boolean
local thistype this = missile
call SetUnitX(dummyVision,missile.x)
call SetUnitY(dummyVision,missile.y)
return false
endmethod
private static method onFinish takes Missile missile returns boolean
local thistype this = missile
local group g = NewGroup()
local unit temp
local real dmg = BlzGetUnitMaxHP(missile.source) * 0.10
call Status.Remove(STATUS_INVULNERABLE,missile.source)
call Status.Remove(STATUS_HIDE,missile.source)
call Status.Remove(STATUS_PAUSE,missile.source)
call SelectUnitForPlayer(missile.source,missile.owner,true)
call SetUnitPosition(missile.source,missile.x,missile.y)
call GroupEnumUnitsInRange(g,missile.x,missile.y,180,null)
call UnitRemoveHp(missile.source,dmg)
call RemoveUnit(dummyVision)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) then
call CodeDamage.Damage(missile.source,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_STUN,temp,1.5,Status_EFFECT[STATUS_STUN])
endif
endloop
call ReleaseGroup(g)
set g = null
set dummyVision = null
return true
endmethod
implement MissileStruct
endstruct
private function RocketLauncher takes unit source, real x, real y returns nothing
local real xu = GetUnitX(source)
local real yu = GetUnitY(source)
local Missile missile = Missile.createXYZ(xu,yu,25.00,x,y,25.00)
call Status.Add(STATUS_INVULNERABLE,source,0,0)
call Status.Add(STATUS_HIDE,source,0,0)
call Status.Add(STATUS_PAUSE,source,0,0)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.speed = 40
set missile.arc = 15 * bj_DEGTORAD
set missile.model = "Abilities\\Weapons\\Mortar\\MortarMissile.mdl"
set missile.scale = 3.0
set RockeLauncherMissile[missile].dummyVision = CreateUnit(missile.owner,'h00O',xu,yu,0)
call RockeLauncherMissile.launch(missile)
endfunction
private function RocketLaunchCast takes nothing returns nothing
local player p = GetTriggerPlayer()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local Hero h = GetPlayerHero(p)
if h != 0 then
if RectContainsUnit(gg_rct_RocketLaunch1,h.hero) or RectContainsUnit(gg_rct_RocketLaunch2,h.hero) then
if IsTerrainWalkable(x,y) then
if GetPlayerState(p,PLAYER_STATE_RESOURCE_GOLD) >= GOLD_COST then
call AddPlayerGold(p,-200)
call RocketLauncher(h.hero,x,y)
else
call Message.ShowToPlayer(p,"Not enough gold",MESSAGE_STYLE_ERROR)
endif
else
call Message.ShowToPlayer(p,"Invalid point to launch",MESSAGE_STYLE_ERROR)
endif
else
call Message.ShowToPlayer(p,"Too far from the launch zone",MESSAGE_STYLE_ERROR)
endif
endif
set p = null
endfunction
private function init takes nothing returns nothing
local group g = NewGroup()
local unit temp
call GroupEnumUnitsInRange(g,GetRectCenterX(gg_rct_RocketLaunch1),GetRectCenterY(gg_rct_RocketLaunch1),250,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if GetLocalPlayer() == GetOwningPlayer(temp) then
call SetUnitScale(temp,1.2,1.2,1.2)
endif
endloop
call GroupEnumUnitsInRange(g,GetRectCenterX(gg_rct_RocketLaunch2),GetRectCenterY(gg_rct_RocketLaunch2),250,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if GetLocalPlayer() == GetOwningPlayer(temp) then
call SetUnitScale(temp,1.2,1.2,1.2)
endif
endloop
call ReleaseGroup(g)
call RegisterSpellEffectEvent('A0D8',function RocketLaunchCast)
set g = null
endfunction
endscope
scope WarHall
globals
private constant integer BOMB_ID = 'A0BJ'
private constant integer BOSS_ID = 'A0BK'
private constant integer CTA_ID = 'A02U'
private constant integer SCT_ID = 'A0D9'
private constant string MISSILE1_SFX = "war3mapImported\\SFMB2.MDX"
private constant string MISSILE2_SFX = "war3mapImported\\SFMR2.MDX"
private constant string AREA_SFX = "war3mapImported\\Point Target.mdl"
private unit TEMP
endglobals
public function Update takes Team t, integer id, real cd, integer cost returns integer
local Team t2 = 2/t
local boolean lossing = t2.resources > t.resources
local integer d = t.resources - t2.resources
local real pd
local real cdf = cd / 2
local real cdr
local integer costf = cost / 2
local integer costr
if d < 0 then
set d = d * -1
endif
if d > 500 then
set d = 500
endif
set pd = I2R(d) / 500.00
if lossing then
set cdr = cd - cdf * pd
set costr = R2I(cost - costf * pd)
else
set cdr = cd + cdf * pd
set costr = R2I(cost + costf * pd)
endif
call BlzSetUnitAbilityCooldown(t.warHall,id,0,cdr)
call BlzSetAbilityIntegerField(BlzGetUnitAbility(t.warHall,id),ABILITY_IF_PRIORITY,costr)
return R2I(cdr)
endfunction
public function UpdateAbilities takes nothing returns nothing
//BOMB
local integer cd
local ability ab = BlzGetUnitAbility(Team[1].warHall,BOMB_ID)
local string tt = "Bombards the selected area with missiles, fire 4 sets of missiles each 3 seconds, each one deals |c00ff2b2bPhysical Damage|r and mini-stun the enemies within the area.|n|n|cff00ff00The cost and cooldown varies based on the resources difference.|r
|n|c0087cefaCount: |r4.|n|c0087cefaInterval: |r3s.|n|c0087cefaDamage x Set: |r100 + (2 * min).|n|c0087cefaArea of Effect: |r650."
local string tt2
set cd = Update(Team[1],BOMB_ID,180,100)
set tt2 = tt + "|n|c0087cefaResources Cost: |r|cffd45e19"+I2S(BlzGetAbilityIntegerField(ab,ABILITY_IF_PRIORITY))+"|r.|n|c0087cefaCooldown: |r|cffd45e19"+I2S(cd)+"s|r."
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,tt2)
set ab = BlzGetUnitAbility(Team[2].warHall,BOMB_ID)
set cd = Update(Team[2],BOMB_ID,180,100)
set tt2 = tt + "|n|c0087cefaResources Cost: |r|cffd45e19"+I2S(BlzGetAbilityIntegerField(ab,ABILITY_IF_PRIORITY))+".|n|c0087cefaCooldown: |r|cffd45e19"+I2S(cd)+"s|r."
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,tt2)
//CALL TO ARMS
set ab = BlzGetUnitAbility(Team[1].warHall,CTA_ID)
set cd = Update(Team[1],CTA_ID,150,100)
set tt = "Instantly summons the wave of units of the targeted controlled Tower using resources. The summoned units are buffed by |c00b4b4b4Inspire|r.|n|n|cff00ff00The cost and cooldown varies based on the resources difference.|r|n|n"
set tt2 = tt + "|c0087cefaResources Cost: |r|cffd45e19"+I2S(BlzGetAbilityIntegerField(ab,ABILITY_IF_PRIORITY))+".|n|c0087cefaCooldown: |r|cffd45e19"+I2S(cd)+"s|r."
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,tt2)
set ab = BlzGetUnitAbility(Team[2].warHall,CTA_ID)
set cd = Update(Team[2],CTA_ID,150,100)
set tt2 = tt + "|c0087cefaResources Cost: |r|cffd45e19"+I2S(BlzGetAbilityIntegerField(ab,ABILITY_IF_PRIORITY))+".|n|c0087cefaCooldown: |r|cffd45e19"+I2S(cd)+"s|r."
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,tt2)
//BOSS
set ab = BlzGetUnitAbility(Team[1].warHall,BOSS_ID)
set cd = Update(Team[1],BOSS_ID,200,150)
set tt = "The Commander assaults the selected Tower or Gold Mine, |c0000ced1Stunning|r all enemies around upon landing.|nThe Commander stats scales with the game time.|nThe Commander has |c00b4b4b4Shockwave|r, |c00b4b4b4Heroic Strike|r and |c00b4b4b4Inspire|r.|n|n|cff00ff00The cost and cooldown varies based on the resources difference.
|n|c0087cefaDuration: |r60s.|n|c0087cefaStun Duration: |r1.2s.|n|c0087cefaStun Area: |r900."
set tt2 = tt + "|n|c0087cefaResources Cost: |r|cffd45e19"+I2S(BlzGetAbilityIntegerField(ab,ABILITY_IF_PRIORITY))+"|n|c0087cefaCooldown: |r|cffd45e19"+I2S(cd)+"s|r."
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,tt2)
set ab = BlzGetUnitAbility(Team[2].warHall,BOSS_ID)
set cd = Update(Team[2],BOSS_ID,200,150)
set tt2 = tt + "|n|c0087cefaResources Cost: |r|cffd45e19"+I2S(BlzGetAbilityIntegerField(ab,ABILITY_IF_PRIORITY))+"|n|c0087cefaCooldown: |r|cffd45e19"+I2S(cd)+"s|r."
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,tt2)
//SANCTUARY
set ab = BlzGetUnitAbility(Team[1].warHall,SCT_ID)
set cd = Update(Team[1],SCT_ID,180,100)
set tt = "Selects a owned Tower or Gold Mine to place the Sanctuary which |c0000ff00Heals|r and recovers the loss Hp and Mp periodically of all alies around. Lasts for 5 seconds.|n|n|cff00ff00The cost and cooldown varies based on the resources difference.|r
|n|c0087cefaHeal/Mana Recover: |r20 + (2 * Min).|n|c0087cefaInterval: |r0.25s.|n|c0087cefaArea Of Effect: |r500."
set tt2 = tt + "|n|c0087cefaResources Cost: |r|cffd45e19"+I2S(BlzGetAbilityIntegerField(ab,ABILITY_IF_PRIORITY))+"|n|c0087cefaCooldown: |r|cffd45e19"+I2S(cd)+"s|r."
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,tt2)
set ab = BlzGetUnitAbility(Team[2].warHall,SCT_ID)
set cd = Update(Team[2],SCT_ID,180,100)
set tt2 = tt + "|n|c0087cefaResources Cost: |r|cffd45e19"+I2S(BlzGetAbilityIntegerField(ab,ABILITY_IF_PRIORITY))+"|n|c0087cefaCooldown: |r|cffd45e19"+I2S(cd)+"s|r."
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED,0,tt2)
endfunction
private function GetBombardDamage takes nothing returns real
return 150.00 + 2.00 * GameLoop.Minutes
endfunction
struct BombardMissile extends array
private static method onFinish takes Missile missile returns boolean
local group g
local unit temp
local Table tb = missile.level
if missile.damage != 0 then
set g = NewGroup()
call GroupEnumUnitsInRange(g,missile.x,missile.y,400,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if UnitAlive(temp) and IsUnitEnemy(temp,missile.owner) and not Status.UnitHasStatus(STATUS_INVULNERABLE,temp) then
if IsUnitType(temp,UNIT_TYPE_STRUCTURE) then
call CodeDamage.Damage(missile.source,temp,missile.damage/2,udg_DamageTypePhysical,"Bombard",0,0)
else
call CodeDamage.Damage(missile.source,temp,missile.damage,udg_DamageTypePhysical,"Bombard",0,0)
endif
call Status.Add(STATUS_STUN,temp,0.5,Status_EFFECT[STATUS_STUN])
endif
endloop
call ReleaseGroup(g)
set g = null
endif
if missile.data == 5 and missile.damage != 0 then
call DestroyEffect(tb.effect[6])
call DestroyFogModifier(tb.fogmodifier[5])
call tb.flush()
call tb.destroy()
endif
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real xt, real yt, real dmg, integer op, integer i, integer tb, integer c returns nothing
local real x = GetUnitX(source)
local real y = GetUnitY(source)
local Missile missile = Missile.createXYZ(x,y,200.0,xt,yt,0.0)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.speed = 100.00
set missile.arc = 45.* bj_DEGTORAD
if op == 1 then
set missile.model = MISSILE2_SFX
else
set missile.model = MISSILE1_SFX
endif
if i == 1 then
set missile.damage = dmg
endif
set missile.scale = 0.20
set missile.data = c
set missile.level = tb
call BombardMissile.launch(missile)
endfunction
private function Callback takes nothing returns nothing
local timer tr = GetExpiredTimer()
local Table tb = GetTimerData(tr)
local unit u = tb.unit[0]
local real x = tb.real[1]
local real y = tb.real[2]
local integer c = tb.integer[3]
local real dmg = tb.real[4]
local real a
local real d
local real tx
local real ty
local integer i = 0
set c = c + 1
set tb.integer[3] = c
if c == 1 then
call TimerStart(tr,3.00,true,function Callback)
endif
loop
exitwhen i == 10
set i = i + 1
if i == 1 then
set tx = x
set ty = y
else
set d = GetRandomReal(50,350)
set a = GetRandomReal(1,360) * bj_DEGTORAD
set tx = x + d * Cos(a)
set ty = y + d * Sin(a)
endif
call SetupMissile(u,tx,ty,dmg,GetUnitTeam(u),i,tb,c)
endloop
if c == 5 then
call ReleaseTimer(tr)
endif
set tr = null
set u = null
endfunction
private function Bombard takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local player p = GetOwningPlayer(u)
local Team t = GetPlayerTeamEx(p)
local effect sfx
local Table tb
local integer cost = BlzGetAbilityIntegerField(BlzGetUnitAbility(u,BOMB_ID),ABILITY_IF_PRIORITY)
if t.resources >= cost then
set t.resources = t.resources - cost
set tb = Table.create()
set tb.unit[0] = u
set tb.real[1] = x
set tb.real[2] = y
set tb.integer[3] = 0
set tb.real[4] = GetBombardDamage()
set tb.fogmodifier[5] = CreateFogModifierRadius(p,FOG_OF_WAR_VISIBLE,x,y,600.00,true,false)
call FogModifierStart(tb.fogmodifier[5])
set sfx = AddSpecialEffect(AREA_SFX,x,y)
call BlzSetSpecialEffectAlpha(sfx,200)
call BlzSetSpecialEffectTimeScale(sfx,0.01)
call BlzSetSpecialEffectScale(sfx,5.5)
set tb.effect[6] = sfx
if p == Game.PLAYER_WARCHIEF_HORDE then
call BlzSetSpecialEffectColor(sfx,255,0,0)
else
call BlzSetSpecialEffectColor(sfx,0,0,255)
endif
call TimerStart(NewTimerEx(tb),0.0,true,function Callback)
else
call UnitRemoveAbility(u,BOMB_ID)
call UnitAddAbility(u,BOMB_ID)
endif
set u = null
set p = null
set sfx = null
endfunction
private function ValidObjective takes real x, real y returns unit
local group g = NewGroup()
local integer id
local unit temp
local real dist = 99999
local real d
call GroupEnumUnitsInRange(g,x,y,1500,null)
set TEMP = null
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
set id = GetUnitTypeId(temp)
if id == 'n00N' or id == 'n006' or id == 'n009' then
set d = Distance(GetUnitX(temp),GetUnitY(temp),x,y)
if d < dist then
set dist = d
set TEMP = temp
endif
endif
endloop
call ReleaseGroup(g)
set temp = null
set g = null
return TEMP
endfunction
private function Assault takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = ValidObjective(GetSpellTargetX(),GetSpellTargetY())
local Team tm = GetPlayerTeamEx(GetTriggerPlayer())
local integer id = GetUnitTypeId(t)
local integer sw = 0
local GoldMine g = 0
local Base b = 0
local integer cost = BlzGetAbilityIntegerField(BlzGetUnitAbility(u,BOSS_ID),ABILITY_IF_PRIORITY)
set TEMP = null
if t != null then
if tm.resources >= cost then
set g = GoldMine.GetGoldMineFromUnit(t)
if g != 0 then
if g.owner != 0 then
call CommanderAssault.create(tm,0,g)
set tm.resources = tm.resources - cost
if tm == 1 then
call Message.Show(" |c00fdfd00Commander|r"+" has entered the battle",MESSAGE_STYLE_HORDE)
else
call Message.Show(" |c00fdfd00Commander|r"+" has entered the battle",MESSAGE_STYLE_ALLIANCE)
endif
else
call UnitRemoveAbility(u,BOMB_ID)
call UnitAddAbility(u,BOMB_ID)
endif
if tm == 1 then
call StartSound(gg_snd_HordeWarCry)
else
call StartSound(gg_snd_AllianceWarCry)
endif
else
set b = Base.GetBaseFromTower(t)
if b != 0 then
if b.owner != 0 then
call CommanderAssault.create(tm,b,0)
set tm.resources = tm.resources - cost
if tm == 1 then
call Message.Show(" |c00fdfd00Commander|r"+" has entered the battle",MESSAGE_STYLE_HORDE)
else
call Message.Show(" |c00fdfd00Commander|r"+" has entered the battle",MESSAGE_STYLE_ALLIANCE)
endif
else
call UnitRemoveAbility(u,BOSS_ID)
call UnitAddAbility(u,BOSS_ID)
endif
endif
if tm == 1 then
call StartSound(gg_snd_HordeWarCry)
else
call StartSound(gg_snd_AllianceWarCry)
endif
endif
else
call UnitRemoveAbility(u,BOSS_ID)
call UnitAddAbility(u,BOSS_ID)
endif
else
call UnitRemoveAbility(u,BOSS_ID)
call UnitAddAbility(u,BOSS_ID)
endif
set u = null
set t = null
endfunction
private function CallToArms takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local Team tm = GetPlayerTeamEx(GetTriggerPlayer())
local Base b = Base.GetBaseFromTower(t)
local integer cost = BlzGetAbilityIntegerField(BlzGetUnitAbility(u,CTA_ID),ABILITY_IF_PRIORITY)
if b != 0 then
if tm.resources >= cost then
set tm.resources = tm.resources - cost
call WarTroops_CallToArmsActions(b,tm)
if tm == 1 then
call StartSound(gg_snd_OrcBurrowBattleStationsWhat101)
call Message.Show(" has"+"|c00fdfd00"+" called to arms|r",MESSAGE_STYLE_HORDE)
else
call StartSound(gg_snd_HumanCallToArmsWhat101)
call Message.Show(" has"+"|c00fdfd00"+" called to arms|r",MESSAGE_STYLE_ALLIANCE)
endif
else
call UnitRemoveAbility(u,CTA_ID)
call UnitAddAbility(u,CTA_ID)
endif
endif
set u = null
set t = null
endfunction
private function SanctuaryCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local real x = tb.real[0]
local real y = tb.real[1]
local Base b = tb.integer[2]
local GoldMine g = tb.integer[3]
local Team tm = tb.integer[4]
local real d = tb.real[5]
local group gr = NewGroup()
local unit temp
local unit th = GetPlayerHero(tm.captain).hero
local real dmg = 20 + 2 * GameLoop.Minutes
call GroupEnumUnitsInRange(gr,x,y,500.00,null)
loop
set temp = FirstOfGroup(gr)
exitwhen temp == null
call GroupRemoveUnit(gr,temp)
if FILT_UNIT_ALLIED(temp,tm.captain) then
call CodeDamage.Damage(th,temp,dmg,udg_DamageTypeHeal,"",0,0)
call UnitAddMp(temp,dmg)
endif
endloop
set d = d - 0.25
set tb.real[5] = d
if d == 0 then
call ReleaseTimer(t)
call DestroyEffect(tb.effect[6])
call tb.flush()
call tb.destroy()
endif
call ReleaseGroup(gr)
set gr = null
set th = null
set t = null
endfunction
private function Sanctuary takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local Team tm = GetPlayerTeamEx(GetTriggerPlayer())
local Base b = Base.GetBaseFromTower(t)
local GoldMine g = GoldMine.GetGoldMineFromUnit(t)
local integer cost = BlzGetAbilityIntegerField(BlzGetUnitAbility(u,SCT_ID),ABILITY_IF_PRIORITY)
local Table tb
local integer sw = 0
if b != 0 then
if tm.resources >= cost then
set tm.resources = tm.resources - cost
set tb = Table.create()
set tb.real[0] = GetUnitX(t)
set tb.real[1] = GetUnitY(t)
set tb.integer[2] = b
set tb.integer[3] = 0
set tb.integer[4] = tm
set tb.real[5] = 5.00
set tb.effect[6] = AddSpecialEffect("war3mapImported\\Heaven's Gate Channel.mdx",tb.real[0],tb.real[1])
call BlzSetSpecialEffectScale(tb.effect[6],1.8)
call TimerStart(NewTimerEx(tb),0.25,true,function SanctuaryCallback)
set sw = 1
else
call UnitRemoveAbility(u,SCT_ID)
call UnitAddAbility(u,SCT_ID)
endif
elseif g != 0 then
if tm.resources >= cost then
set tm.resources = tm.resources - cost
set tb = Table.create()
set tb.real[0] = GetUnitX(t)
set tb.real[1] = GetUnitY(t)
set tb.integer[2] = b
set tb.integer[3] = 0
set tb.integer[4] = tm
set tb.real[5] = 5.00
set tb.effect[6] = AddSpecialEffect("war3mapImported\\Heaven's Gate Channel.mdx",tb.real[0],tb.real[1])
call BlzSetSpecialEffectScale(tb.effect[6],1.8)
call TimerStart(NewTimerEx(tb),0.25,true,function SanctuaryCallback)
set sw = 1
else
call UnitRemoveAbility(u,SCT_ID)
call UnitAddAbility(u,SCT_ID)
endif
endif
if sw == 1 then
if tm == 1 then
call Message.Show(" has activated a"+"|c00fdfd00"+" Sanctuary|r",MESSAGE_STYLE_HORDE)
else
call Message.Show(" has activated a"+"|c00fdfd00"+" Sanctuary|r",MESSAGE_STYLE_ALLIANCE)
endif
call StartSound(gg_snd_Sanctuary)
endif
set u = null
set t = null
endfunction
public function Setup takes nothing returns nothing
call RegisterSpellEffectEvent(BOMB_ID, function Bombard)
call RegisterSpellEffectEvent(BOSS_ID, function Assault)
call RegisterSpellEffectEvent(CTA_ID, function CallToArms)
call RegisterSpellEffectEvent(SCT_ID, function Sanctuary)
call BlzUnitDisableAbility(Team[1].warHall,BOSS_ID,true,false)
call BlzUnitDisableAbility(Team[2].warHall,BOSS_ID,true,false)
call BlzUnitDisableAbility(Team[1].warHall,CTA_ID,true,false)
call BlzUnitDisableAbility(Team[2].warHall,CTA_ID,true,false)
call BlzUnitDisableAbility(Team[1].warHall,BOMB_ID,true,false)
call BlzUnitDisableAbility(Team[2].warHall,BOMB_ID,true,false)
//call BlzUnitDisableAbility(Team[1].warHall,SCT_ID,true,false)
//call BlzUnitDisableAbility(Team[2].warHall,SCT_ID,true,false)
call CommanderAssault_Setup.evaluate()
endfunction
endscope
scope WaveAbilities initializer init
private function Heal takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local UnitGuardPath gp = UnitGuardPath[GetUnitUserData(u)]
if gp.path != 0 then
call gp.returnToPath()
endif
call CodeDamage.Damage(u,t,120,udg_DamageTypeHeal,"",0,0)
call Lightning.create("HWPB",u,t,0.7,0.25,0,100)
set u = null
set t = null
endfunction
private function Bloodlust takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local DefenderSquad ds = GetUnitData(u,"DSInstance")
if ds != 0 then
if ds.passive then
call ds.makeHostile(GetUnitX(t),GetUnitY(t),"")
endif
endif
set u = null
set t = null
endfunction
private function init takes nothing returns nothing
call RegisterSpellEffectEvent('Ahea', function Heal)
call RegisterSpellEffectEvent('ACbb', function Bloodlust)
endfunction
endscope
scope DefenderSquad
globals
LinkedList HORDE_DS
LinkedList ALLIANCE_DS
LinkedList NEUTRAL_DS
endglobals
struct DefenderBack extends array
DefenderSquad squad
boolean reach
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_INVULNERABLE,b.target)
set squad.invulCount = squad.invulCount - 1
if squad.invulCount == 0 then
set squad.passive = true
endif
call DestroyEffect(sfx)
call SetUnitPathing(b.target,true)
set sfx = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Point p
if not reach then
set p = GetUnitData(b.target,"DSPoint")
if Distance(GetUnitX(b.target),GetUnitY(b.target),p.x,p.y) <= 50 then
set reach = true
set squad.returnCount = squad.returnCount + 1
call IssueImmediateOrderById(b.target,ORDER_stop)
call SetUnitFacing(b.target,squad.angle)
else
if GetUnitCurrentOrder(b.target) != ORDER_move then
call IssuePointOrderById(b.target,ORDER_move,p.x,p.y)
endif
endif
endif
if reach and squad.returnCount == squad.units.size then
set b.removeInside = true
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Point p = GetUnitData(b.target,"DSPoint")
set squad = b.int
set sfx = AddSpecialEffectTarget("Abilities\\Spells\\Human\\DivineShield\\DivineShieldTarget.mdl",b.target,"origin")
call UnitAddAbility(b.target,'Arel')
call UnitMakeAbilityPermanent(b.target,true,'Arel')
call SetUnitAbilityLevel(b.target,'Arel',2)
call UnitAddAbility(b.target,'Abun')
call SetUnitPathing(b.target,false)
call UnitMakeAbilityPermanent(b.target,true,'Abun')
call Status.Add(STATUS_INVULNERABLE,b.target,0,0)
call IssuePointOrderById(b.target,ORDER_move,p.x,p.y)
if IsUnitInCombat(b.target) then
call LeaveUnitCombat(b.target,0)
endif
set reach = false
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Defender Back"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.10
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct DefenderSquad extends array
implement Alloc
LinkedList list
LinkedList units
GoldMine g
boolean passive
integer combatUnits
integer returnCount
integer invulCount
integer level
player owner
real angle
real x
real y
public method inspire takes nothing returns nothing
local Link h = units.head
local unit u
loop
exitwhen h == 0
set u = GetUnitByIndex(h.data)
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
set h = h.next
endloop
set u = null
endmethod
public method removeUnit takes unit u returns nothing
local Point p = GetUnitData(u,"DSPoint")
call p.destroy()
call units.remove(GetUnitData(u,"DSIndexList"))
call SetUnitData(u,"DSIndexList",0)
call SetUnitData(u,"DSInstance",0)
call SetUnitData(u,"DSPoint",0)
endmethod
public method makePassive takes nothing returns nothing
local Link h = units.head
local unit u
if invulCount != 0 then
return
endif
set returnCount = 0
set invulCount = 0
set combatUnits = 0
loop
exitwhen h == 0
set u = GetUnitByIndex(h.data)
set invulCount = invulCount + 1
call UnitAddBuff(u,u,99,DefenderBack.buff,0,this)
set h = h.next
endloop
set u = null
endmethod
public method makeHostile takes real x, real y, string txt returns nothing
local Link h = units.head
local unit u
if not passive then
return
endif
loop
exitwhen h == 0
set u = GetUnitByIndex(h.data)
call UnitRemoveAbility(u,'Arel')
call UnitRemoveAbility(u,'Abun')
if txt == "Bombard" then
call IssuePointOrder(u,"attack",GetUnitX(u),GetUnitY(u))
else
call IssuePointOrder(u,"attack",x,y)
endif
call EnterUnitCombat(u,null,0)
set combatUnits = combatUnits + 1
set h = h.next
endloop
set passive = false
set u = null
endmethod
public method createUnits takes nothing returns nothing
local Link h = list.head
local real a
local integer lvl = BaseTroops[4*(g.owner-1) + g].level
local real asep = 180 / list.size
local real iang = angle - (asep * (list.size / 2))
local unit u
local real xc
local real yc
local integer index
local integer c = 0
local integer mid = (list.size / 2) + 1
local real distance = 150
local Point p
set level = lvl
loop
exitwhen h == 0
set c = c + 1
set a = iang * bj_DEGTORAD
set xc = x + distance * Cos(a)
set yc = y + distance * Sin(a)
set iang = iang + asep
if c < mid then
set distance = distance + 75.00
else
set distance = distance - 5.00
endif
if h.data != -1 then
set p = Point.create(xc,yc)
set u = CreateUnit(owner,h.data,xc,yc,angle)
call RemoveGuardPosition(u)
call UnitAddAbility(u,'Abun')
call UnitMakeAbilityPermanent(u,true,'Abun')
call UnitAddAbility(u,'Arel')
call UnitMakeAbilityPermanent(u,true,'Arel')
set index = units.add(GetUnitUserData(u))
call SetUnitData(u,"DSIndexList",index)
call SetUnitData(u,"DSInstance",this)
call SetUnitData(u,"DSPoint",p)
call SetUnitData(u,"DSAttack",0 )
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,100,0)
if owner != Game.PLAYER_NEUTRAL_HOSTILE then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,30 * lvl,0)
if h.data == 'h00I' or h.data == 'o005' then
call SetUnitAbilityLevel(u,'ACpv',lvl)
call BlzSetUnitMaxHP(u,500 + 500 * lvl)
call BlzSetUnitBaseDamage(u,39 + 20 * lvl,0)
call BlzSetUnitArmor(u,5 * lvl)
if owner == Game.PLAYER_WARCHIEF_HORDE then
call BlzSetUnitName(u,"Warlord "+I2S(lvl))
else
call BlzSetUnitName(u,"Captain "+I2S(lvl))
endif
endif
if h.data == 'o007' or h.data == 'o008' then
call SetUnitAbilityLevel(u,'ACbb',lvl)
call BlzSetUnitMaxHP(u,300 + 100 * lvl)
call BlzSetUnitBaseDamage(u,19 + 5 * lvl,0)
call BlzSetUnitArmor(u,2 + lvl)
endif
endif
call SetUnitState(u,UNIT_STATE_LIFE,9999999)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",GetUnitX(u),GetUnitY(u)))
endif
set h = h.next
endloop
set passive = true
set u = null
endmethod
public static method create takes real xc, real yc, LinkedList pool, real a, player o, GoldMine gm returns thistype
local thistype this = thistype.allocate()
set list = pool
set units = LinkedList.create()
set owner = o
set angle = a
set g = gm
set combatUnits = 0
set x = xc
set y = yc
set returnCount = 0
set invulCount = 0
call createUnits()
if owner == Game.PLAYER_WARCHIEF_HORDE then
if Team[1].commander.commanderAssault != 0 then
if Team[1].commander.commanderAssault.mineTarget == g then
call inspire()
endif
endif
elseif owner == Game.PLAYER_WARCHIEF_ALLIANCE then
if Team[2].commander.commanderAssault != 0 then
if Team[2].commander.commanderAssault.mineTarget == g then
call inspire()
endif
endif
endif
return this
endmethod
public method destroy takes nothing returns nothing
local Link h = units.head
local Point p
local unit u
loop
exitwhen h == 0
set u = GetUnitByIndex(h.data)
set p = GetUnitData(u,"DSPoint")
call p.destroy()
call SetUnitData(u,"DSIndexList",0)
call SetUnitData(u,"DSInstance",0)
call SetUnitData(u,"DSPoint",0)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",GetUnitX(u),GetUnitY(u)))
call RemoveUnit(u)
set h = h.next
endloop
set list = 0
call units.destroy()
set owner = null
set u = null
call this.deallocate()
endmethod
endstruct
private function OnDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
local group g
local unit temp
local effect sfx
local DefenderSquad c
local player p = GetOwningPlayer(d.target)
local real d1
local integer lvl
local integer ac
if d.dmgType == udg_DamageTypeHeal or d.dmgType == udg_DamageTypeHealOverTime then
set p = null
return
endif
if p == Game.PLAYER_WARCHIEF_HORDE or p == Game.PLAYER_WARCHIEF_ALLIANCE or p == Game.PLAYER_NEUTRAL_HOSTILE then
set c = GetUnitData(d.target,"DSInstance")
if c != 0 then
set d1 = Distance(GetUnitX(d.target),GetUnitY(d.target),c.x,c.y)
if d1 > 750 and d.codeDmg.codeName != "Bombard" then
call c.makePassive()
else
if UnitAlive(d.source) then
call c.makeHostile(GetUnitX(d.source),GetUnitY(d.source),d.codeDmg.codeName)
endif
endif
endif
endif
set p = GetOwningPlayer(d.source)
if p == Game.PLAYER_WARCHIEF_HORDE or p == Game.PLAYER_WARCHIEF_ALLIANCE or p == Game.PLAYER_NEUTRAL_HOSTILE then
set c = GetUnitData(d.source,"DSInstance")
if c != 0 then
set d1 = Distance(GetUnitX(d.source),GetUnitY(d.source),c.x,c.y)
if d1 > 750 then
call c.makePassive()
endif
endif
endif
if d.dmgType == udg_DamageTypeAttack and d.mainAttack and not d.isMiss and d.damageMod > 0 then
set lvl = GetUnitAbilityLevel(d.source,'ACpv')
if lvl != 0 then
set ac = GetUnitData(d.source,"DSAttack") + 1
if ac == 3 then
call SetUnitData(d.source,"DSAttack",0)
set p = GetOwningPlayer(d.source)
set g = NewGroup()
call GroupEnumUnitsInRange(g,GetUnitX(d.target),GetUnitY(d.target),320,null)
set d1 = 80 + 20 * lvl
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and temp != d.target then
call CodeDamage.Damage(d.source,temp,d1,udg_DamageTypeAttack,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set sfx = AddSpecialEffect("Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl",GetUnitX(d.target),GetUnitY(d.target))
call BlzSetSpecialEffectScale(sfx,0.80)
call DestroyEffect(sfx)
set sfx = null
else
call SetUnitData(d.source,"DSAttack",ac)
endif
endif
endif
set p = null
endfunction
private function OnDeath takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetKillingUnit()
local player p
local DefenderSquad ds
if not IsUnitType(u,UNIT_TYPE_STRUCTURE) then
set ds = GetUnitData(u,"DSInstance")
if ds != 0 then
set p = GetOwningPlayer(t)
set ds.combatUnits = ds.combatUnits - 1
call ds.removeUnit(u)
if ds.units.size == 0 then
if p != Game.PLAYER_NEUTRAL_HOSTILE then
call ds.g.changeOwner(p)
else
call ds.g.changeOwner(Game.PLAYER_NEUTRAL_HOSTILE)
endif
call ds.destroy()
endif
set p = null
endif
endif
set u = null
set t = null
endfunction
private function OnLeaveCombat takes nothing returns nothing
local unit u = GetEventCombatLeaveUnit()
local DefenderSquad ds
if not IsUnitType(u,UNIT_TYPE_STRUCTURE) and GetEventCombatLeaveID() != -1 then
set ds = GetUnitData(u,"DSInstance")
if ds != 0 then
if not UnitHasBuff(u,DefenderBack.buff) then
set ds.combatUnits = ds.combatUnits - 1
if ds.combatUnits == 0 then
call ds.makePassive()
endif
endif
endif
endif
set u = null
endfunction
private function SetupLists takes nothing returns nothing
set ALLIANCE_DS = LinkedList.create()
call ALLIANCE_DS.add('o008')
call ALLIANCE_DS.add('h00I')
call ALLIANCE_DS.add('o008')
set HORDE_DS = LinkedList.create()
call HORDE_DS.add('o007')
call HORDE_DS.add('o005')
call HORDE_DS.add('o007')
set NEUTRAL_DS = LinkedList.create()
call NEUTRAL_DS.add('nbrg')
call NEUTRAL_DS.add('nban')
call NEUTRAL_DS.add('nbld')
call NEUTRAL_DS.add('nban')
call NEUTRAL_DS.add('nbrg')
set GoldMine[1].defenders = DefenderSquad.create(GoldMine[1].x,GoldMine[1].y,NEUTRAL_DS,GoldMine[1].a,Game.PLAYER_NEUTRAL_HOSTILE,GoldMine[1])
set GoldMine[2].defenders = DefenderSquad.create(GoldMine[2].x,GoldMine[2].y,NEUTRAL_DS,GoldMine[2].a,Game.PLAYER_NEUTRAL_HOSTILE,GoldMine[2])
set GoldMine[3].defenders = DefenderSquad.create(GoldMine[3].x,GoldMine[3].y,NEUTRAL_DS,GoldMine[3].a,Game.PLAYER_NEUTRAL_HOSTILE,GoldMine[3])
set GoldMine[4].defenders = DefenderSquad.create(GoldMine[4].x,GoldMine[4].y,NEUTRAL_DS,GoldMine[4].a,Game.PLAYER_NEUTRAL_HOSTILE,GoldMine[4])
endfunction
struct Fervor extends array
integer as
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = 30 + 5 * b.level
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
set sfx = AddSpecialEffectTarget("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl",b.target,"weapon")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05Y'
set BUFF_DATA.BuffID = 'B02A'
set BUFF_DATA.Name = "Fervor"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function FervorCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
call UnitRemoveAbility(t,'Bblo')
call UnitAddBuff(t,u,7.0,Fervor.buff,GetUnitAbilityLevel(u,'ACbb'),0)
set u = null
set t = null
endfunction
public function Setup takes nothing returns nothing
call SetupLists()
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call RegisterPlayerUnitEventForPlayer(EVENT_PLAYER_UNIT_DEATH,function OnDeath,Game.PLAYER_WARCHIEF_HORDE)
call RegisterPlayerUnitEventForPlayer(EVENT_PLAYER_UNIT_DEATH,function OnDeath,Game.PLAYER_WARCHIEF_ALLIANCE)
call RegisterPlayerUnitEventForPlayer(EVENT_PLAYER_UNIT_DEATH,function OnDeath,Game.PLAYER_NEUTRAL_HOSTILE)
call RegisterCombatEvent(function OnLeaveCombat,EVENT_UNIT_LEAVE_COMBAT)
call DefenderBack.Initialize()
call Fervor.Initialize()
call RegisterSpellEffectEvent('ACbb', function FervorCast)
endfunction
endscope
library AncientObelisk uses TimerUtils, PlayerLib, MiscLibrary
globals
private constant integer ITEM_ID = 'I014'
private constant integer SPELL_ID = 'ANcl'
private constant real CONTROL_TIME = 15.00
private constant real TEXT_SIZE = 20 * 0.023 / 10
private constant integer GOLD_REWARD = 200
private trigger CONTROL_TRIGGER
RSound ObeliskHealSound
endglobals
struct AncientObelisk extends array
static unit obelisk
static unit currentHero = null
static real time = 0
static real timeC = 0
static real timeE = 0
static real timeP = 0
static real x
static real y
static real angle
static Team owner = 0
static boolean enabled = false
static timer t
static real percent
static texttag text
static minimapicon icon
static Table AI_current
public static method getCurrentHeroes takes Team t returns integer
return AI_current.integer[t]
endmethod
public static method addCurrentHeroes takes Team t, integer i returns nothing
set AI_current.integer[t] = AI_current.integer[t] + i
endmethod
public static method Enable takes boolean b returns nothing
set enabled = b
if b then
call SetUnitAnimation(obelisk,"stand alternate")
else
set timeP = 0
call SetUnitAnimation(obelisk,"stand")
endif
endmethod
public static method ChangeOwner takes boolean neutral returns nothing
if not neutral then
call SetUnitOwner(obelisk,owner.captain,true)
call SetUnitAnimation(obelisk,"stand work")
call BlzSetUnitMaxMana(obelisk,180)
call UnitAddAbility(obelisk,'A01U')
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl",x,y))
call UnitRemoveAbility(obelisk,'Apit')
call DestroyMinimapIcon(icon)
if owner == 1 then
set icon = CreateMinimapIconOnUnit(AncientObelisk.obelisk, 255, 255, 255, "war3mapImported\\MiniMap-obelisk-horde.mdx", FOG_OF_WAR_FOGGED )
else
set icon = CreateMinimapIconOnUnit(AncientObelisk.obelisk, 255, 255, 255, "war3mapImported\\MiniMap-obelisk-alliance.mdx", FOG_OF_WAR_FOGGED )
endif
else
set owner = 0
set timeC = 0
call SetUnitOwner(obelisk,Game.PLAYER_NEUTRAL_EXTRA,true)
call SetUnitAnimation(obelisk,"stand")
call BlzSetUnitMaxMana(obelisk,0)
call UnitRemoveAbility(obelisk,'A01U')
call UnitAddAbility(obelisk,'Apit')
call SetUnitAnimation(obelisk,"stand alternate")
call DestroyMinimapIcon(icon)
set icon = CreateMinimapIconOnUnit(AncientObelisk.obelisk, 255, 255, 255, "war3mapImported\\MiniMap-obelisk-neutral.mdx", FOG_OF_WAR_FOGGED )
set currentHero = null
endif
endmethod
private static method Loop takes nothing returns nothing
if GetUnitCurrentOrder(currentHero) == ORDER_channel then
set time = time + 0.03125
set percent = (time*100) / CONTROL_TIME
call SetTextTagText(text,I2S(R2I(percent))+"%",TEXT_SIZE)
if time >= CONTROL_TIME then
set time = 0.00
set owner = GetUnitTeam(currentHero)
set Players[GetPlayerId(GetOwningPlayer(currentHero))].obeliskT = Players[GetPlayerId(GetOwningPlayer(currentHero))].obeliskT + 1
call ChangeOwner(false)
call AddTeamGold(owner,GOLD_REWARD)
if owner == 1 then
call Message.Show(" has captured the Ancient Obelisk"+" ("+GOLD_COLOR+"+200|r)",MESSAGE_STYLE_HORDE)
else
call Message.Show(" has captured the Ancient Obelisk"+" ("+GOLD_COLOR+"+200|r)",MESSAGE_STYLE_ALLIANCE)
endif
call DestroyTextTag(text)
set text = null
call PauseTimer(t)
call UnitRemoveAbility(currentHero,SPELL_ID)
set currentHero = null
call StartSound(gg_snd_ObeliskCapture)
endif
else
call UnitRemoveAbility(currentHero,SPELL_ID)
call DestroyTextTag(text)
call PauseTimer(t)
set text = null
set time = 0.00
set percent = 0
set currentHero = null
endif
endmethod
public static method Control takes unit u returns nothing
local Hero h = GetUnitData(u,"HeroIndex")
call UnitAddAbility(u,SPELL_ID)
if IssueImmediateOrderById(u,ORDER_channel) then
set currentHero = u
set time = 0
set timeC = 0
set percent = 0
if h.heroAI != -1 then
set h.heroAI.channelingOrder = ORDER_channel
endif
set text = CreateTextTag()
call SetTextTagPermanent(text,false)
call SetTextTagText(text,I2S(R2I(percent))+"%",TEXT_SIZE)
call SetTextTagPos(text,x - 25,y,390)
call SetTextTagColor(text,255,255,0,255)
call TimerStart(t,0.03125,true,function thistype.Loop)
else
call UnitRemoveAbility(u,SPELL_ID)
endif
endmethod
public static method RegisterHero takes unit u returns nothing
call TriggerRegisterUnitEvent(CONTROL_TRIGGER,u,EVENT_UNIT_ISSUED_TARGET_ORDER)
endmethod
endstruct
function ObeliskRay takes nothing returns nothing
local integer i
local integer j
local integer c = 1
local Hero h1 = 0
local Hero h = 0
if AncientObelisk.owner == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
if Players[i].isPlaying then
set h1 = Players[i].hero
if Game.Mode == GAME_MODE_NORMAL then
if UnitAlive(h1.hero) and IsUnitInCombat(h1.hero) then
if GetRandomInt(1,c) == 1 then
set h = h1
endif
set c = c + 1
endif
endif
endif
set i = i + 1
exitwhen i > j
endloop
if h != 0 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\HealingWave\\HealingWaveTarget.mdl",h.hero,"origin"))
call CodeDamage.Damage(AncientObelisk.obelisk,h.hero,50 + 2 * GameLoop.Minutes,udg_DamageTypeHeal,"",0,0)
call Lightning.create("HWPB",AncientObelisk.obelisk,h.hero,0.9,0.25,370,75)
call ObeliskHealSound.play(GetUnitX(h.hero),GetUnitY(h.hero),0,120)
endif
endfunction
private function RightClick takes nothing returns nothing
local unit u = GetOrderedUnit()
local unit t = GetOrderTargetUnit()
local real d
if GetIssuedOrderId() == ORDER_smart and Game.Mode == GAME_MODE_NORMAL and t == AncientObelisk.obelisk then
set d = DistanceBetweenUnits(u,AncientObelisk.obelisk)
if AncientObelisk.currentHero == null and AncientObelisk.owner == 0 and AncientObelisk.enabled and d <= 200.00 then
call AncientObelisk.Control(u)
endif
endif
set u = null
set t = null
endfunction
public function Setup takes nothing returns nothing
set AncientObelisk.obelisk = gg_unit_n00C_0039
set AncientObelisk.t = CreateTimer()
set CONTROL_TRIGGER = CreateTrigger()
call TriggerAddCondition(CONTROL_TRIGGER,function RightClick)
set AncientObelisk.x = GetUnitX(gg_unit_n00C_0039)
set AncientObelisk.y = GetUnitY(gg_unit_n00C_0039)
set AncientObelisk.enabled = false
set AncientObelisk.angle = 0
set AncientObelisk.AI_current = Table.create()
call SetUnitOwner(AncientObelisk.obelisk,Game.PLAYER_NEUTRAL_EXTRA,true)
set AncientObelisk.icon = CreateMinimapIconOnUnit(AncientObelisk.obelisk, 255, 255, 255, "war3mapImported\\MiniMap-obelisk-neutral.mdx", FOG_OF_WAR_FOGGED )
set ObeliskHealSound = RSound.create("Abilities\\Spells\\Orc\\HealingWave\\HealingWave.flac", true, true, 12700, 12700)
endfunction
endlibrary
library BaseLib uses ControlBase, BaseTroops, UnitRecycler
globals
private constant integer BANNER_HORDE = 'n005'
private constant integer BANNER_ALLIANCE = 'n008'
private constant integer BANNER_NEUTRAL = 'n00I'
private constant integer TOWER_HORDE = 'n009'
private constant integer TOWER_ALLIANCE = 'n006'
private constant integer TROOP_HORDE = 'n00C'
private constant integer TROOP_ALLIANCE = 'n00V'
private constant string TOWER_SFX_DEATH = "buildings\\other\\TowerDefenseTower\\TowerDefenseTower.mdl"
private constant string UPGRADE_SFX = "Objects\\Spawnmodels\\Human\\HCancelDeath\\HCancelDeath.mdl"
constant integer BASE_STATE_NEUTRAL = 0
constant integer BASE_STATE_CONTROLED = 1
constant integer BASE_STATE_TAKING = 3
private constant real SPAWN_TEXT_SIZE = 25 * 0.023 / 10
unit array TowerUnit[9]
private trigger SelectTrigger
endglobals
struct Base extends array
real x
real y
rect r
integer state
texttag spawn
Team owner
Team controlTeam
integer controlUnits
real time
unit dummyPlatform
unit neutralBanner
unit tower
unit target
boolean goldMineAttack
boolean callToArmsSpawn
BaseTroops baseTroops
minimapicon icon
static HashTable AI_count
static HashTable AI_current
static real UpgradeCount
static integer Level
//For Teleport
real angle
//For control
LoadingBar bar
AoE aoe
//For AI
LinkedList waves
public static method UpdateSpawnText takes nothing returns nothing
local integer i = 0
local Base b
loop
set i = i + 1
set b = thistype[i]
if b.owner != 0 then
call SetTextTagText(b.spawn,I2S(b.owner.waveTime),SPAWN_TEXT_SIZE)
endif
exitwhen i == 4
endloop
endmethod
public static method Safe takes Base b, Team t returns boolean
local Team t2 = 2/t
if b == 1 then
return Base[2].owner != t2 and Base[4].owner != t2
endif
if b == 2 then
return Base[1].owner != t2 and Base[3].owner != t2
endif
if b == 3 then
return Base[2].owner != t2 and Base[4].owner != t2
endif
if b == 4 then
return Base[1].owner != t2 and Base[3].owner != t2
endif
return false
endmethod
private static method UpgradeTowers takes nothing returns nothing
local integer i = 0
if thistype.Level < 5 then
call Message.Show("The level of Towers and Defenders has been increased. ",MESSAGE_STYLE_INFO)
set thistype.Level = thistype.Level +1
loop
set i = i + 1
if not IsUnitHidden(TowerUnit[i]) then
call DestroyEffect(AddSpecialEffectTarget(UPGRADE_SFX,TowerUnit[i],"origin"))
endif
call BlzSetUnitMaxMana(TowerUnit[i],600)
call BlzSetUnitName(TowerUnit[i],"Tower Level " + I2S(thistype.Level))
call BonusStruct.Add(BONUS_TYPE_HP,TowerUnit[i],500,0,false)
call UnitRemoveHp(TowerUnit[i],250)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,TowerUnit[i],30,0,false)
call BonusStruct.Add(BONUS_TYPE_ARMOR,TowerUnit[i],10,0,false)
call BaseTroops[i].increaseLevel()
exitwhen i == 8
endloop
if GoldMine[1].owner != 0 then
call GoldMine[1].updateDefenders()
endif
if GoldMine[2].owner != 0 then
call GoldMine[2].updateDefenders()
endif
if GoldMine[3].owner != 0 then
call GoldMine[3].updateDefenders()
endif
if GoldMine[4].owner != 0 then
call GoldMine[4].updateDefenders()
endif
endif
endmethod
public static method UpgradeLoop takes nothing returns nothing
local integer i = 0
if thistype.Level == 5 then
return
endif
set UpgradeCount = UpgradeCount - 1
if UpgradeCount == 0 then
set UpgradeCount = 600
call thistype.UpgradeTowers()
endif
loop
set i = i + 1
call SetUnitState(TowerUnit[i],UNIT_STATE_MANA,GetUnitState(TowerUnit[i],UNIT_STATE_MAX_MANA) - UpgradeCount)
exitwhen i == 8
endloop
endmethod
public method getCurrentHeroes takes Team t returns integer
return AI_current[t].integer[this]
endmethod
public method getHeroesTarget takes Team t returns integer
return AI_count[t].integer[this]
endmethod
public method addHeroesTarget takes Team t, integer i returns nothing
set AI_count[t].integer[this] = AI_count[t].integer[this] + i
endmethod
public method addCurrentHeroes takes Team t, integer i returns nothing
set AI_current[t].integer[this] = AI_current[t].integer[this] + i
endmethod
public static method GetBaseFromTower takes unit t returns thistype
if TowerUnit[1] == t or TowerUnit[5] == t then
return thistype[1]
elseif TowerUnit[2] == t or TowerUnit[6] == t then
return thistype[2]
elseif TowerUnit[3] == t or TowerUnit[7] == t then
return thistype[3]
elseif TowerUnit[4] == t or TowerUnit[8] == t then
return thistype[4]
endif
return 0
endmethod
public method changeOwner takes nothing returns nothing
local real r
call UnitRemoveBuff(tower,RefineDefences.buff)
call UnitRemoveBuff(tower,RefineWeapons.buff)
call ShowUnit(neutralBanner,false)
call ShowUnit(tower,false)
call UnitRemoveAbility(tower,'A0BD')
call PauseUnit(tower,true)
call UnitIgnoreAlarm(tower,true)
call UnitAddAbility(tower,'A0B4')
call DestroyMinimapIcon(icon)
//call SetUnitPosition(bannerDummy,Game.HIDE_X,Game.HIDE_Y)
//call SetUnitPosition(tower,Game.HIDE_X,Game.HIDE_Y)
if owner == 0 then
set tower = null
call SetUnitOwner(dummyPlatform,Game.PLAYER_NEUTRAL_EXTRA,false)
call SetUnitColor(dummyPlatform,PLAYER_COLOR_LIGHT_GRAY)
call UnitRemoveAbility(neutralBanner,'Aloc')
call ShowUnit(neutralBanner,true)
call UnitAddAbility(neutralBanner,'Aloc')
call SetTextTagVisibility(spawn,false)
set icon = CreateMinimapIconOnUnit(dummyPlatform, 255, 255, 255, "war3mapImported\\MiniMap-tower-neutral.mdx", FOG_OF_WAR_FOGGED )
else
if owner == Team[1] then
set tower = TowerUnit[this]
call SetUnitOwner(dummyPlatform,Game.PLAYER_WARCHIEF_HORDE,false)
call SetUnitColor(dummyPlatform,PLAYER_COLOR_RED)
call SetUnitColor(tower,PLAYER_COLOR_RED)
set baseTroops = BaseTroops[this]
set baseTroops.base = this
set icon = CreateMinimapIconOnUnit(dummyPlatform, 255, 255, 255, "war3mapImported\\MiniMap-tower-horde.mdx", FOG_OF_WAR_FOGGED )
elseif owner == Team[2] then
set tower = TowerUnit[4 + this]
call SetUnitOwner(dummyPlatform,Game.PLAYER_WARCHIEF_ALLIANCE,false)
call SetUnitColor(dummyPlatform,PLAYER_COLOR_BLUE)
call SetUnitColor(tower,PLAYER_COLOR_BLUE)
set baseTroops = BaseTroops[4 + this]
set baseTroops.base = this
set icon = CreateMinimapIconOnUnit(dummyPlatform, 255, 255, 255, "war3mapImported\\MiniMap-tower-alliance.mdx", FOG_OF_WAR_FOGGED )
endif
call SetTextTagVisibility(spawn,true)
call WarTroops_UpdateTeamSpawnTime(owner)
call SetTextTagText(spawn,I2S(owner.waveTime),SPAWN_TEXT_SIZE)
call ShowUnit(tower,true)
call UnitRemoveAbility(tower,'A0B4')
call UnitAddAbility(tower,'A0BD')
call UnitMakeAbilityPermanent(tower,true,'A0BD')
call PauseUnit(tower,false)
call UnitIgnoreAlarm(tower,false)
call SetUnitPosition(tower,x,y)
set angle = 180
endif
endmethod
public method Create takes rect reg returns nothing
set owner = 0
set state = BASE_STATE_NEUTRAL
set x = GetRectCenterX(reg)
set y = GetRectCenterY(reg)
set r = reg
set bar = LoadingBar.create()
call bar.setLoc(x,y,GetLocZ(x,y) + 400.00)
call bar.setSize(2.5)
set neutralBanner = CreateUnit(Game.PLAYER_NEUTRAL_EXTRA,'n00I',x,y,270)
//call UnitSetUsesAltIcon(CreateUnit(Game.PLAYER_NEUTRAL_EXTRA,'n00L',x,y,0) ,true)
set dummyPlatform = CreateUnit(Game.PLAYER_NEUTRAL_EXTRA,'n00M',x,y,0)
call SetUnitColor(dummyPlatform,PLAYER_COLOR_LIGHT_GRAY)
call UnitAddAbility(neutralBanner,'Aloc')
set icon = CreateMinimapIconOnUnit(dummyPlatform, 255, 255, 255, "war3mapImported\\MiniMap-tower-neutral.mdx", FOG_OF_WAR_FOGGED )
set AI_count[1].integer[this] = 0
set AI_count[2].integer[this] = 0
set spawn = CreateTextTag()
call SetTextTagText(spawn,"",SPAWN_TEXT_SIZE)
call SetTextTagPos(spawn,GetUnitX(dummyPlatform) - 30.00,GetUnitY(dummyPlatform),425.00)
call SetTextTagPermanent(spawn,true)
call SetTextTagVisibility(spawn,false)
call SetTextTagColor(spawn,255,255,0,255)
set controlUnits = 0
set controlTeam = 0
set target = null
set angle = 180
set goldMineAttack = true
set callToArmsSpawn = false
endmethod
endstruct
private function PrepareBannerUnits takes nothing returns nothing
set TowerUnit[1] = CreateUnit(Game.PLAYER_WARCHIEF_HORDE,TOWER_HORDE,Game.HIDE_X,Game.HIDE_Y,270)
set TowerUnit[2] = CreateUnit(Game.PLAYER_WARCHIEF_HORDE,TOWER_HORDE,Game.HIDE_X,Game.HIDE_Y,270)
set TowerUnit[3] = CreateUnit(Game.PLAYER_WARCHIEF_HORDE,TOWER_HORDE,Game.HIDE_X,Game.HIDE_Y,270)
set TowerUnit[4] = CreateUnit(Game.PLAYER_WARCHIEF_HORDE,TOWER_HORDE,Game.HIDE_X,Game.HIDE_Y,270)
set TowerUnit[5] = CreateUnit(Game.PLAYER_WARCHIEF_ALLIANCE,TOWER_ALLIANCE,Game.HIDE_X,Game.HIDE_Y,270)
set TowerUnit[6] = CreateUnit(Game.PLAYER_WARCHIEF_ALLIANCE,TOWER_ALLIANCE,Game.HIDE_X,Game.HIDE_Y,270)
set TowerUnit[7] = CreateUnit(Game.PLAYER_WARCHIEF_ALLIANCE,TOWER_ALLIANCE,Game.HIDE_X,Game.HIDE_Y,270)
set TowerUnit[8] = CreateUnit(Game.PLAYER_WARCHIEF_ALLIANCE,TOWER_ALLIANCE,Game.HIDE_X,Game.HIDE_Y,270)
call RemoveGuardPosition(TowerUnit[1])
call RemoveGuardPosition(TowerUnit[2])
call RemoveGuardPosition(TowerUnit[3])
call RemoveGuardPosition(TowerUnit[4])
call RemoveGuardPosition(TowerUnit[5])
call RemoveGuardPosition(TowerUnit[6])
call RemoveGuardPosition(TowerUnit[7])
call RemoveGuardPosition(TowerUnit[8])
call ShowUnit(TowerUnit[1],false)
call ShowUnit(TowerUnit[2],false)
call ShowUnit(TowerUnit[3],false)
call ShowUnit(TowerUnit[4],false)
call ShowUnit(TowerUnit[5],false)
call ShowUnit(TowerUnit[6],false)
call ShowUnit(TowerUnit[7],false)
call ShowUnit(TowerUnit[8],false)
set Index[GetUnitUserData(TowerUnit[1])].lock = true
set Index[GetUnitUserData(TowerUnit[2])].lock = true
set Index[GetUnitUserData(TowerUnit[3])].lock = true
set Index[GetUnitUserData(TowerUnit[4])].lock = true
set Index[GetUnitUserData(TowerUnit[5])].lock = true
set Index[GetUnitUserData(TowerUnit[6])].lock = true
set Index[GetUnitUserData(TowerUnit[7])].lock = true
set Index[GetUnitUserData(TowerUnit[8])].lock = true
endfunction
private function onPostDamageTower takes nothing returns nothing
local DamageData d = DamageEvent.EventData
local unit t = d.target
local Base b
if GetUnitTypeId(t) == TOWER_HORDE or GetUnitTypeId(t) == TOWER_ALLIANCE then
if GetUnitState(t,UNIT_STATE_LIFE) - d.damageMod < 0.41 then
call SetUnitState(t, UNIT_STATE_LIFE, 9999999)
set d.damageMod = 0
set d.isAbsorbed = true
set b = Base.GetBaseFromTower(t)
set b.owner.bases = b.owner.bases - 1
call MultiboardUpdateTeamBases(b.owner)
call TowerLossSound.play(0,0,0,100)
if b.owner == 1 then
call Message.Show(" lost a |c00ff8000Tower|r",MESSAGE_STYLE_HORDE)
call WarTroops_UpdateTeamSpawnTime(Team[1])
elseif b.owner == 2 then
call Message.Show(" lost a |c00ff8000Tower|r",MESSAGE_STYLE_ALLIANCE)
call WarTroops_UpdateTeamSpawnTime(Team[2])
endif
set b.owner = 0
set b.state = BASE_STATE_NEUTRAL
call b.changeOwner()
call DestroyEffect(AddSpecialEffect(TOWER_SFX_DEATH,b.x,b.y))
endif
endif
set t = null
endfunction
public function Setup takes nothing returns nothing
set Base.AI_count = HashTable.create()
set Base.AI_current = HashTable.create()
set Base.UpgradeCount = 900
set Base.Level = 1
call Base[1].Create(gg_rct_Base1)
call Base[2].Create(gg_rct_Base2)
call Base[3].Create(gg_rct_Base3)
call Base[4].Create(gg_rct_Base4)
//Create Event for Control
call PrepareBannerUnits()
call ControlBase_Setup()
call BaseTroops_Setup()
call DamageEvent.RegisterPostCalculation(Filter(function onPostDamageTower))
call Preload(TOWER_SFX_DEATH)
endfunction
endlibrary
library BaseTroops initializer init uses UnitRecycler, GuardPath
globals
private constant integer TROOPS_MAX_LEVEL = 5
public constant integer BASIC_MEELE_HORDE = 'o000'
public constant integer BASIC_MEELE_ALLIANCE = 'o002'
public constant integer BASIC_RANGED_HORDE = 'o001'
public constant integer BASIC_RANGED_ALLIANCE = 'h000'
HashTable TroopData
endglobals
private function AddTroopData takes integer id, integer lvl, integer t returns nothing
set TroopData[t][lvl] = id //unit
endfunction
struct BaseTroops extends array
integer level
LinkedList units
Base base
Team team
integer spawncount
private method CreateBasicTroops takes GuardPath p, real x, real y, boolean i returns nothing
local unit u
if team == 1 then
set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_HORDE,BASIC_MEELE_HORDE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_HORDE,BASIC_MEELE_HORDE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_HORDE,BASIC_MEELE_HORDE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
/*set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_HORDE,BASIC_MEELE_HORDE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif*/
set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_HORDE,BASIC_RANGED_HORDE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
else
set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_ALLIANCE,BASIC_MEELE_ALLIANCE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_ALLIANCE,BASIC_MEELE_ALLIANCE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_ALLIANCE,BASIC_MEELE_ALLIANCE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
/* set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_ALLIANCE,BASIC_MEELE_ALLIANCE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif*/
set u = GetRecycledUnit(Game.PLAYER_WARCHIEF_ALLIANCE,BASIC_RANGED_ALLIANCE,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
endif
set u = null
endmethod
private method CreateTroops takes GuardPath p returns nothing
local Link h = units.head
local real x = base.x
local real y = base.y
local GuardPoint gp
local unit u
local player ow
local integer cost
local boolean i = false
if team.bases == 0 then
set gp = p.list.head.data
set x = gp.x
set y = gp.y
set ow = team.captain
else
set ow = team.captain
endif
set i = team.commander.commanderAssault.baseTarget == base or base.callToArmsSpawn or team.bases == 0
call CreateBasicTroops(p,x,y,i)
set spawncount = spawncount + 1
if spawncount == 2 then
set spawncount = 0
endif
loop
exitwhen h == 0
if h.data == 'o004' or h.data == 'h00B' then
set u = GetRecycledUnit(ow,h.data,x,y,p.angle)
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
else
if spawncount == 0 then
set u = GetRecycledUnit(ow,h.data,x,y,p.angle)
if h.data == 'h00A' or h.data == 'h009' then
call Status.Add(STATUS_SPELL_IMMUNITY,u,0,0)
endif
call RemoveGuardPosition(u)
call SetUnitGuardPath(u,p)
call RunGuardPath(u)
if i then
call UnitAddBuff(u,u,9999,Inspire.buff,GameLoop.Minutes,0)
endif
endif
endif
set h = h.next
endloop
set ow = null
set u = null
endmethod
public method attack takes GuardPath p returns nothing
call CreateTroops(p)
endmethod
public method increaseLevel takes nothing returns boolean
if level < TROOPS_MAX_LEVEL then
set level = level + 1
call units.add(TroopData[team][level])
return true
endif
return false
endmethod
public method Create takes Team t returns nothing
set units = LinkedList.create()
set level = 1
set team = t
set spawncount = 0
endmethod
endstruct
public function Setup takes nothing returns nothing
call BaseTroops[1].Create(1)
call BaseTroops[2].Create(1)
call BaseTroops[3].Create(1)
call BaseTroops[4].Create(1)
call BaseTroops[5].Create(2)
call BaseTroops[6].Create(2)
call BaseTroops[7].Create(2)
call BaseTroops[8].Create(2)
set TroopData = HashTable.create()
//Horde
call AddTroopData('o004',2,1)
call AddTroopData('h00A',3,1)
call AddTroopData('o003',4,1)
call AddTroopData('o006',5,1)
//Alliance
call AddTroopData('h00B',2,2)
call AddTroopData('h009',3,2)
call AddTroopData('h003',4,2)
call AddTroopData('h00E',5,2)
endfunction
public function init takes nothing returns nothing
call PreloadGen.Add(BASIC_MEELE_HORDE,PRELOAD_UNIT)
call PreloadGen.Add(BASIC_MEELE_ALLIANCE,PRELOAD_UNIT)
call PreloadGen.Add(BASIC_RANGED_HORDE,PRELOAD_UNIT)
call PreloadGen.Add(BASIC_RANGED_ALLIANCE,PRELOAD_UNIT)
endfunction
endlibrary
library WarTroops uses UnitRecycler, GuardPath
globals
public constant real PERIODIC = 1.00
private integer TEMP
endglobals
function CreateDoubleTroops1 takes Team t returns nothing
local integer c = 2
local Base b = Base[1]
local Team t2 = 2/t
if Base[2].owner == t2 then
if GoldMine[2].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B1_TO_G2b)
else
set c = c - 1
call b.baseTroops.attack(B1_TO_B2)
endif
else
if GoldMine[2].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B1_TO_G2)
endif
endif
if Base[4].owner == t2 then
if GoldMine[1].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B1_TO_G1b)
else
set c = c - 1
call b.baseTroops.attack(B1_TO_B4)
endif
else
if GoldMine[1].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B1_TO_G1)
endif
endif
if Base[3].owner == t2 and c != 0 then
if GetRandomInt(1,2) == 1 then
call b.baseTroops.attack(B1_TO_B3b)
else
call b.baseTroops.attack(B1_TO_B3)
endif
endif
endfunction
function CreateDoubleTroops2 takes Team t returns nothing
local integer c = 2
local Base b = Base[2]
local Team t2 = 2/t
if Base[1].owner == t2 then
if GoldMine[2].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B2_TO_G2b)
else
set c = c - 1
call b.baseTroops.attack(B2_TO_B1)
endif
else
if GoldMine[2].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B2_TO_G2)
endif
endif
if Base[3].owner == t2 then
if GoldMine[3].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B2_TO_G3b)
else
set c = c - 1
call b.baseTroops.attack(B2_TO_B3)
endif
else
if GoldMine[3].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B2_TO_G3)
endif
endif
if Base[4].owner == t2 and c != 0 then
if GetRandomInt(1,2) == 1 then
call b.baseTroops.attack(B2_TO_B4)
else
call b.baseTroops.attack(B2_TO_B4b)
endif
endif
endfunction
function CreateDoubleTroops3 takes Team t returns nothing
local integer c = 2
local Base b = Base[3]
local Team t2 = 2/t
if Base[4].owner == t2 then
if GoldMine[4].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B3_TO_G4b)
else
set c = c - 1
call b.baseTroops.attack(B3_TO_B4)
endif
else
if GoldMine[4].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B3_TO_G4)
endif
endif
if Base[2].owner == t2 then
if GoldMine[3].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B3_TO_G3b)
else
set c = c - 1
call b.baseTroops.attack(B3_TO_B2)
endif
else
if GoldMine[3].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B3_TO_G3)
endif
endif
if Base[1].owner == t2 and c != 0 then
if GetRandomInt(1,2) == 1 then
call b.baseTroops.attack(B3_TO_B1b)
else
call b.baseTroops.attack(B3_TO_B1)
endif
endif
endfunction
function CreateDoubleTroops4 takes Team t returns nothing
local integer c = 2
local Base b = Base[4]
local Team t2 = 2/t
if Base[3].owner == t2 then
if GoldMine[4].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B4_TO_G4b)
else
set c = c - 1
call b.baseTroops.attack(B4_TO_B3)
endif
else
if GoldMine[4].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B4_TO_G4)
endif
endif
if Base[1].owner == t2 then
if GoldMine[1].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B4_TO_G1b)
else
set c = c - 1
call b.baseTroops.attack(B4_TO_B1)
endif
else
if GoldMine[1].owner == t2 then
set c = c - 1
call b.baseTroops.attack(B4_TO_G1)
endif
endif
if Base[2].owner == t2 and c != 0 then
if GetRandomInt(1,2) == 1 then
call b.baseTroops.attack(B4_TO_B2b)
else
call b.baseTroops.attack(B4_TO_B2)
endif
endif
endfunction
function CreateDefenseTroop takes Team t returns nothing
local GuardPath gp = 0
if t == 1 then
if Base[1].owner == 2 then
set gp = BH_TO_B1
elseif Base[2].owner == 2 then
set gp = BH_TO_B2
elseif Base[4].owner == 2 then
set gp = BH_TO_B4
elseif Base[3].owner == 2 then
set gp = BH_TO_B3
endif
if gp != 0 then
call BaseTroops[1].attack(gp)
endif
if GoldMine[1].owner == 2 then
set gp = BH_TO_G1
elseif GoldMine[2].owner == 2 then
set gp = BH_TO_G2
endif
if gp != 0 then
call BaseTroops[1].attack(gp)
endif
else
if Base[3].owner == 1 then
set gp = BA_TO_B3
elseif Base[4].owner == 1 then
set gp = BA_TO_B4
elseif Base[2].owner == 1 then
set gp = BA_TO_B2
elseif Base[1].owner == 1 then
set gp = BA_TO_B1
endif
if gp != 0 then
call BaseTroops[7].attack(gp)
endif
if GoldMine[3].owner == 1 then
set gp = BA_TO_G3
elseif GoldMine[4].owner == 1 then
set gp = BA_TO_G4
endif
if gp != 0 then
call BaseTroops[7].attack(gp)
endif
endif
endfunction
private function waveAttackTargetBase1 takes Team t1, Team t2 returns GuardPath
if Base[2].owner == t2 then
if GoldMine[2].owner == t2 then
if not Base[1].goldMineAttack then
set Base[1].goldMineAttack = true
return B1_TO_G2b
else
set Base[1].goldMineAttack = false
return B1_TO_B2
endif
else
set Base[1].goldMineAttack = false
return B1_TO_B2
endif
endif
if GoldMine[2].owner == t2 and Base[2].owner == 0 and GoldMine[1].owner == t1 then
if not Base[1].goldMineAttack then
set Base[1].goldMineAttack = true
return B1_TO_G2
endif
endif
if Base[4].owner == t2 then
if GoldMine[1].owner == t2 then
if not Base[1].goldMineAttack then
set Base[1].goldMineAttack = true
return B1_TO_G1b
else
set Base[1].goldMineAttack = false
return B1_TO_B4
endif
else
set Base[1].goldMineAttack = false
return B1_TO_B4
endif
else
if GoldMine[1].owner == t2 then
if not Base[1].goldMineAttack then
set Base[1].goldMineAttack = true
return B1_TO_G1
endif
endif
endif
if Base[3].owner == t2 then
set Base[1].goldMineAttack = false
if GetRandomInt(1,2) == 1 then
return B1_TO_B3
else
return B1_TO_B3b
endif
endif
if Base[1].owner == 1 then
set Base[1].goldMineAttack = false
return B1_TO_BA
elseif Base[1].owner == 2 then
set Base[1].goldMineAttack = false
return B1_TO_BH
endif
return 0
endfunction
private function waveAttackTargetBase2 takes Team t1, Team t2 returns GuardPath
if Base[1].owner == t2 then
if GoldMine[2].owner == t2 then
if not Base[2].goldMineAttack then
set Base[2].goldMineAttack = true
return B2_TO_G2b
else
set Base[2].goldMineAttack = false
return B2_TO_B1
endif
else
set Base[2].goldMineAttack = false
return B2_TO_B1
endif
endif
if GoldMine[2].owner == t2 then
if not Base[2].goldMineAttack then
set Base[2].goldMineAttack = true
return B2_TO_G2
endif
endif
if Base[3].owner == t2 then
if GoldMine[3].owner == t2 then
if not Base[2].goldMineAttack then
set Base[2].goldMineAttack = true
return B2_TO_G3b
else
set Base[2].goldMineAttack = false
return B2_TO_B3
endif
else
set Base[2].goldMineAttack = false
return B2_TO_B3
endif
else
if GoldMine[3].owner == t2 then
if not Base[2].goldMineAttack then
set Base[2].goldMineAttack = true
return B2_TO_G3
endif
endif
endif
if Base[4].owner == t2 then
set Base[2].goldMineAttack = true
if GetRandomInt(1,2) == 1 then
return B2_TO_B4
else
return B2_TO_B4b
endif
endif
if Base[2].owner == 1 then
set Base[2].goldMineAttack = true
return B2_TO_BA
elseif Base[2].owner == 2 then
set Base[2].goldMineAttack = true
return B2_TO_BH
endif
return 0
endfunction
private function waveAttackTargetBase3 takes Team t1, Team t2 returns GuardPath
if Base[4].owner == t2 then
if GoldMine[4].owner == t2 then
if not Base[3].goldMineAttack then
set Base[3].goldMineAttack = true
return B3_TO_G4b
else
set Base[3].goldMineAttack = false
return B3_TO_B4
endif
else
set Base[3].goldMineAttack = false
return B3_TO_B4
endif
endif
if GoldMine[4].owner == t2 and Base[4].owner == 0 and GoldMine[3].owner == t1 then
if not Base[3].goldMineAttack then
set Base[3].goldMineAttack = true
return B3_TO_G4
endif
endif
if Base[2].owner == t2 then
if GoldMine[3].owner == t2 then
if not Base[3].goldMineAttack then
set Base[3].goldMineAttack = true
return B3_TO_G3b
else
set Base[3].goldMineAttack = false
return B3_TO_B2
endif
else
set Base[3].goldMineAttack = false
return B3_TO_B2
endif
else
if GoldMine[3].owner == t2 then
if not Base[3].goldMineAttack then
set Base[3].goldMineAttack = true
return B3_TO_G3
endif
endif
endif
if Base[1].owner == t2 then
set Base[3].goldMineAttack = true
if GetRandomInt(1,2) == 1 then
return B3_TO_B1
else
return B3_TO_B1b
endif
endif
if Base[3].owner == 1 then
set Base[3].goldMineAttack = true
return B3_TO_BA
elseif Base[3].owner == 2 then
set Base[3].goldMineAttack = true
return B3_TO_BH
endif
return 0
endfunction
private function waveAttackTargetBase4 takes Team t1, Team t2 returns GuardPath
if Base[3].owner == t2 then
if GoldMine[4].owner == t2 then
if not Base[4].goldMineAttack then
set Base[4].goldMineAttack = true
return B4_TO_G4b
else
set Base[4].goldMineAttack = false
return B4_TO_B3
endif
else
set Base[4].goldMineAttack = false
return B4_TO_B3
endif
else
if GoldMine[4].owner == t2 then
if not Base[4].goldMineAttack then
set Base[4].goldMineAttack = true
return B4_TO_G4
endif
endif
endif
if Base[1].owner == t2 then
if GoldMine[1].owner == t2 then
if not Base[4].goldMineAttack then
set Base[4].goldMineAttack = true
return B4_TO_G1b
else
set Base[4].goldMineAttack = false
return B4_TO_B1
endif
else
set Base[4].goldMineAttack = false
return B4_TO_B1
endif
else
if GoldMine[1].owner == t2 then
if not Base[4].goldMineAttack then
set Base[4].goldMineAttack = true
return B4_TO_G1
endif
endif
endif
if Base[2].owner == t2 then
set Base[4].goldMineAttack = true
if GetRandomInt(1,2) == 1 then
return B4_TO_B2
else
return B4_TO_B2b
endif
endif
if Base[4].owner == 1 then
set Base[4].goldMineAttack = true
return B4_TO_BA
elseif Base[4].owner == 2 then
set Base[4].goldMineAttack = true
return B4_TO_BH
endif
return 0
endfunction
function CreateWaves takes Team t returns nothing
local Base b = 0
local Team t2 = 2/t
local GuardPath gp = 0
local integer i = 0
local integer c = 0
if t.bases == 0 then
call CreateDefenseTroop(t)
return
endif
loop
set i = i + 1
set b = Base[i]
set gp = 0
if b.owner != 0 then
if i == 1 and b.owner == t then
if t.bases == 1 then
call CreateDoubleTroops1(t)
else
set gp = waveAttackTargetBase1(t,t2)
endif
endif
if i == 2 and b.owner == t then
if t.bases == 1 then
call CreateDoubleTroops2(t)
else
set gp = waveAttackTargetBase2(t,t2)
endif
endif
if i == 3 and b.owner == t then
if t.bases == 1 then
call CreateDoubleTroops3(t)
else
set gp = waveAttackTargetBase3(t,t2)
endif
endif
if i == 4 and b.owner == t then
if t.bases == 1 then
call CreateDoubleTroops4(t)
else
set gp = waveAttackTargetBase4(t,t2)
endif
endif
endif
if gp != 0 then
call b.baseTroops.attack(gp)
endif
exitwhen i == 4
endloop
endfunction
public function UpdateTeamSpawnTime takes Team t returns nothing
local integer ct = t.currentTime
local Team et = 2/t
local integer wt
local integer r
if not Game.CreepsSpawned then
return
endif
if t.bases == 0 or t.bases == 1 then
set t.currentTime = 20
elseif t.bases == 2 then
set t.currentTime = 30
elseif t.bases == 3 then
set t.currentTime = 60
elseif t.bases == 4 then
set t.currentTime = 90
endif
set r = ct - t.currentTime
set wt = IAbsBJ(t.waveTime - r)
if wt <= 0 then
set wt = t.currentTime
endif
set t.waveTime = wt
endfunction
private function Periodic takes nothing returns nothing
if Game.GameOver then
return
endif
set Team[1].waveTime = Team[1].waveTime - 1
if Team[1].waveTime <= 0 then
call UpdateTeamSpawnTime(Team[1])
call CreateWaves(Team[1])
endif
set Team[2].waveTime = Team[2].waveTime - 1
if Team[2].waveTime <= 0 then
call UpdateTeamSpawnTime(Team[2])
call CreateWaves(Team[2])
endif
call Base.UpdateSpawnText()
endfunction
public function CallToArmsActions takes Base b, Team t returns nothing
local Team t2 = 2/t
local GuardPath gp = 0
set b.callToArmsSpawn = true
if b.owner != 0 then
if b == 1 then
if t.bases < t2.bases then
call CreateDoubleTroops1(t)
else
set gp = waveAttackTargetBase1(t,t2)
endif
endif
if b == 2 then
if t.bases < t2.bases then
call CreateDoubleTroops2(t)
else
set gp = waveAttackTargetBase2(t,t2)
endif
endif
if b == 3 then
if t.bases < t2.bases then
call CreateDoubleTroops3(t)
else
set gp = waveAttackTargetBase3(t,t2)
endif
endif
if b == 4 then
if t.bases < t2.bases then
call CreateDoubleTroops4(t)
else
set gp = waveAttackTargetBase4(t,t2)
endif
endif
endif
if gp != 0 then
call b.baseTroops.attack(gp)
endif
set b.callToArmsSpawn = false
endfunction
private function IsBaseEnemy takes Base b, Base b2 returns boolean
if b2.owner != 0 then
if b2.owner != b.owner then
return true
endif
endif
return false
endfunction
public function Start takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterTimerEvent(t,PERIODIC,true)
call TriggerAddCondition(t,function Periodic)
set t = null
endfunction
public function Setup takes nothing returns nothing
//set Team[1].waveTime = 30
//set Team[2].waveTime = 30
endfunction
endlibrary
library GuardPath initializer Init uses InCombat, LinkedList, UnitRecycler
globals
GuardPath BH_TO_BAa
GuardPath BH_TO_BAb
GuardPath BH_TO_G1
GuardPath BH_TO_G2
GuardPath BA_TO_BHa
GuardPath BA_TO_BHb
GuardPath BA_TO_G3
GuardPath BA_TO_G4
//BASES
GuardPath BH_TO_B1
GuardPath BH_TO_B2
GuardPath BH_TO_B3
GuardPath BH_TO_B4
GuardPath BA_TO_B1
GuardPath BA_TO_B2
GuardPath BA_TO_B3
GuardPath BA_TO_B4
//Base 1 Paths
GuardPath B1_TO_B2
GuardPath B1_TO_B3
GuardPath B1_TO_B3b
GuardPath B1_TO_B4
GuardPath B1_TO_G1
GuardPath B1_TO_G1b
GuardPath B1_TO_G2
GuardPath B1_TO_G2b
GuardPath B1_TO_BH
GuardPath B1_TO_BA
GuardPath B1_TO_BAb
//Base 2 Paths
GuardPath B2_TO_B1
GuardPath B2_TO_B3
GuardPath B2_TO_B4
GuardPath B2_TO_B4b
GuardPath B2_TO_G2
GuardPath B2_TO_G2b
GuardPath B2_TO_G3
GuardPath B2_TO_G3b
GuardPath B2_TO_BH
GuardPath B2_TO_BA
//Base 3 Paths
GuardPath B3_TO_B1
GuardPath B3_TO_B1b
GuardPath B3_TO_B2
GuardPath B3_TO_B4
GuardPath B3_TO_G3
GuardPath B3_TO_G3b
GuardPath B3_TO_G4
GuardPath B3_TO_G4b
GuardPath B3_TO_BH
GuardPath B3_TO_BHb
GuardPath B3_TO_BA
//Base 4 Paths
GuardPath B4_TO_B1
GuardPath B4_TO_B2
GuardPath B4_TO_B2b
GuardPath B4_TO_B3
GuardPath B4_TO_G4
GuardPath B4_TO_G4b
GuardPath B4_TO_G1
GuardPath B4_TO_G1b
GuardPath B4_TO_BH
GuardPath B4_TO_BA
LinkedList UnitsPath
endglobals
struct UnitGuardPath extends array
GuardPath path
Link current
GuardPoint currentPoint
boolean ended
integer listIndex
public method resetVars takes nothing returns nothing
set path = 0
set current = 0
set currentPoint = 0
if listIndex != 0 then
call UnitsPath.remove(listIndex)
endif
set listIndex = 0
set ended = false
endmethod
public method Finished takes nothing returns boolean
local GuardPoint g = path.list.last.data
if ended and IsUnitInRegion(g.R,Index[this].u) then
return true
endif
return false
endmethod
public method moveToNextPoint takes boolean next returns nothing
local unit u = Index[this].u
local integer id = GetUnitTypeId(u)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local Hero h
if not ended then
if not next and current != 0 then
if Distance(x,y,currentPoint.x,currentPoint.y) <= 70 then
set next = true
endif
endif
if next then
if current == 0 then
set current = path.list.head.next
set currentPoint = current.data
else
set current = current.next
set currentPoint = current.data
endif
endif
if current != 0 then
//call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl",currentPoint.x,currentPoint.y))
call IssuePointOrder(u,"attack",currentPoint.x,currentPoint.y)
else
set ended = true
set current = path.list.last
set currentPoint = current.data
call IssuePointOrder(u,"attack",currentPoint.x,currentPoint.y)
call EnterUnitCombat(u,null,0)
endif
else
call IssuePointOrder(u,"attack",currentPoint.x,currentPoint.y)
call EnterUnitCombat(u,null,0)
endif
set u = null
endmethod
public method returnToPath takes nothing returns nothing
call moveToNextPoint(false)
endmethod
public method run takes nothing returns nothing
call moveToNextPoint(true)
endmethod
endstruct
function RestartUnitsPath takes nothing returns nothing
local Link node = UnitsPath.head
local unit u
local UnitGuardPath gp
loop
exitwhen node == 0
set u = Index[node.data].u
set gp = UnitGuardPath[node.data]
if gp.path != 0 then
if GetUnitCurrentOrder(u) != ORDER_massteleport and not IsUnitInCombat(u) then
call gp.returnToPath()
endif
endif
set node = node.next
endloop
set u = null
endfunction
struct GuardPoint
real x
real y
region R
public static method create takes real x, real y, region r returns thistype
local thistype this = thistype.allocate()
set this.x = x
set this.y = y
set this.R = r
return this
endmethod
endstruct
struct GuardPath
LinkedList list
real angle
static Table regions
private static trigger trig
private static method EnterRegion takes nothing returns nothing
local unit u = GetEnteringUnit()
local UnitGuardPath gu = UnitGuardPath[GetUnitUserData(u)]
local GuardPoint p
local Link next
if gu.path != 0 and gu.currentPoint != 0 and not gu.ended then
if gu.currentPoint.R == GetTriggeringRegion() then
call gu.moveToNextPoint(true)
endif
endif
set u = null
endmethod
public method AddRegion takes rect r returns nothing
local region reg
if regions.region[GetHandleId(r)] == null then
set reg = CreateRegion()
call RegionAddRect(reg,r)
call TriggerRegisterEnterRegion(trig,reg,null)
set regions.region[GetHandleId(r)] = reg
call list.addLast(GuardPoint.create(GetRectCenterX(r),GetRectCenterY(r),reg))
else
set reg = regions.region[GetHandleId(r)]
call list.addLast(GuardPoint.create(GetRectCenterX(r),GetRectCenterY(r),reg))
endif
set reg = null
endmethod
public static method create takes real a returns thistype
local thistype this = thistype.allocate()
set list = LinkedList.create()
set angle = a
return this
endmethod
public static method Ini takes nothing returns nothing
set trig = CreateTrigger()
set regions = Table.create()
call TriggerAddCondition(trig,Filter(function thistype.EnterRegion))
endmethod
endstruct
function GetUnitGuardPath takes unit u returns GuardPath
return UnitGuardPath[GetUnitUserData(u)].path
endfunction
function SetUnitGuardPath takes unit u, GuardPath g returns nothing
if g == 0 then
call UnitGuardPath[GetUnitUserData(u)].resetVars()
else
set UnitGuardPath[GetUnitUserData(u)].path = g
set UnitGuardPath[GetUnitUserData(u)].listIndex = UnitsPath.add(GetUnitUserData(u))
endif
endfunction
function RunGuardPath takes unit u returns nothing
if UnitGuardPath[GetUnitUserData(u)].path != 0 then
call UnitGuardPath[GetUnitUserData(u)].run()
endif
endfunction
private function ReturnToPath takes nothing returns nothing
local unit u = GetEventCombatLeaveUnit()
local Team t
local Hero h
local integer id = GetUnitTypeId(u)
if UnitGuardPath[GetUnitUserData(u)].path != 0 then
if GetEventCombatLeaveID() != -1 then
if UnitGuardPath[GetUnitUserData(u)].Finished() then
if GetUnitCurrentOrder(u) != ORDER_attack then
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",GetUnitX(u),GetUnitY(u)))
call UnitGuardPath[GetUnitUserData(u)].resetVars()
call RecycleUnit(u)
endif
else
call UnitGuardPath[GetUnitUserData(u)].returnToPath()
endif
else
call UnitGuardPath[GetUnitUserData(u)].resetVars()
endif
endif
set u = null
endfunction
private function SetupBHA takes nothing returns nothing
set BH_TO_B1 = GuardPath.create(45)
call BH_TO_B1.AddRegion(gg_rct_BHtoB1a)
call BH_TO_B1.AddRegion(gg_rct_BHtoB1b)
call BH_TO_B1.AddRegion(gg_rct_BHtoB1c)
call BH_TO_B1.AddRegion(gg_rct_Base1)
set BH_TO_G1 = GuardPath.create(45)
call BH_TO_G1.AddRegion(gg_rct_BHtoB1a)
call BH_TO_G1.AddRegion(gg_rct_BHtoB1b)
call BH_TO_G1.AddRegion(gg_rct_B1toG1a)
call BH_TO_G1.AddRegion(gg_rct_B1toG1b)
call BH_TO_G1.AddRegion(gg_rct_B1toG1c)
call BH_TO_G1.AddRegion(gg_rct_GoldMine1)
set BH_TO_G2 = GuardPath.create(45)
call BH_TO_G2.AddRegion(gg_rct_BHtoB1a)
call BH_TO_G2.AddRegion(gg_rct_BHtoB1b)
call BH_TO_G2.AddRegion(gg_rct_B1toG2c)
call BH_TO_G2.AddRegion(gg_rct_GoldMine2)
set BH_TO_B2 = GuardPath.create(45)
call BH_TO_B2.AddRegion(gg_rct_BHtoB1a)
call BH_TO_B2.AddRegion(gg_rct_BHtoB1b)
call BH_TO_B2.AddRegion(gg_rct_BHtoB1c)
call BH_TO_B2.AddRegion(gg_rct_Base1)
call BH_TO_B2.AddRegion(gg_rct_B1toB2a)
call BH_TO_B2.AddRegion(gg_rct_B1toB2b)
call BH_TO_B2.AddRegion(gg_rct_B1toB2c)
call BH_TO_B2.AddRegion(gg_rct_B1toB2d)
call BH_TO_B2.AddRegion(gg_rct_Base2)
set BH_TO_B3 = GuardPath.create(45)
call BH_TO_B3.AddRegion(gg_rct_BHtoB1a)
call BH_TO_B3.AddRegion(gg_rct_BHtoB1b)
call BH_TO_B3.AddRegion(gg_rct_BHtoB1c)
call BH_TO_B3.AddRegion(gg_rct_B1toB4a)
call BH_TO_B3.AddRegion(gg_rct_B1toB4b)
call BH_TO_B3.AddRegion(gg_rct_B1toB4c)
call BH_TO_B3.AddRegion(gg_rct_BAtoBHb)
call BH_TO_B3.AddRegion(gg_rct_BAtoBHa)
call BH_TO_B3.AddRegion(gg_rct_B3toB4d)
call BH_TO_B3.AddRegion(gg_rct_B3toB4c)
call BH_TO_B3.AddRegion(gg_rct_B3toB4b)
call BH_TO_B3.AddRegion(gg_rct_B3toB4a)
call BH_TO_B3.AddRegion(gg_rct_Base3)
set BH_TO_B4 = GuardPath.create(45)
call BH_TO_B4.AddRegion(gg_rct_BHtoB1a)
call BH_TO_B4.AddRegion(gg_rct_BHtoB1b)
call BH_TO_B4.AddRegion(gg_rct_BHtoB1c)
call BH_TO_B4.AddRegion(gg_rct_B1toB4a)
call BH_TO_B4.AddRegion(gg_rct_B1toB4b)
call BH_TO_B4.AddRegion(gg_rct_B1toB4c)
call BH_TO_B4.AddRegion(gg_rct_B1toB4d)
call BH_TO_B4.AddRegion(gg_rct_B1toB4e)
call BH_TO_B4.AddRegion(gg_rct_Base4)
set BA_TO_B1 = GuardPath.create(225)
call BA_TO_B1.AddRegion(gg_rct_BAtoB3a)
call BA_TO_B1.AddRegion(gg_rct_BAtoB3b)
call BA_TO_B1.AddRegion(gg_rct_BAtoB3c)
call BA_TO_B1.AddRegion(gg_rct_Base3)
call BA_TO_B1.AddRegion(gg_rct_B3toB2a)
call BA_TO_B1.AddRegion(gg_rct_B3toB2b)
call BA_TO_B1.AddRegion(gg_rct_B3toB2c)
call BA_TO_B1.AddRegion(gg_rct_BHtoBAb)
call BA_TO_B1.AddRegion(gg_rct_BHtoBAa)
call BA_TO_B1.AddRegion(gg_rct_B1toB2c)
call BA_TO_B1.AddRegion(gg_rct_B1toB2b)
call BA_TO_B1.AddRegion(gg_rct_B1toB2a)
call BA_TO_B1.AddRegion(gg_rct_Base1)
set BA_TO_B2 = GuardPath.create(225)
call BA_TO_B2.AddRegion(gg_rct_BAtoB3a)
call BA_TO_B2.AddRegion(gg_rct_BAtoB3b)
call BA_TO_B2.AddRegion(gg_rct_BAtoB3c)
call BA_TO_B2.AddRegion(gg_rct_Base3)
call BA_TO_B2.AddRegion(gg_rct_B3toB2a)
call BA_TO_B2.AddRegion(gg_rct_B3toB2b)
call BA_TO_B2.AddRegion(gg_rct_B3toB2c)
call BA_TO_B2.AddRegion(gg_rct_B3toB2d)
call BA_TO_B2.AddRegion(gg_rct_B3toB2e)
call BA_TO_B2.AddRegion(gg_rct_Base2)
set BA_TO_B3 = GuardPath.create(225)
call BA_TO_B3.AddRegion(gg_rct_BAtoB3a)
call BA_TO_B3.AddRegion(gg_rct_BAtoB3b)
call BA_TO_B3.AddRegion(gg_rct_BAtoB3c)
call BA_TO_B3.AddRegion(gg_rct_Base3)
set BA_TO_G3 = GuardPath.create(225)
call BA_TO_G3.AddRegion(gg_rct_BAtoB3a)
call BA_TO_G3.AddRegion(gg_rct_BAtoB3b)
call BA_TO_G3.AddRegion(gg_rct_B3toG3b)
call BA_TO_G3.AddRegion(gg_rct_B3toG3c)
call BA_TO_G3.AddRegion(gg_rct_GoldMine3)
set BA_TO_G4 = GuardPath.create(225)
call BA_TO_G4.AddRegion(gg_rct_BAtoB3a)
call BA_TO_G4.AddRegion(gg_rct_B3toG4b)
call BA_TO_G4.AddRegion(gg_rct_B3toG4c)
call BA_TO_G4.AddRegion(gg_rct_GoldMine4)
set BA_TO_B4 = GuardPath.create(225)
call BA_TO_B4.AddRegion(gg_rct_BAtoB3a)
call BA_TO_B4.AddRegion(gg_rct_BAtoB3b)
call BA_TO_B4.AddRegion(gg_rct_BAtoB3c)
call BA_TO_B4.AddRegion(gg_rct_Base3)
call BA_TO_B4.AddRegion(gg_rct_B3toB4a)
call BA_TO_B4.AddRegion(gg_rct_B3toB4b)
call BA_TO_B4.AddRegion(gg_rct_B3toB4c)
call BA_TO_B4.AddRegion(gg_rct_B3toB4d)
call BA_TO_B4.AddRegion(gg_rct_Base4)
set BH_TO_BAa = GuardPath.create(0)
call BH_TO_BAa.AddRegion(gg_rct_BHtoB1a)
call BH_TO_BAa.AddRegion(gg_rct_BHtoB1b)
call BH_TO_BAa.AddRegion(gg_rct_BHtoB1c)
call BH_TO_BAa.AddRegion(gg_rct_B1toB2a)
call BH_TO_BAa.AddRegion(gg_rct_B1toB2b)
call BH_TO_BAa.AddRegion(gg_rct_B1toB2c)
call BH_TO_BAa.AddRegion(gg_rct_BHtoBAa)
call BH_TO_BAa.AddRegion(gg_rct_BHtoBAb)
call BH_TO_BAa.AddRegion(gg_rct_B3toB2c)
call BH_TO_BAa.AddRegion(gg_rct_B3toB2b)
call BH_TO_BAa.AddRegion(gg_rct_B3toB2a)
call BH_TO_BAa.AddRegion(gg_rct_Base3)
call BH_TO_BAa.AddRegion(gg_rct_BAtoB3c)
call BH_TO_BAa.AddRegion(gg_rct_BAtoB3b)
call BH_TO_BAa.AddRegion(gg_rct_BAtoB3a)
call BH_TO_BAa.AddRegion(gg_rct_AllianceWarchiefBase)
set BH_TO_BAb = GuardPath.create(0)
call BH_TO_BAb.AddRegion(gg_rct_BHtoB1a)
call BH_TO_BAb.AddRegion(gg_rct_BHtoB1b)
call BH_TO_BAb.AddRegion(gg_rct_BHtoB1c)
call BH_TO_BAb.AddRegion(gg_rct_B1toB4a)
call BH_TO_BAb.AddRegion(gg_rct_B1toB4b)
call BH_TO_BAb.AddRegion(gg_rct_B1toB4c)
call BH_TO_BAb.AddRegion(gg_rct_BAtoBHb)
call BH_TO_BAb.AddRegion(gg_rct_BAtoBHa)
call BH_TO_BAb.AddRegion(gg_rct_B3toB4d)
call BH_TO_BAb.AddRegion(gg_rct_B3toB4c)
call BH_TO_BAb.AddRegion(gg_rct_B3toB4b)
call BH_TO_BAb.AddRegion(gg_rct_B3toB4a)
call BH_TO_BAb.AddRegion(gg_rct_Base3)
call BH_TO_BAb.AddRegion(gg_rct_BAtoB3c)
call BH_TO_BAb.AddRegion(gg_rct_BAtoB3b)
call BH_TO_BAb.AddRegion(gg_rct_BAtoB3a)
call BH_TO_BAb.AddRegion(gg_rct_AllianceWarchiefBase)
set BA_TO_BHa = GuardPath.create(0)
call BA_TO_BHa.AddRegion(gg_rct_BAtoB3a)
call BA_TO_BHa.AddRegion(gg_rct_BAtoB3b)
call BA_TO_BHa.AddRegion(gg_rct_BAtoB3c)
call BA_TO_BHa.AddRegion(gg_rct_Base3)
call BA_TO_BHa.AddRegion(gg_rct_B3toB2a)
call BA_TO_BHa.AddRegion(gg_rct_B3toB2b)
call BA_TO_BHa.AddRegion(gg_rct_B3toB2c)
call BA_TO_BHa.AddRegion(gg_rct_BHtoBAb)
call BA_TO_BHa.AddRegion(gg_rct_BHtoBAa)
call BA_TO_BHa.AddRegion(gg_rct_B1toB2c)
call BA_TO_BHa.AddRegion(gg_rct_B1toB2b)
call BA_TO_BHa.AddRegion(gg_rct_B1toB2a)
call BA_TO_BHa.AddRegion(gg_rct_Base1)
call BA_TO_BHa.AddRegion(gg_rct_BHtoB1c)
call BA_TO_BHa.AddRegion(gg_rct_BHtoB1b)
call BA_TO_BHa.AddRegion(gg_rct_BHtoB1a)
call BA_TO_BHa.AddRegion(gg_rct_HordeWarchiefBase)
set BA_TO_BHb = GuardPath.create(0)
call BA_TO_BHb.AddRegion(gg_rct_BAtoB3a)
call BA_TO_BHb.AddRegion(gg_rct_BAtoB3b)
call BA_TO_BHb.AddRegion(gg_rct_BAtoB3c)
call BA_TO_BHb.AddRegion(gg_rct_B3toB4a)
call BA_TO_BHb.AddRegion(gg_rct_B3toB4b)
call BA_TO_BHb.AddRegion(gg_rct_B3toB4c)
call BA_TO_BHb.AddRegion(gg_rct_B3toB4d)
call BA_TO_BHb.AddRegion(gg_rct_BAtoBHa)
call BA_TO_BHb.AddRegion(gg_rct_BAtoBHb)
call BA_TO_BHb.AddRegion(gg_rct_B1toB4c)
call BA_TO_BHb.AddRegion(gg_rct_B1toB4b)
call BA_TO_BHb.AddRegion(gg_rct_B1toB4a)
call BA_TO_BHb.AddRegion(gg_rct_BHtoB1c)
call BA_TO_BHb.AddRegion(gg_rct_BHtoB1b)
call BA_TO_BHb.AddRegion(gg_rct_BHtoB1a)
call BA_TO_BHb.AddRegion(gg_rct_HordeWarchiefBase)
endfunction
private function SetupB4 takes nothing returns nothing
set B4_TO_B1 = GuardPath.create(180)
call B4_TO_B1.AddRegion(gg_rct_Base4)
call B4_TO_B1.AddRegion(gg_rct_B1toB4e)
call B4_TO_B1.AddRegion(gg_rct_B1toB4d)
call B4_TO_B1.AddRegion(gg_rct_B1toB4c)
call B4_TO_B1.AddRegion(gg_rct_B1toB4b)
call B4_TO_B1.AddRegion(gg_rct_B1toB4a)
call B4_TO_B1.AddRegion(gg_rct_Base1)
set B4_TO_B2 = GuardPath.create(180)
call B4_TO_B2.AddRegion(gg_rct_Base4)
call B4_TO_B2.AddRegion(gg_rct_B3toB4d)
call B4_TO_B2.AddRegion(gg_rct_B3toB4c)
call B4_TO_B2.AddRegion(gg_rct_B3toB4b)
call B4_TO_B2.AddRegion(gg_rct_B3toB4a)
call B4_TO_B2.AddRegion(gg_rct_Base3)
call B4_TO_B2.AddRegion(gg_rct_B3toB2a)
call B4_TO_B2.AddRegion(gg_rct_B3toB2b)
call B4_TO_B2.AddRegion(gg_rct_B3toB2c)
call B4_TO_B2.AddRegion(gg_rct_B3toB2d)
call B4_TO_B2.AddRegion(gg_rct_B3toB2e)
call B4_TO_B2.AddRegion(gg_rct_Base2)
set B4_TO_B2b = GuardPath.create(180)
call B4_TO_B2b.AddRegion(gg_rct_Base4)
call B4_TO_B2b.AddRegion(gg_rct_B1toB4e)
call B4_TO_B2b.AddRegion(gg_rct_B1toB4d)
call B4_TO_B2b.AddRegion(gg_rct_B1toB4c)
call B4_TO_B2b.AddRegion(gg_rct_B1toB4b)
call B4_TO_B2b.AddRegion(gg_rct_B1toB4a)
call B4_TO_B2b.AddRegion(gg_rct_Base1)
call B4_TO_B2b.AddRegion(gg_rct_B1toB2a)
call B4_TO_B2b.AddRegion(gg_rct_B1toB2b)
call B4_TO_B2b.AddRegion(gg_rct_B1toB2c)
call B4_TO_B2b.AddRegion(gg_rct_B1toB2d)
call B4_TO_B2b.AddRegion(gg_rct_Base2)
set B4_TO_B3 = GuardPath.create(90)
call B4_TO_B3.AddRegion(gg_rct_Base4)
call B4_TO_B3.AddRegion(gg_rct_B3toB4d)
call B4_TO_B3.AddRegion(gg_rct_B3toB4c)
call B4_TO_B3.AddRegion(gg_rct_B3toB4b)
call B4_TO_B3.AddRegion(gg_rct_B3toB4a)
call B4_TO_B3.AddRegion(gg_rct_Base3)
set B4_TO_G4 = GuardPath.create(90)
call B4_TO_G4.AddRegion(gg_rct_Base4)
call B4_TO_G4.AddRegion(gg_rct_B4toG4a)
call B4_TO_G4.AddRegion(gg_rct_B4toG4b)
call B4_TO_G4.AddRegion(gg_rct_B4toG4c)
call B4_TO_G4.AddRegion(gg_rct_GoldMine4)
set B4_TO_G4b = GuardPath.create(90)
call B4_TO_G4b.AddRegion(gg_rct_Base4)
call B4_TO_G4b.AddRegion(gg_rct_B4toG4a)
call B4_TO_G4b.AddRegion(gg_rct_B4toG4b)
call B4_TO_G4b.AddRegion(gg_rct_B4toG4c)
call B4_TO_G4b.AddRegion(gg_rct_B3toG4c)
call B4_TO_G4b.AddRegion(gg_rct_B3toG4b)
call B4_TO_G4b.AddRegion(gg_rct_B3toG4a)
call B4_TO_G4b.AddRegion(gg_rct_Base3)
set B4_TO_G1 = GuardPath.create(90)
call B4_TO_G1.AddRegion(gg_rct_Base4)
call B4_TO_G1.AddRegion(gg_rct_B4toG1a)
call B4_TO_G1.AddRegion(gg_rct_B4toG1b)
call B4_TO_G1.AddRegion(gg_rct_GoldMine1)
set B4_TO_G1b = GuardPath.create(90)
call B4_TO_G1b.AddRegion(gg_rct_Base4)
call B4_TO_G1b.AddRegion(gg_rct_B4toG1a)
call B4_TO_G1b.AddRegion(gg_rct_B4toG1b)
call B4_TO_G1b.AddRegion(gg_rct_B1toG1c)
call B4_TO_G1b.AddRegion(gg_rct_B1toG1b)
call B4_TO_G1b.AddRegion(gg_rct_B1toG1a)
call B4_TO_G1b.AddRegion(gg_rct_Base1)
set B4_TO_BH = GuardPath.create(180)
call B4_TO_BH.AddRegion(gg_rct_Base4)
call B4_TO_BH.AddRegion(gg_rct_B1toB4e)
call B4_TO_BH.AddRegion(gg_rct_B1toB4d)
call B4_TO_BH.AddRegion(gg_rct_B1toB4c)
call B4_TO_BH.AddRegion(gg_rct_B1toB4b)
call B4_TO_BH.AddRegion(gg_rct_B1toB4a)
call B4_TO_BH.AddRegion(gg_rct_BHtoB1c)
call B4_TO_BH.AddRegion(gg_rct_BHtoB1b)
call B4_TO_BH.AddRegion(gg_rct_BHtoB1a)
call B4_TO_BH.AddRegion(gg_rct_HordeWarchiefBase)
set B4_TO_BA = GuardPath.create(90)
call B4_TO_BA.AddRegion(gg_rct_Base4)
call B4_TO_BA.AddRegion(gg_rct_B3toB4d)
call B4_TO_BA.AddRegion(gg_rct_B3toB4c)
call B4_TO_BA.AddRegion(gg_rct_B3toB4b)
call B4_TO_BA.AddRegion(gg_rct_B3toB4a)
call B4_TO_BA.AddRegion(gg_rct_Base3)
call B4_TO_BA.AddRegion(gg_rct_BAtoB3c)
call B4_TO_BA.AddRegion(gg_rct_BAtoB3b)
call B4_TO_BA.AddRegion(gg_rct_BAtoB3a)
call B4_TO_BA.AddRegion(gg_rct_AllianceWarchiefBase)
endfunction
private function SetupB3 takes nothing returns nothing
set B3_TO_B1 = GuardPath.create(270)
call B3_TO_B1.AddRegion(gg_rct_Base3)
call B3_TO_B1.AddRegion(gg_rct_B3toB4a)
call B3_TO_B1.AddRegion(gg_rct_B3toB4b)
call B3_TO_B1.AddRegion(gg_rct_B3toB4c)
call B3_TO_B1.AddRegion(gg_rct_B3toB4d)
call B3_TO_B1.AddRegion(gg_rct_BAtoBHa)
call B3_TO_B1.AddRegion(gg_rct_BAtoBHb)
call B3_TO_B1.AddRegion(gg_rct_B1toB4c)
call B3_TO_B1.AddRegion(gg_rct_B1toB4b)
call B3_TO_B1.AddRegion(gg_rct_B1toB4a)
call B3_TO_B1.AddRegion(gg_rct_Base1)
set B3_TO_B1b = GuardPath.create(180)
call B3_TO_B1b.AddRegion(gg_rct_Base3)
call B3_TO_B1b.AddRegion(gg_rct_B3toB2a)
call B3_TO_B1b.AddRegion(gg_rct_B3toB2b)
call B3_TO_B1b.AddRegion(gg_rct_B3toB2c)
call B3_TO_B1b.AddRegion(gg_rct_BHtoBAb)
call B3_TO_B1b.AddRegion(gg_rct_BHtoBAa)
call B3_TO_B1b.AddRegion(gg_rct_B1toB2c)
call B3_TO_B1b.AddRegion(gg_rct_B1toB2b)
call B3_TO_B1b.AddRegion(gg_rct_B1toB2a)
call B3_TO_B1b.AddRegion(gg_rct_Base1)
set B3_TO_B2 = GuardPath.create(180)
call B3_TO_B2.AddRegion(gg_rct_Base3)
call B3_TO_B2.AddRegion(gg_rct_B3toB2a)
call B3_TO_B2.AddRegion(gg_rct_B3toB2b)
call B3_TO_B2.AddRegion(gg_rct_B3toB2c)
call B3_TO_B2.AddRegion(gg_rct_B3toB2d)
call B3_TO_B2.AddRegion(gg_rct_B3toB2e)
call B3_TO_B2.AddRegion(gg_rct_Base2)
set B3_TO_B4 = GuardPath.create(270)
call B3_TO_B4.AddRegion(gg_rct_Base3)
call B3_TO_B4.AddRegion(gg_rct_B3toB4a)
call B3_TO_B4.AddRegion(gg_rct_B3toB4b)
call B3_TO_B4.AddRegion(gg_rct_B3toB4c)
call B3_TO_B4.AddRegion(gg_rct_B3toB4d)
call B3_TO_B4.AddRegion(gg_rct_Base4)
set B3_TO_G3 = GuardPath.create(180)
call B3_TO_G3.AddRegion(gg_rct_Base3)
call B3_TO_G3.AddRegion(gg_rct_B3toG3a)
call B3_TO_G3.AddRegion(gg_rct_B3toG3b)
call B3_TO_G3.AddRegion(gg_rct_B3toG3c)
call B3_TO_G3.AddRegion(gg_rct_GoldMine3)
set B3_TO_G3b = GuardPath.create(180)
call B3_TO_G3b.AddRegion(gg_rct_Base3)
call B3_TO_G3b.AddRegion(gg_rct_B3toG3a)
call B3_TO_G3b.AddRegion(gg_rct_B3toG3b)
call B3_TO_G3b.AddRegion(gg_rct_B3toG3c)
call B3_TO_G3b.AddRegion(gg_rct_B2toG3b)
call B3_TO_G3b.AddRegion(gg_rct_B2toG3a)
call B3_TO_G3b.AddRegion(gg_rct_Base2)
set B3_TO_G4 = GuardPath.create(180)
call B3_TO_G4.AddRegion(gg_rct_Base3)
call B3_TO_G4.AddRegion(gg_rct_B3toG4a)
call B3_TO_G4.AddRegion(gg_rct_B3toG4b)
call B3_TO_G4.AddRegion(gg_rct_B3toG4c)
call B3_TO_G4.AddRegion(gg_rct_GoldMine4)
set B3_TO_G4b = GuardPath.create(180)
call B3_TO_G4b.AddRegion(gg_rct_Base3)
call B3_TO_G4b.AddRegion(gg_rct_B3toG4a)
call B3_TO_G4b.AddRegion(gg_rct_B3toG4b)
call B3_TO_G4b.AddRegion(gg_rct_B3toG4c)
call B3_TO_G4b.AddRegion(gg_rct_B4toG4c)
call B3_TO_G4b.AddRegion(gg_rct_B4toG4b)
call B3_TO_G4b.AddRegion(gg_rct_B4toG4a)
call B3_TO_G4b.AddRegion(gg_rct_Base4)
set B3_TO_BH = GuardPath.create(225)
call B3_TO_BH.AddRegion(gg_rct_Base3)
call B3_TO_BH.AddRegion(gg_rct_B3toB4a)
call B3_TO_BH.AddRegion(gg_rct_B3toB4b)
call B3_TO_BH.AddRegion(gg_rct_B3toB4c)
call B3_TO_BH.AddRegion(gg_rct_B3toB4d)
call B3_TO_BH.AddRegion(gg_rct_BAtoBHa)
call B3_TO_BH.AddRegion(gg_rct_BAtoBHb)
call B3_TO_BH.AddRegion(gg_rct_B1toB4c)
call B3_TO_BH.AddRegion(gg_rct_B1toB4b)
call B3_TO_BH.AddRegion(gg_rct_B1toB4a)
call B3_TO_BH.AddRegion(gg_rct_BHtoB1c)
call B3_TO_BH.AddRegion(gg_rct_BHtoB1b)
call B3_TO_BH.AddRegion(gg_rct_BHtoB1a)
call B3_TO_BH.AddRegion(gg_rct_HordeWarchiefBase)
set B3_TO_BHb = GuardPath.create(180)
call B3_TO_BHb.AddRegion(gg_rct_Base3)
call B3_TO_BHb.AddRegion(gg_rct_B3toB2a)
call B3_TO_BHb.AddRegion(gg_rct_B3toB2b)
call B3_TO_BHb.AddRegion(gg_rct_B3toB2c)
call B3_TO_BHb.AddRegion(gg_rct_BHtoBAb)
call B3_TO_BHb.AddRegion(gg_rct_BHtoBAa)
call B3_TO_BHb.AddRegion(gg_rct_B1toB2c)
call B3_TO_BHb.AddRegion(gg_rct_B1toB2b)
call B3_TO_BHb.AddRegion(gg_rct_B1toB2a)
call B3_TO_BHb.AddRegion(gg_rct_Base1)
call B3_TO_BHb.AddRegion(gg_rct_BHtoB1c)
call B3_TO_BHb.AddRegion(gg_rct_BHtoB1b)
call B3_TO_BHb.AddRegion(gg_rct_BHtoB1a)
call B3_TO_BHb.AddRegion(gg_rct_HordeWarchiefBase)
set B3_TO_BA = GuardPath.create(45)
call B3_TO_BA.AddRegion(gg_rct_Base3)
call B3_TO_BA.AddRegion(gg_rct_BAtoB3c)
call B3_TO_BA.AddRegion(gg_rct_BAtoB3b)
call B3_TO_BA.AddRegion(gg_rct_BAtoB3a)
call B3_TO_BA.AddRegion(gg_rct_AllianceWarchiefBase)
endfunction
private function SetupB2 takes nothing returns nothing
set B2_TO_B1 = GuardPath.create(270)
call B2_TO_B1.AddRegion(gg_rct_Base2)
call B2_TO_B1.AddRegion(gg_rct_B1toB2d)
call B2_TO_B1.AddRegion(gg_rct_B1toB2c)
call B2_TO_B1.AddRegion(gg_rct_B1toB2b)
call B2_TO_B1.AddRegion(gg_rct_B1toB2a)
call B2_TO_B1.AddRegion(gg_rct_Base1)
set B2_TO_B3 = GuardPath.create(0)
call B2_TO_B3.AddRegion(gg_rct_Base2)
call B2_TO_B3.AddRegion(gg_rct_B3toB2e)
call B2_TO_B3.AddRegion(gg_rct_B3toB2d)
call B2_TO_B3.AddRegion(gg_rct_B3toB2c)
call B2_TO_B3.AddRegion(gg_rct_B3toB2b)
call B2_TO_B3.AddRegion(gg_rct_B3toB2a)
call B2_TO_B3.AddRegion(gg_rct_Base3)
set B2_TO_B4 = GuardPath.create(0)
call B2_TO_B4.AddRegion(gg_rct_Base2)
call B2_TO_B4.AddRegion(gg_rct_B3toB2e)
call B2_TO_B4.AddRegion(gg_rct_B3toB2d)
call B2_TO_B4.AddRegion(gg_rct_B3toB2c)
call B2_TO_B4.AddRegion(gg_rct_B3toB2b)
call B2_TO_B4.AddRegion(gg_rct_B3toB2a)
call B2_TO_B4.AddRegion(gg_rct_Base3)
call B2_TO_B4.AddRegion(gg_rct_B3toB4a)
call B2_TO_B4.AddRegion(gg_rct_B3toB4b)
call B2_TO_B4.AddRegion(gg_rct_B3toB4c)
call B2_TO_B4.AddRegion(gg_rct_B3toB4d)
call B2_TO_B4.AddRegion(gg_rct_Base4)
set B2_TO_B4b = GuardPath.create(270)
call B2_TO_B4b.AddRegion(gg_rct_Base2)
call B2_TO_B4b.AddRegion(gg_rct_B1toB2d)
call B2_TO_B4b.AddRegion(gg_rct_B1toB2c)
call B2_TO_B4b.AddRegion(gg_rct_B1toB2b)
call B2_TO_B4b.AddRegion(gg_rct_B1toB2a)
call B2_TO_B4b.AddRegion(gg_rct_Base1)
call B2_TO_B4b.AddRegion(gg_rct_B1toB4a)
call B2_TO_B4b.AddRegion(gg_rct_B1toB4b)
call B2_TO_B4b.AddRegion(gg_rct_B1toB4c)
call B2_TO_B4b.AddRegion(gg_rct_B1toB4d)
call B2_TO_B4b.AddRegion(gg_rct_B1toB4e)
call B2_TO_B4b.AddRegion(gg_rct_Base4)
set B2_TO_G2 = GuardPath.create(270)
call B2_TO_G2.AddRegion(gg_rct_Base2)
call B2_TO_G2.AddRegion(gg_rct_B2toG2a)
call B2_TO_G2.AddRegion(gg_rct_B2toG2b)
call B2_TO_G2.AddRegion(gg_rct_B2toG2c)
call B2_TO_G2.AddRegion(gg_rct_GoldMine2)
set B2_TO_G2b = GuardPath.create(270)
call B2_TO_G2b.AddRegion(gg_rct_Base2)
call B2_TO_G2b.AddRegion(gg_rct_B2toG2a)
call B2_TO_G2b.AddRegion(gg_rct_B2toG2b)
call B2_TO_G2b.AddRegion(gg_rct_B2toG2c)
call B2_TO_G2b.AddRegion(gg_rct_B1toG2c)
call B2_TO_G2b.AddRegion(gg_rct_B1toG2b)
call B2_TO_G2b.AddRegion(gg_rct_B1toG2a)
call B2_TO_G2b.AddRegion(gg_rct_Base1)
set B2_TO_G3 = GuardPath.create(270)
call B2_TO_G3.AddRegion(gg_rct_Base2)
call B2_TO_G3.AddRegion(gg_rct_B2toG3a)
call B2_TO_G3.AddRegion(gg_rct_B2toG3b)
call B2_TO_G3.AddRegion(gg_rct_GoldMine3)
set B2_TO_G3b = GuardPath.create(270)
call B2_TO_G3b.AddRegion(gg_rct_Base2)
call B2_TO_G3b.AddRegion(gg_rct_B2toG3a)
call B2_TO_G3b.AddRegion(gg_rct_B2toG3b)
call B2_TO_G3b.AddRegion(gg_rct_B3toG3c)
call B2_TO_G3b.AddRegion(gg_rct_B3toG3b)
call B2_TO_G3b.AddRegion(gg_rct_B3toG3a)
call B2_TO_G3b.AddRegion(gg_rct_Base3)
set B2_TO_BH = GuardPath.create(270)
call B2_TO_BH.AddRegion(gg_rct_Base2)
call B2_TO_BH.AddRegion(gg_rct_B1toB2d)
call B2_TO_BH.AddRegion(gg_rct_B1toB2c)
call B2_TO_BH.AddRegion(gg_rct_B1toB2b)
call B2_TO_BH.AddRegion(gg_rct_B1toB2a)
call B2_TO_BH.AddRegion(gg_rct_Base1)
call B2_TO_BH.AddRegion(gg_rct_BHtoB1c)
call B2_TO_BH.AddRegion(gg_rct_BHtoB1b)
call B2_TO_BH.AddRegion(gg_rct_BHtoB1a)
call B2_TO_BH.AddRegion(gg_rct_HordeWarchiefBase)
set B2_TO_BA = GuardPath.create(225)
call B2_TO_BA.AddRegion(gg_rct_Base2)
call B2_TO_BA.AddRegion(gg_rct_B3toB2e)
call B2_TO_BA.AddRegion(gg_rct_B3toB2d)
call B2_TO_BA.AddRegion(gg_rct_B3toB2c)
call B2_TO_BA.AddRegion(gg_rct_B3toB2b)
call B2_TO_BA.AddRegion(gg_rct_B3toB2a)
call B2_TO_BA.AddRegion(gg_rct_Base3)
call B2_TO_BA.AddRegion(gg_rct_BAtoB3c)
call B2_TO_BA.AddRegion(gg_rct_BAtoB3b)
call B2_TO_BA.AddRegion(gg_rct_BAtoB3a)
call B2_TO_BA.AddRegion(gg_rct_AllianceWarchiefBase)
endfunction
private function SetupB1 takes nothing returns nothing
//Base1
set B1_TO_B2 = GuardPath.create(90)
call B1_TO_B2.AddRegion(gg_rct_Base1)
call B1_TO_B2.AddRegion(gg_rct_B1toB2a)
call B1_TO_B2.AddRegion(gg_rct_B1toB2b)
call B1_TO_B2.AddRegion(gg_rct_B1toB2c)
call B1_TO_B2.AddRegion(gg_rct_B1toB2d)
call B1_TO_B2.AddRegion(gg_rct_Base2)
set B1_TO_B3 = GuardPath.create(90)
call B1_TO_B3.AddRegion(gg_rct_Base1)
call B1_TO_B3.AddRegion(gg_rct_B1toB2a)
call B1_TO_B3.AddRegion(gg_rct_B1toB2b)
call B1_TO_B3.AddRegion(gg_rct_B1toB2c)
call B1_TO_B3.AddRegion(gg_rct_BHtoBAa)
call B1_TO_B3.AddRegion(gg_rct_BHtoBAb)
call B1_TO_B3.AddRegion(gg_rct_B3toB2c)
call B1_TO_B3.AddRegion(gg_rct_B3toB2b)
call B1_TO_B3.AddRegion(gg_rct_B3toB2a)
call B1_TO_B3.AddRegion(gg_rct_Base3)
set B1_TO_B3b = GuardPath.create(0)
call B1_TO_B3b.AddRegion(gg_rct_Base1)
call B1_TO_B3b.AddRegion(gg_rct_B1toB4a)
call B1_TO_B3b.AddRegion(gg_rct_B1toB4b)
call B1_TO_B3b.AddRegion(gg_rct_B1toB4c)
call B1_TO_B3b.AddRegion(gg_rct_BAtoBHb)
call B1_TO_B3b.AddRegion(gg_rct_BAtoBHa)
call B1_TO_B3b.AddRegion(gg_rct_B3toB4d)
call B1_TO_B3b.AddRegion(gg_rct_B3toB4c)
call B1_TO_B3b.AddRegion(gg_rct_B3toB4b)
call B1_TO_B3b.AddRegion(gg_rct_B3toB4a)
call B1_TO_B3b.AddRegion(gg_rct_Base3)
set B1_TO_B4 = GuardPath.create(0)
call B1_TO_B4.AddRegion(gg_rct_Base1)
call B1_TO_B4.AddRegion(gg_rct_B1toB4a)
call B1_TO_B4.AddRegion(gg_rct_B1toB4b)
call B1_TO_B4.AddRegion(gg_rct_B1toB4c)
call B1_TO_B4.AddRegion(gg_rct_B1toB4d)
call B1_TO_B4.AddRegion(gg_rct_B1toB4e)
call B1_TO_B4.AddRegion(gg_rct_Base4)
set B1_TO_G1 = GuardPath.create(0)
call B1_TO_G1.AddRegion(gg_rct_Base1)
call B1_TO_G1.AddRegion(gg_rct_B1toG1a)
call B1_TO_G1.AddRegion(gg_rct_B1toG1b)
call B1_TO_G1.AddRegion(gg_rct_B1toG1c)
call B1_TO_G1.AddRegion(gg_rct_GoldMine1)
set B1_TO_G1b = GuardPath.create(0)
call B1_TO_G1b.AddRegion(gg_rct_Base1)
call B1_TO_G1b.AddRegion(gg_rct_B1toG1a)
call B1_TO_G1b.AddRegion(gg_rct_B1toG1b)
call B1_TO_G1b.AddRegion(gg_rct_B1toG1c)
call B1_TO_G1b.AddRegion(gg_rct_B4toG1b)
call B1_TO_G1b.AddRegion(gg_rct_B4toG1a)
call B1_TO_G1b.AddRegion(gg_rct_Base4)
set B1_TO_G2 = GuardPath.create(0)
call B1_TO_G2.AddRegion(gg_rct_Base1)
call B1_TO_G2.AddRegion(gg_rct_B1toG2a)
call B1_TO_G2.AddRegion(gg_rct_B1toG2b)
call B1_TO_G2.AddRegion(gg_rct_B1toG2c)
call B1_TO_G2.AddRegion(gg_rct_GoldMine2)
set B1_TO_G2b = GuardPath.create(0)
call B1_TO_G2b.AddRegion(gg_rct_Base1)
call B1_TO_G2b.AddRegion(gg_rct_B1toG2a)
call B1_TO_G2b.AddRegion(gg_rct_B1toG2b)
call B1_TO_G2b.AddRegion(gg_rct_B1toG2c)
call B1_TO_G2b.AddRegion(gg_rct_B2toG2c)
call B1_TO_G2b.AddRegion(gg_rct_B2toG2b)
call B1_TO_G2b.AddRegion(gg_rct_B2toG2a)
call B1_TO_G2b.AddRegion(gg_rct_Base2)
set B1_TO_BH = GuardPath.create(225)
call B1_TO_BH.AddRegion(gg_rct_Base1)
call B1_TO_BH.AddRegion(gg_rct_BHtoB1c)
call B1_TO_BH.AddRegion(gg_rct_BHtoB1b)
call B1_TO_BH.AddRegion(gg_rct_BHtoB1a)
call B1_TO_BH.AddRegion(gg_rct_HordeWarchiefBase)
set B1_TO_BA = GuardPath.create(45)
call B1_TO_BA.AddRegion(gg_rct_Base1)
call B1_TO_BA.AddRegion(gg_rct_B1toB2a)
call B1_TO_BA.AddRegion(gg_rct_B1toB2b)
call B1_TO_BA.AddRegion(gg_rct_B1toB2c)
call B1_TO_BA.AddRegion(gg_rct_BHtoBAa)
call B1_TO_BA.AddRegion(gg_rct_BHtoBAb)
call B1_TO_BA.AddRegion(gg_rct_B3toB2c)
call B1_TO_BA.AddRegion(gg_rct_B3toB2b)
call B1_TO_BA.AddRegion(gg_rct_B3toB2a)
call B1_TO_BA.AddRegion(gg_rct_Base3)
call B1_TO_BA.AddRegion(gg_rct_BAtoB3c)
call B1_TO_BA.AddRegion(gg_rct_BAtoB3b)
call B1_TO_BA.AddRegion(gg_rct_BAtoB3a)
call B1_TO_BA.AddRegion(gg_rct_AllianceWarchiefBase)
set B1_TO_BAb = GuardPath.create(45)
call B1_TO_BAb.AddRegion(gg_rct_Base1)
call B1_TO_BAb.AddRegion(gg_rct_B1toB4a)
call B1_TO_BAb.AddRegion(gg_rct_B1toB4b)
call B1_TO_BAb.AddRegion(gg_rct_B1toB4c)
call B1_TO_BAb.AddRegion(gg_rct_BAtoBHb)
call B1_TO_BAb.AddRegion(gg_rct_BAtoBHa)
call B1_TO_BAb.AddRegion(gg_rct_B3toB4d)
call B1_TO_BAb.AddRegion(gg_rct_B3toB4c)
call B1_TO_BAb.AddRegion(gg_rct_B3toB4b)
call B1_TO_BAb.AddRegion(gg_rct_B3toB4a)
call B1_TO_BAb.AddRegion(gg_rct_Base3)
call B1_TO_BAb.AddRegion(gg_rct_BAtoB3c)
call B1_TO_BAb.AddRegion(gg_rct_BAtoB3b)
call B1_TO_BAb.AddRegion(gg_rct_BAtoB3a)
call B1_TO_BAb.AddRegion(gg_rct_AllianceWarchiefBase)
endfunction
public function Setup takes nothing returns nothing
call ForForce(bj_FORCE_PLAYER[0],function SetupB1)
call ForForce(bj_FORCE_PLAYER[0],function SetupB2)
call ForForce(bj_FORCE_PLAYER[0],function SetupB3)
call ForForce(bj_FORCE_PLAYER[0],function SetupB4)
call ForForce(bj_FORCE_PLAYER[0],function SetupBHA)
call GuardPath.regions.flush()
call GuardPath.regions.destroy()
endfunction
private function Init takes nothing returns nothing
call GuardPath.Ini()
set UnitsPath = LinkedList.create()
call RegisterCombatEvent(function ReturnToPath,EVENT_UNIT_LEAVE_COMBAT)
endfunction
endlibrary
library ControlBase requires NewGroup, CTL, GameMultiboard, InCombat, Lightning
globals
private constant real TIME_TAKE_CONTROL = 10.00
private constant real RANGE_TO_TAKE_CONTROL = 275.00
private constant real RANGE_TO_BREAK_CONTROL = 300.00
private constant string SFX_CONTROL_TAKE = "Abilities\\Spells\\Undead\\ReviveUndead\\ReviveUndead.mdl"
private constant string MESSAGE_CONTROL_TAKE = " captured a |c00ff8000Tower|r"
private constant integer EXP_REWARD_TEAM = 20
private constant integer GOLD_REWARD_TEAM = 200
RSound TowerCaptureSound = 0
RSound TowerEnemyCaptureSound = 0
RSound TowerLossSound = 0
private trigger array EnterTrigger[4]
endglobals
struct ControlBase extends array
unit u
Base base
static group CONTROL_GROUP = null
private method Destroy takes nothing returns nothing
local Hero h = GetUnitData(u,"HeroIndex")
//call BJDebugMsg("destroy control")
call GroupRemoveUnit(CONTROL_GROUP,u)
if FirstOfGroup(CONTROL_GROUP) == null then
call ReleaseGroup(CONTROL_GROUP)
set CONTROL_GROUP = null
endif
call SetUnitData(u,"BaseControl",0)
if h.heroAI != -1 then
call h.heroAI.setGuardSpot(0,0,0)
endif
set u = null
set base = 0
call this.destroy()
endmethod
implement CTL
local real xu
local real yu
local real dist
implement CTLExpire
set dist = Distance(GetUnitX(u),GetUnitY(u),base.x,base.y)
if base.state == BASE_STATE_CONTROLED then
set Players[GetPlayerId(GetOwningPlayer(u))].basesT = Players[GetPlayerId(GetOwningPlayer(u))].basesT + 1
call Destroy()
else
if dist > RANGE_TO_BREAK_CONTROL or not UnitAlive(u) or IsUnitHidden(u) then
set base.controlUnits = base.controlUnits - 1
call Status.Add(STATUS_STUN,u,1.0,Status_EFFECT[STATUS_STUN])
if base.controlUnits == 0 and base.state == BASE_STATE_TAKING then
set base.state = BASE_STATE_NEUTRAL
set base.controlTeam = 0
set base.time = 0
call base.aoe.destroy()
call base.bar.setPercent(0)
call base.bar.show(false)
endif
call Destroy()
else
if base.time >= TIME_TAKE_CONTROL and base.state == BASE_STATE_TAKING then
set base.state = BASE_STATE_CONTROLED
set base.owner = base.controlTeam
set base.owner.bases = base.owner.bases + 1
call MultiboardUpdateTeamBases(base.owner)
call base.changeOwner()
set base.controlTeam = 0
set base.controlUnits = 0
set base.time = 0
call base.aoe.destroy()
call base.bar.setPercent(0)
call base.bar.show(false)
if base.owner == 1 then
call TowerCaptureSound.playForTeam(0,0,0,100,1)
call TowerEnemyCaptureSound.playForTeam(0,0,0,100,2)
elseif base.owner == 2 then
call TowerCaptureSound.playForTeam(0,0,0,100,2)
call TowerEnemyCaptureSound.playForTeam(0,0,0,100,1)
endif
if base.owner == 1 then
call AddTeamGold(Team[1],GOLD_REWARD_TEAM)
call AddTeamBarPercentExp(Team[1],0,EXP_REWARD_TEAM)
call Message.Show(MESSAGE_CONTROL_TAKE+" ("+GOLD_COLOR+"+200|r)",MESSAGE_STYLE_HORDE)
elseif base.owner == 2 then
call AddTeamGold(Team[2],GOLD_REWARD_TEAM)
call AddTeamBarPercentExp(Team[2],0,EXP_REWARD_TEAM)
call Message.Show(MESSAGE_CONTROL_TAKE+" ("+GOLD_COLOR+"+200|r)",MESSAGE_STYLE_ALLIANCE)
endif
call DestroyEffect(AddSpecialEffect(SFX_CONTROL_TAKE,base.x,base.y))
set Players[GetPlayerId(GetOwningPlayer(u))].basesT = Players[GetPlayerId(GetOwningPlayer(u))].basesT + 1
call Destroy()
else
set base.time = base.time + 0.03125
call base.bar.setPercent(100*base.time/10.00)
endif
endif
endif
implement CTLEnd
public static method CreateControl takes unit cu, Base cbase returns thistype
local thistype this = thistype.create()
local Hero h = GetUnitData(cu,"HeroIndex")
set u = cu
set base = cbase
call SetUnitData(u,"BaseControl",this)
if CONTROL_GROUP == null then
set CONTROL_GROUP = NewGroup()
endif
call GroupAddUnit(CONTROL_GROUP,this.u)
if h.heroAI != -1 then
call h.heroAI.setGuardSpot(cbase.x,cbase.y,300)
endif
return this
endmethod
endstruct
private function ControlFilter takes unit h, Base b returns boolean
if UnitAlive(h) and not IsUnitIllusion(h) and not IsUnitHidden(h) and not IsUnitInGroup(h,ControlBase.CONTROL_GROUP) and GetUnitTypeId(h) != 'Owc1' and GetUnitTypeId(h) != 'Awc1' then
if b.state == BASE_STATE_NEUTRAL then
if b.controlTeam == 0 then
set b.controlTeam = GetUnitTeam(h)
set b.state = BASE_STATE_TAKING
call b.bar.show(true)
set b.aoe = AoE.create(b.x,b.y,null,RANGE_TO_BREAK_CONTROL)
if b.controlTeam == 1 then
call b.bar.setColorPlayer(Player(0))
call BlzSetSpecialEffectColor(b.aoe.sfx,255,0,0)
else
call b.bar.setColorPlayer(Player(1))
call BlzSetSpecialEffectColor(b.aoe.sfx,0,0,255)
endif
endif
endif
if b.state == BASE_STATE_TAKING then
if IsUnitAlly(h,b.controlTeam.captain) then
set b.controlUnits = b.controlUnits + 1
call ControlBase.CreateControl(h,b)
return true
endif
endif
endif
return false
endfunction
private function onEnterBase1 takes nothing returns boolean
local unit u = GetFilterUnit()
if IsUnitType(u,UNIT_TYPE_HERO) and GetUnitAbilityLevel(u,'A02T') == 0 then
call ControlFilter(u,Base[1])
endif
set u = null
return false
endfunction
private function onEnterBase2 takes nothing returns boolean
local unit u = GetFilterUnit()
if IsUnitType(u,UNIT_TYPE_HERO) and GetUnitAbilityLevel(u,'A02T') == 0 then
call ControlFilter(u,Base[2])
endif
set u = null
return false
endfunction
private function onEnterBase3 takes nothing returns boolean
local unit u = GetFilterUnit()
if IsUnitType(u,UNIT_TYPE_HERO) and GetUnitAbilityLevel(u,'A02T') == 0 then
call ControlFilter(u,Base[3])
endif
set u = null
return false
endfunction
private function onEnterBase4 takes nothing returns boolean
local unit u = GetFilterUnit()
if IsUnitType(u,UNIT_TYPE_HERO) and GetUnitAbilityLevel(u,'A02T') == 0 then
call ControlFilter(u,Base[4])
endif
set u = null
return false
endfunction
private function OnLeaveCombat takes nothing returns nothing
local unit u = GetEventCombatLeaveUnit()
local real x
local real y
if IsUnitType(u,UNIT_TYPE_HERO) and GetUnitAbilityLevel(u,'A02T') == 0 then
set x = GetUnitX(u)
set y = GetUnitY(u)
if Distance(x,y,Base[1].x,Base[1].y) <= RANGE_TO_TAKE_CONTROL then
call ControlFilter(u,Base[1])
elseif Distance(x,y,Base[2].x,Base[2].y) <= RANGE_TO_TAKE_CONTROL then
call ControlFilter(u,Base[2])
elseif Distance(x,y,Base[3].x,Base[3].y) <= RANGE_TO_TAKE_CONTROL then
call ControlFilter(u,Base[3])
elseif Distance(x,y,Base[4].x,Base[4].y) <= RANGE_TO_TAKE_CONTROL then
call ControlFilter(u,Base[4])
endif
endif
set u = null
endfunction
public function Setup takes nothing returns nothing
set EnterTrigger[0] = CreateTrigger()
call TriggerRegisterUnitInRange(EnterTrigger[0],Base[1].dummyPlatform,RANGE_TO_TAKE_CONTROL,Filter(function onEnterBase1))
set EnterTrigger[1] = CreateTrigger()
call TriggerRegisterUnitInRange(EnterTrigger[1],Base[2].dummyPlatform,RANGE_TO_TAKE_CONTROL,Filter(function onEnterBase2))
set EnterTrigger[2] = CreateTrigger()
call TriggerRegisterUnitInRange(EnterTrigger[2],Base[3].dummyPlatform,RANGE_TO_TAKE_CONTROL,Filter(function onEnterBase3))
set EnterTrigger[3] = CreateTrigger()
call TriggerRegisterUnitInRange(EnterTrigger[3],Base[4].dummyPlatform,RANGE_TO_TAKE_CONTROL,Filter(function onEnterBase4))
call RegisterCombatEvent(function OnLeaveCombat,EVENT_UNIT_LEAVE_COMBAT)
set TowerCaptureSound = RSound.create("Sound\\Interface\\QuestNew.flac", false, true, 12700, 12700)
set TowerEnemyCaptureSound = RSound.create("Sound\\Interface\\Rescue.flac", false, true, 12700, 12700)
set TowerLossSound = RSound.create("Sound\\Buildings\\Other\\GoldMine\\GoldMineDeath1.flac", false, true, 12700, 12700)
endfunction
endlibrary
library GoldMine uses PlayerLib, CTL, MiscLibrary, UnitRecycler, InCombat
globals
private constant integer GOLD_MINE_ID = 'n00N'
private constant string GOLD_MINE_WORKANIM = "Stand Work"
private constant string GOLD_MINE_EFFECT = "Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl"
private constant string CAPTURED_SFX = "Objects\\StartLocation\\StartLocation.mdl"
RSound HordeCaptureSound = 0
RSound HordeLossSound = 0
RSound AllianceCaptureSound = 0
RSound AllianceLossSound = 0
endglobals
struct GoldMine extends array
unit gold
rect r
real x
real y
real a
DefenderSquad defenders
Team owner
effect sfx
minimapicon icon
static HashTable AI_count
static HashTable AI_current
static integer timeCount = 0
//For Teleport
real angle
public method getCurrentHeroes takes Team t returns integer
return AI_current[t].integer[this]
endmethod
public method getHeroesTarget takes Team t returns integer
return AI_count[t].integer[this]
endmethod
public method addHeroesTarget takes Team t, integer i returns nothing
set AI_count[t].integer[this] = AI_count[t].integer[this] + i
endmethod
public method addCurrentHeroes takes Team t, integer i returns nothing
set AI_current[t].integer[this] = AI_current[t].integer[this] + i
endmethod
public static method GetGoldMineFromUnit takes unit u returns thistype
if thistype[1].gold == u then
return thistype[1]
endif
if thistype[2].gold == u then
return thistype[2]
endif
if thistype[3].gold == u then
return thistype[3]
endif
if thistype[4].gold == u then
return thistype[4]
endif
return 0
endmethod
public static method GiveResources takes nothing returns nothing
local integer c1 = Team[1].goldmines
local integer c2 = Team[2].goldmines
local boolean sw = true
if AncientObelisk.owner == 1 and Team[2].resources > Team[1].resources then
set c1 = c1 + 1
elseif AncientObelisk.owner == 2 and Team[1].resources > Team[2].resources then
set c2 = c2 + 1
endif
/*if Team[1].commander.commanderAssault.mineTarget != 0 and Team[1].commander.commanderAssault.mineTarget.owner == Team[1] then
set c1 = c1 + 1
endif
if Team[2].commander.commanderAssault.mineTarget != 0 and Team[2].commander.commanderAssault.mineTarget.owner == Team[2] then
set c2 = c2 + 1
endif*/
/*if c1 > c2 then
set sw = true
else
set sw = Team[1].giveR
set Team[1].giveR = not Team[1].giveR
endif*/
if sw then
call Team[1].addResource(c1)
endif
/*if c2 > c1 then
set sw = true
else
set sw = Team[2].giveR
set Team[2].giveR = not Team[2].giveR
endif*/
if sw then
call Team[2].addResource(c2)
endif
endmethod
public method updateDefenders takes nothing returns nothing
call defenders.destroy()
if owner == 1 then
set defenders = DefenderSquad.create(x,y,HORDE_DS,a,Game.PLAYER_WARCHIEF_HORDE,this)
else
set defenders = DefenderSquad.create(x,y,ALLIANCE_DS,a,Game.PLAYER_WARCHIEF_ALLIANCE,this)
endif
endmethod
public method changeOwner takes player p returns nothing
local integer lvl
local Team t = GetPlayerTeamEx(p)
local Team lo = owner
call SetUnitAnimation(gold,GOLD_MINE_WORKANIM)
call DestroyEffect(AddSpecialEffectTarget(GOLD_MINE_EFFECT,gold,"origin"))
call DestroyMinimapIcon(icon)
if owner != 0 then
if this == 2 or this == 4 then
set angle = a - 90
else
set angle = a + 90.00
endif
set owner.goldmines = owner.goldmines - 1
call MultiboardUpdateTeamMines(owner)
if p == Game.PLAYER_NEUTRAL_HOSTILE then
call Message.ShowToForce(Team[1].forceP," A Gold Mine has become neutral.",MESSAGE_STYLE_HORDE)
endif
endif
set owner = t
if owner != 0 then
set owner.goldmines = owner.goldmines + 1
call MultiboardUpdateTeamMines(owner)
set lvl = BaseTroops[4*(owner-1) + this].level
set Players[GetPlayerId(p)].minesT = Players[GetPlayerId(p)].minesT + 1
endif
if lo == 1 then
call HordeLossSound.playForTeam(0,0,0,100,Team[1])
elseif lo == 2 then
call AllianceLossSound.playForTeam(0,0,0,100,Team[2])
elseif lo == 0 then
if owner == 1 then
call TowerEnemyCaptureSound.playForTeam(0,0,0,100,Team[2])
elseif owner == 2 then
call TowerEnemyCaptureSound.playForTeam(0,0,0,100,Team[1])
endif
endif
if owner == 1 then
call Message.Show(" captured a |cFFEFB743Gold Mine|r",MESSAGE_STYLE_HORDE)
call SetUnitOwner(gold,Game.PLAYER_WARCHIEF_HORDE,true)
set defenders = DefenderSquad.create(x,y,HORDE_DS,a,Game.PLAYER_WARCHIEF_HORDE,this)
call UnitRemoveAbility(gold,'Abun')
call HordeCaptureSound.playForTeam(0,0,0,100,owner)
call BlzSetSpecialEffectColorByPlayer(sfx,Game.PLAYER_WARCHIEF_HORDE)
set icon = CreateMinimapIconOnUnit(gold, 255, 255, 255, "war3mapImported\\MiniMap-Mine-Horde.mdx", FOG_OF_WAR_FOGGED )
elseif owner == 2 then
call Message.Show(" captured a |cFFEFB743Gold Mine|r",MESSAGE_STYLE_ALLIANCE)
call SetUnitOwner(gold,Game.PLAYER_WARCHIEF_ALLIANCE,true)
call UnitRemoveAbility(gold,'Abun')
call AllianceCaptureSound.playForTeam(0,0,0,100,owner)
set defenders = DefenderSquad.create(x,y,ALLIANCE_DS,a,Game.PLAYER_WARCHIEF_ALLIANCE,this)
call BlzSetSpecialEffectColorByPlayer(sfx,Game.PLAYER_WARCHIEF_ALLIANCE)
set icon = CreateMinimapIconOnUnit(gold, 255, 255, 255, "war3mapImported\\MiniMap-Mine-Alliance.mdx", FOG_OF_WAR_FOGGED )
else
call SetUnitOwner(gold,Game.PLAYER_NEUTRAL_HOSTILE,true)
call UnitAddAbility(gold,'Abun')
call SetUnitAnimation(gold,"stand")
call BlzSetSpecialEffectColorByPlayer(sfx,Game.PLAYER_NEUTRAL_HOSTILE)
set owner = 0
endif
endmethod
public method Setup takes unit u, rect rg, real a returns nothing
local integer id = GetUnitUserData(u)
local real xu = GetUnitX(u)
local real yu = GetUnitY(u)
set Index[id].lock = true
set owner = 0
set gold = u
set r = rg
set this.a = a
set x = GetRectCenterX(rg)
set y = GetRectCenterY(rg)
call UnitRemoveAbility(u,'Amov')
call RemoveGuardPosition(u)
set sfx = AddSpecialEffect(CAPTURED_SFX,xu,yu)
call BlzSetSpecialEffectScale(sfx,1.2)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(xu,yu) - 75)
call BlzSetSpecialEffectColorByPlayer(sfx,Game.PLAYER_NEUTRAL_HOSTILE)
call BlzSetSpecialEffectAlpha(sfx,150)
set icon = CreateMinimapIconOnUnit(u, 255, 255, 255, "war3mapImported\\MiniMap-Mine-Neutral.mdx", FOG_OF_WAR_FOGGED )
if this == 2 or this == 3 then
set angle = a - 90
else
set angle = a + 90.00
endif
endmethod
endstruct
public function GSetup takes nothing returns nothing
set GoldMine.AI_count = HashTable.create()
set GoldMine.AI_current = HashTable.create()
call GoldMine[1].Setup(gg_unit_n00N_0058,gg_rct_GoldMine1,120)
call GoldMine[2].Setup(gg_unit_n00N_0033,gg_rct_GoldMine2,0)
call GoldMine[3].Setup(gg_unit_n00N_0118,gg_rct_GoldMine3,300)
call GoldMine[4].Setup(gg_unit_n00N_0117,gg_rct_GoldMine4,180)
set gg_unit_n00N_0058 = null
set gg_unit_n00N_0033 = null
set gg_unit_n00N_0118 = null
set gg_unit_n00N_0117 = null
set HordeCaptureSound = RSound.create("war3mapImported\\HordeCapture.mp3", false, true, 12700, 12700)
set HordeLossSound = RSound.create("war3mapImported\\HordeLoss.mp3", false, true, 12700, 12700)
set AllianceCaptureSound = RSound.create("war3mapImported\\AllianceCapture.mp3", false, true, 12700, 12700)
set AllianceLossSound = RSound.create("war3mapImported\\AllianceLoss.mp3", false, true, 12700, 12700)
endfunction
endlibrary
library CommanderLib uses MiscLibrary
struct Commander
unit dummyReq
unit heroUnit
real angle
real xOrigin
real yOrigin
boolean assaultActive
effect sfx
CommanderAssault commanderAssault
public static method UpdateAbilities takes nothing returns nothing
local string q = "Sends a destructive shockwave that travels towards the target point, dealing |c00ee82eePure Damage|r to enemies, deals 2x damage to units.|n|n|c0087cefaDamage: |r"+I2S(100 + 5 * GameLoop.Minutes)+".|n|c0087cefaDistance: |r1100.|n|c0087cefaAoE: |r150.|n|n|c00b4b4b4Cooldown: |r4s."
local string w = "Hits the target point with such force that lifts the enemies into the air dealing |c00ee82eePure Damage|r, has 1.3s casting time.|n|n|c0087cefaDamage: |r"+I2S(150 + 5 * GameLoop.Minutes)+"|n|c0087cefaAoE: |r240.|n|c0087cefaAir Time: |r1.2s.|n|n|c00b4b4b4Cooldown: |r10s"
local string e = "The Commander presence inspires the team units, increasing their attack damage, armor and provides them reduction to spell damage, until they die.|n|n|c0087cefaDamage: |r"+I2S(20 + 2 * (GameLoop.Minutes/5))+".|n|c0087cefaArmor: |r"+I2S(5 + (GameLoop.Minutes/5))+"|n|c0087cefaSpell Damage Reduction: |r50%."
call BlzSetAbilityExtendedTooltip('A02T',q,0)
call BlzSetAbilityExtendedTooltip('A0AB',w,0)
call BlzSetAbilityExtendedTooltip('A0BL',e,0)
endmethod
public method UpdateStats takes nothing returns nothing
call BlzSetUnitMaxHP(heroUnit,6500 + 100 * GameLoop.Minutes)
if commanderAssault == 0 then
call SetUnitState(heroUnit,UNIT_STATE_LIFE,99999)
endif
call BlzSetUnitArmor(heroUnit,10 + 1 * GameLoop.Minutes)
call BlzSetUnitBaseDamage(heroUnit,(148 + 2 * GameLoop.Minutes) - 1,0)
endmethod
public method commanderStand takes boolean flag returns nothing
if flag then
call BlzUnitDisableAbility(heroUnit,'Amov',true,true)
call BlzUnitDisableAbility(heroUnit,'Aatk',true,true)
call BlzUnitDisableAbility(heroUnit,'A099',false,false)
call BlzUnitDisableAbility(heroUnit,'A098',false,false)
call RemoveUnit(dummyReq)
call UnitAddAbility(heroUnit,'Aall')
call UnitMakeAbilityPermanent(heroUnit,true,'Aall')
call BlzSetUnitFacingEx(heroUnit,angle)
else
call BlzUnitDisableAbility(heroUnit,'Amov',false,false)
call BlzUnitDisableAbility(heroUnit,'Aatk',false,false)
call BlzUnitDisableAbility(heroUnit,'A099',true,true)
call BlzUnitDisableAbility(heroUnit,'A098',true,true)
set dummyReq = CreateUnit(GetOwningPlayer(heroUnit),'h002',xOrigin,yOrigin,angle)
call UnitRemoveAbility(heroUnit,'Aall')
call BlzSetUnitFacingEx(heroUnit,angle)
endif
endmethod
public static method create takes real x, real y, player owner, real angle returns thistype
local thistype this = thistype.allocate()
set this.angle = angle
if this == 1 then
set heroUnit = CreateUnit(owner,'H00T',x,y,angle)
call CreateMinimapIconOnUnit(heroUnit, 255, 255, 255, "war3mapImported\\MiniMap-king-horde.mdx",FOG_OF_WAR_FOGGED)
set sfx = AddSpecialEffectTarget("war3mapImported\\Commander Horde Halo.mdx",heroUnit,"origin")
set Players[0].hero = Hero.create(heroUnit,CommanderData_HORDE_HERO_DATA)
else
set heroUnit = CreateUnit(owner,'H00W',x,y,angle)
call CreateMinimapIconOnUnit(heroUnit, 255, 255, 255, "war3mapImported\\MiniMap-king-alliance.mdx",FOG_OF_WAR_FOGGED)
set sfx = AddSpecialEffectTarget("war3mapImported\\Commander Alliance Halo.mdx",heroUnit,"origin")
set Players[1].hero = Hero.create(heroUnit,CommanderData_ALLIANCE_HERO_DATA)
endif
call SuspendHeroXP(heroUnit,true)
call AddUnitNegativeStatusReduction(heroUnit,0,true)
call DisableHeroRegen.evaluate(heroUnit,true,true)
call MakeFly(heroUnit)
call RemoveGuardPosition(heroUnit)
call commanderStand(true)
call BlzStartUnitAbilityCooldown(heroUnit,'A099',120)
call BlzStartUnitAbilityCooldown(heroUnit,'A098',120)
set Index[GetUnitUserData(heroUnit)].lock = true
set xOrigin = x
set yOrigin = y
set assaultActive = false
set commanderAssault = 0
return this
endmethod
endstruct
public function Setup takes nothing returns nothing
set Team[1].commander = Commander.create(GetRectCenterX(gg_rct_HordeWarchiefBase),GetRectCenterY(gg_rct_HordeWarchiefBase),Game.PLAYER_WARCHIEF_HORDE,45)
set Team[2].commander = Commander.create(GetRectCenterX(gg_rct_AllianceWarchiefBase),GetRectCenterY(gg_rct_AllianceWarchiefBase),Game.PLAYER_WARCHIEF_ALLIANCE,225)
call CommanderAbilities_Setup.evaluate()
endfunction
endlibrary
library CommanderData initializer InitData uses HeroLibrary
globals
public HeroData HORDE_HERO_DATA
public HeroData ALLIANCE_HERO_DATA
endglobals
private function InitData takes nothing returns nothing
set HORDE_HERO_DATA = HeroData.create()
set HORDE_HERO_DATA.TypeID = 'H00W'
set HORDE_HERO_DATA.Name = "Horde Commander"
set HORDE_HERO_DATA.IconID = ""
set HORDE_HERO_DATA.WinAni = ""
set HORDE_HERO_DATA.Block = 0
set HORDE_HERO_DATA.Evasion = 0
set HORDE_HERO_DATA.Resistance = 0
set HORDE_HERO_DATA.LifeRegen = 0
set HORDE_HERO_DATA.ManaRegen = 0
set HORDE_HERO_DATA.Armor = 5
set HORDE_HERO_DATA.AttackRange = 125
set HORDE_HERO_DATA.PrimaryAttribute = 3
set HORDE_HERO_DATA.HeroAbility1 = 'A02T'
set HORDE_HERO_DATA.HeroAbility2 = 'A0AB'
call PreloadGen.Add(HORDE_HERO_DATA.TypeID,PRELOAD_UNIT)
set ALLIANCE_HERO_DATA = HeroData.create()
set ALLIANCE_HERO_DATA.TypeID = 'H00T'
set ALLIANCE_HERO_DATA.Name = "Alliance Commander"
set ALLIANCE_HERO_DATA.IconID = ""
set ALLIANCE_HERO_DATA.WinAni = ""
set ALLIANCE_HERO_DATA.Block = 0
set ALLIANCE_HERO_DATA.Evasion = 0
set ALLIANCE_HERO_DATA.Resistance = 0
set ALLIANCE_HERO_DATA.LifeRegen = 0
set ALLIANCE_HERO_DATA.ManaRegen = 0
set ALLIANCE_HERO_DATA.Armor = 5
set ALLIANCE_HERO_DATA.AttackRange = 125
set ALLIANCE_HERO_DATA.PrimaryAttribute = 3
set ALLIANCE_HERO_DATA.HeroAbility1 = 'A02T'
set ALLIANCE_HERO_DATA.HeroAbility2 = 'A0AB'
call PreloadGen.Add(ALLIANCE_HERO_DATA.TypeID,PRELOAD_UNIT)
endfunction
endlibrary
scope CommanderAssault
globals
private constant string AREA_SFX = "war3mapImported\\Earth Rage.mdx"
private constant real AOE = 900.00
private constant real STUN_DURATION = 1.2
endglobals
struct CommanderAssault extends array
implement Alloc
Team owner
Base baseTarget
GoldMine mineTarget
real xTarget
real yTarget
real hx
real hy
real landX
real landY
integer level
boolean landed
real duration
effect sfxInvu
effect sfxTp
real angle
//
group enum
timer clock
integer castTime
integer channelingOrder
unit closestEnemy
real closestEnemyDist
unit enemyUnit
integer enemyHeroCount
integer enemyUnitCount
unit target
unit lastTarget
boolean goldUnit
boolean isBeingDestroyed
private method InspireUnitsAround takes nothing returns nothing
local group g = NewGroup()
local unit temp
call GroupEnumUnitsInRange(g,xTarget,yTarget,1000,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_VALID_UNIT(temp) and GetOwningPlayer(temp) == owner.captain then
call UnitAddBuff(temp,temp,9999,Inspire.buff,GameLoop.Minutes,0)
endif
endloop
call ReleaseGroup(g)
set g = null
endmethod
public method destroy takes nothing returns nothing
set owner.commander.assaultActive = false
set owner.commander.commanderAssault = 0
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",owner.commander.xOrigin,owner.commander.yOrigin))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",GetUnitX(owner.commander.heroUnit),GetUnitY(owner.commander.heroUnit)))
call SetUnitX(owner.commander.heroUnit,owner.commander.yOrigin)
call SetUnitY(owner.commander.heroUnit,owner.commander.xOrigin)
call SetUnitAnimation(owner.commander.heroUnit,"stand")
call Status.Remove(STATUS_PAUSE,owner.commander.heroUnit)
call Status.Remove(STATUS_INVULNERABLE,owner.commander.heroUnit)
call owner.commander.commanderStand(true)
call ReleaseGroup(enum)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,owner.commander.heroUnit,-(50 * level),0)
call SetUnitData(owner.commander.heroUnit,"Commander_Inst",0)
set enum = null
set closestEnemy = null
set enemyUnit = null
set target = null
set lastTarget = null
set baseTarget = 0
set mineTarget = 0
set isBeingDestroyed = false
call this.deallocate()
endmethod
private static method PreDestroyCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
call DestroyEffect(sfxInvu)
set sfxInvu = null
call DestroyEffect(sfxTp)
set sfxTp = null
call destroy()
call ReleaseTimer(t)
set t = null
endmethod
public method preDestroy takes boolean dead returns nothing
set isBeingDestroyed = true
if clock == null then
return
endif
call ReleaseTimer(clock)
set clock = null
call Status.Add(STATUS_INVULNERABLE,owner.commander.heroUnit,0,0)
call Status.Add(STATUS_PAUSE,owner.commander.heroUnit,0,0)
call UnitRemoveAllBuffs(owner.commander.heroUnit)
if dead then
call SetUnitAnimation(owner.commander.heroUnit,"death")
else
if owner == 1 then
call SetUnitAnimation(owner.commander.heroUnit,"spell")
else
call SetUnitAnimation(owner.commander.heroUnit,"spell channel")
endif
endif
set sfxInvu = AddSpecialEffectTarget("Abilities\\Spells\\Human\\DivineShield\\DivineShieldTarget.mdl",owner.commander.heroUnit,"origin")
set sfxTp = AddSpecialEffect("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTo.mdl",GetUnitX(owner.commander.heroUnit),GetUnitY(owner.commander.heroUnit))
call TimerStart(NewTimerEx(this),1.5,false,function thistype.PreDestroyCallback)
endmethod
private static method UnitFilter takes unit u returns boolean
return GetOwningPlayer(u) != Game.PLAYER_NEUTRAL_EXTRA and GetUnitAbilityLevel(u,Game.FLAG_NO_AGGRO) != 1 and not Status.UnitHasStatus(STATUS_INVULNERABLE,u)
endmethod
private method updateValues takes nothing returns nothing
local real dist = 9999
local real d
local unit temp
set enemyHeroCount = 0
set enemyUnitCount = 0
set closestEnemyDist = 0.00
set closestEnemy = null
set enemyUnit = null
set goldUnit = false
set target = null
set hx = GetUnitX(owner.commander.heroUnit)
set hy = GetUnitY(owner.commander.heroUnit)
call GroupEnumUnitsInRange(enum,hx,hy,1000,null)
loop
set temp = FirstOfGroup(enum)
exitwhen temp == null
call GroupRemoveUnit(enum,temp)
if UnitFilter(temp) then
if FILT_UNIT_ENEMY(temp,owner.captain) then
if IsUnitType(temp,UNIT_TYPE_HERO) then
set d = Distance(hx,hy,GetUnitX(temp),GetUnitY(temp))
set enemyHeroCount = enemyHeroCount + 1
if d < dist then
set closestEnemy = temp
set closestEnemyDist = d
endif
else
if GetUnitAbilityLevel(temp,'ACpv') != 0 then
set goldUnit = true
endif
set enemyUnit = temp
set enemyUnitCount = enemyUnitCount + 1
endif
endif
endif
endloop
endmethod
private method CastAbilities takes nothing returns nothing
local boolean cd1 = BlzGetUnitAbilityCooldownRemaining(owner.commander.heroUnit,'A02T') == 0
local boolean cd2 = BlzGetUnitAbilityCooldownRemaining(owner.commander.heroUnit,'A0AB') == 0
if cd1 then
if enemyHeroCount > 0 then
if closestEnemyDist <= 700 then
if IssuePointOrderById(owner.commander.heroUnit,ORDER_shockwave,GetUnitX(closestEnemy),GetUnitY(closestEnemy)) then
set castTime = 1
return
endif
endif
endif
if enemyUnitCount >= 4 or goldUnit then
if IssuePointOrderById(owner.commander.heroUnit,ORDER_shockwave,GetUnitX(enemyUnit),GetUnitY(enemyUnit)) then
set castTime = 1
return
endif
endif
endif
if cd2 then
if enemyHeroCount > 0 then
if closestEnemyDist <= 250 then
if IssueImmediateOrderById(owner.commander.heroUnit,ORDER_stomp) then
set channelingOrder = ORDER_stomp
return
endif
endif
endif
endif
endmethod
private static method Loop takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local real d
local group g
local unit temp
if landed then
set duration = duration - 0.50
call SetUnitState(owner.commander.heroUnit,UNIT_STATE_MANA,duration)
if duration > 0 then
if castTime > 0 or channelingOrder != 0 then
set castTime = castTime - 1
if castTime < 0 then
set castTime = 0
endif
if GetUnitCurrentOrder(owner.commander.heroUnit) != channelingOrder then
set channelingOrder = 0
endif
else
call updateValues()
call CastAbilities()
if castTime > 0 or channelingOrder != 0 then
return
endif
if Distance(xTarget,yTarget,GetUnitX(owner.commander.heroUnit),GetUnitY(owner.commander.heroUnit)) > 800 then
call LeaveUnitCombat(owner.commander.heroUnit,-2)
set castTime = 1
return
endif
if enemyHeroCount != 0 and closestEnemyDist <= 300 then
set target = closestEnemy
endif
if target != null then
set d = Distance(hx,hy,GetUnitX(target),GetUnitY(target))
if d <= 800 then
if target != lastTarget then
set lastTarget = target
call IssueTargetOrderById(owner.commander.heroUnit,ORDER_attack,target)
endif
endif
else
if enemyUnitCount != 0 then
if GetUnitCurrentOrder(owner.commander.heroUnit) != ORDER_attack then
call IssuePointOrderById(owner.commander.heroUnit,ORDER_attack,GetUnitX(enemyUnit),GetUnitY(enemyUnit))
endif
endif
endif
endif
else
call preDestroy(false)
endif
else
set landed = true
set castTime = 0
call QueueUnitAnimation(owner.commander.heroUnit,"stand")
set g = NewGroup()
call GroupEnumUnitsInRange(g,GetUnitX(owner.commander.heroUnit),GetUnitY(owner.commander.heroUnit),AOE,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,owner.captain) then
call Status.Add(STATUS_STUN,temp,STUN_DURATION,Status_EFFECT[STATUS_STUN])
endif
endloop
call ReleaseGroup(g)
set g = null
endif
endmethod
public static method create takes Team t, Base b, GoldMine g returns thistype
local thistype this = thistype.allocate()
local effect sfx
local real a = GetRandomInt(1,360) * bj_DEGTORAD
set owner = t
if b != 0 then
set baseTarget = b
set landX = b.x + 250 * Cos(a)
set landY = b.y + 250 * Sin(a)
set xTarget = b.x
set yTarget = b.y
set angle = 270
call BlzSetUnitFacingEx(t.commander.heroUnit,90)
elseif g != 0 then
set mineTarget = g
set landX = g.x + 150 * Cos(g.a * bj_DEGTORAD)
set landY = g.y + 150 * Sin(g.a * bj_DEGTORAD)
set xTarget = g.x
set yTarget = g.y
set angle = g.a
call BlzSetUnitFacingEx(t.commander.heroUnit,g.a)
if g.owner == t then
call g.defenders.inspire()
endif
endif
call InspireUnitsAround()
set duration = 60.00
set enum = NewGroup()
set closestEnemy = null
set target = null
set lastTarget = null
set enemyHeroCount = 0
set channelingOrder = 0
set clock = NewTimerEx(this)
call SetUnitData(t.commander.heroUnit,"Commander_Inst",this)
call t.commander.commanderStand(false)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",t.commander.xOrigin,t.commander.yOrigin))
set landed = false
call SetUnitFlyHeight(t.commander.heroUnit,1000,0)
call Status.Add(STATUS_PAUSE,t.commander.heroUnit,0.75,0)
call Status.Add(STATUS_INVULNERABLE,t.commander.heroUnit,0.75,0)
call SetUnitX(t.commander.heroUnit,landX)
call SetUnitY(t.commander.heroUnit,landY)
set sfx = AddSpecialEffect(AREA_SFX,landX,landY)
call BlzSetSpecialEffectScale(sfx,2.0)
call DestroyEffect(sfx)
set sfx = null
call SetUnitFlyHeight(t.commander.heroUnit,0,4000)
call SetUnitAnimation(owner.commander.heroUnit,"spell")
set castTime = 1
set t.commander.assaultActive = true
set t.commander.commanderAssault = this
call TimerStart(clock,0.50,true,function thistype.Loop)
return this
endmethod
endstruct
private function onPreDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
local integer id = GetUnitTypeId(d.source)
local Buff b
if id == 'H00W' or id == 'H00T' then
set d.notCritical = true
endif
if d.dmgType != udg_DamageTypeHeal and d.dmgType != udg_DamageTypeHealOverTime then
if UnitHasBuff(d.target,RefineDefences.buff) then
set d.mult = d.mult - 0.90
endif
endif
if d.dmgType != udg_DamageTypeAttack and d.dmgType != udg_DamageTypeHeal and d.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(d.target,Inspire.buff)
if b != 0 then
set d.mult = d.mult - Inspire[b.buffAllocIndex].spellR
endif
endif
endfunction
private function onPostDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
local CommanderAssault c
local integer id = GetUnitTypeId(d.target)
local Team t
if id == 'H00W' or id == 'H00T' then
if GetUnitState(d.target,UNIT_STATE_LIFE) - d.damageMod < 0.41 then
call SetUnitState(d.target, UNIT_STATE_LIFE, GetUnitState(d.target, UNIT_STATE_MAX_LIFE))
set c = GetUnitData(d.target,"Commander_Inst")
if c != 0 then
call c.preDestroy(true)
endif
set d.damageMod = 0
set d.isAbsorbed = true
if c.owner == 1 then
call Message.Show(" has killed the enemy Commander ("+GOLD_COLOR+"+300|r)",MESSAGE_STYLE_ALLIANCE)
call AddTeamGold(2/c.owner,300)
else
call Message.Show(" has killed the enemy Commander ("+GOLD_COLOR+"+300|r)",MESSAGE_STYLE_HORDE)
call AddTeamGold(2/c.owner,300)
endif
endif
endif
endfunction
private function OnLeaveCombat takes nothing returns nothing
local unit u = GetEventCombatLeaveUnit()
local integer id = GetUnitTypeId(u)
local CommanderAssault c
if (id == 'H00W' or id == 'H00T') and GetEventCombatLeaveID() != -1 then
set c = GetUnitData(u,"Commander_Inst")
if c != 0 then
if ((c.enemyHeroCount == 0 and c.enemyUnitCount == 0) or GetEventCombatLeaveID() == -2) and not c.isBeingDestroyed then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\MassTeleport\\MassTeleportCaster.mdl",c.owner.commander.heroUnit,"origin"))
call SetUnitPosition(c.owner.commander.heroUnit,c.xTarget,c.yTarget)
call IssueImmediateOrderById(c.owner.commander.heroUnit,ORDER_stop)
call BlzSetUnitFacingEx(c.owner.commander.heroUnit,c.angle)
endif
endif
endif
set u = null
endfunction
public function Setup takes nothing returns nothing
call DamageEvent.RegisterPostCalculation(Filter(function onPostDamage))
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
call RegisterCombatEvent(function OnLeaveCombat,EVENT_UNIT_LEAVE_COMBAT)
endfunction
endscope
scope CommanderBuffs initializer init
struct Inspire extends array
integer armor
real spellR
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-armor,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set armor = 10 + (b.level / 5)
set spellR = 0.40 + 0.02 * (b.level / 5)
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A035'
set BUFF_DATA.BuffID = 'B01C'
set BUFF_DATA.Name = "Inspire"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct RefineWeapons extends array
private integer dmg
private integer as
private effect sfx
private boolean si
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call DestroyEffect(sfx)
set sfx = null
if si then
set si = false
call Status.Remove(STATUS_SPELL_IMMUNITY,b.target)
else
if GetUnitTypeId(b.target) == 'n009' then
call UnitRemoveAbility(b.target,'A09Z')
else
call UnitRemoveAbility(b.target,'A00H')
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 20 + 10 * b.level
set as = 20 + 5 * b.level
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
if IsUnitType(b.target,UNIT_TYPE_STRUCTURE) then
set sfx = AddSpecialEffect("war3mapImported\\MagicShieldRed1Big.mdx",GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectHeight(sfx,GetLocZ(GetUnitX(b.target),GetUnitY(b.target)) - 50)
call BlzSetSpecialEffectScale(sfx,3.2)
set si = false
if GetUnitTypeId(b.target) == 'n009' then
call UnitAddAbility(b.target,'A09Z')
else
call UnitAddAbility(b.target,'A00H')
endif
else
set sfx = AddSpecialEffectTarget("war3mapImported\\MagicShieldRed1.mdx",b.target,"origin")
set si = true
call Status.Add(STATUS_SPELL_IMMUNITY,b.target,0,0)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AH'
set BUFF_DATA.BuffID = 'B01H'
set BUFF_DATA.Name = "Refine Weapons"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct RefineDefences extends array
private effect sfx
private boolean si
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(sfx)
set sfx = null
if si then
set si = false
call Status.Remove(STATUS_SPELL_IMMUNITY,b.target)
else
if GetUnitTypeId(b.target) == 'n009' then
call UnitRemoveAbility(b.target,'A09Z')
else
call UnitRemoveAbility(b.target,'A00H')
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real hp
if IsUnitType(b.target,UNIT_TYPE_STRUCTURE) then
set hp = 200.00 + 100.00 * b.level
set sfx = AddSpecialEffect("war3mapImported\\MagicShieldYellowBig.mdx",GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectHeight(sfx,GetLocZ(GetUnitX(b.target),GetUnitY(b.target)) - 50)
call BlzSetSpecialEffectScale(sfx,3.2)
if GetUnitTypeId(b.target) == 'n009' then
call UnitAddAbility(b.target,'A09Z')
else
call UnitAddAbility(b.target,'A00H')
endif
set si = false
else
set hp = BlzGetUnitMaxHP(b.target) * 0.20 + (0.03 * b.level)
set sfx = AddSpecialEffectTarget("war3mapImported\\MagicShieldYellow.mdx",b.target,"origin")
set si = true
call Status.Add(STATUS_SPELL_IMMUNITY,b.target,0,0)
endif
call UnitAddHp(b.target,hp)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AI'
set BUFF_DATA.BuffID = 'B01I'
set BUFF_DATA.Name = "Refine Defences"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function init takes nothing returns nothing
call RefineWeapons.Initialize()
call RefineDefences.Initialize()
call Inspire.Initialize()
endfunction
endscope
scope CommanderAbilities
globals
private constant integer RD_ID = 'A099'
private constant integer RW_ID = 'A098'
private constant integer SW_ID = 'A02T'
private constant integer HS_ID = 'A0AB'
private constant string HEROIC_SFX1 = "war3mapImported\\RedAftershock.mdx"
private constant string HEROIC_SFX2 = "war3mapImported\\BlueAftershock.mdx"
endglobals
private function RefineWeaponsC takes nothing returns nothing
local unit u = GetTriggerUnit()
local Team t = GetPlayerTeamEx(GetTriggerPlayer())
local integer i = 0
local real cd = BlzGetUnitAbilityCooldownRemaining(t.warHall,'A0BK')
local unit temp
local Link h
call BlzStartUnitAbilityCooldown(u,RD_ID,120.00)
if cd == 0 then
call BlzStartUnitAbilityCooldown(t.warHall,'A0BK',10.00)
else
call BlzStartUnitAbilityCooldown(t.warHall,'A0BK',cd + 10.00)
endif
call SetUnitAnimation(u,"spell")
if t == 1 then
call Message.ShowToForce(t.forceP," activated "+"|c00fdfd00"+"Refine Weapons|r.",MESSAGE_STYLE_HORDE)
call StartSound(gg_snd_HordeWarCry)
else
call Message.ShowToForce(t.forceP," activated "+"|c00fdfd00"+"Refine Weapons|r.",MESSAGE_STYLE_ALLIANCE)
call StartSound(gg_snd_AllianceWarCry)
endif
loop
set i = i + 1
if Base[i].owner == t then
call UnitAddBuff(Base[i].tower,u,10.0,RefineWeapons.buff,Base[i].baseTroops.level,0)
endif
exitwhen i == 4
endloop
set i = 0
loop
set i = i + 1
if GoldMine[i].owner == t then
set h = GoldMine[i].defenders.units.head
loop
exitwhen h == 0
set temp = GetUnitByIndex(h.data)
call UnitAddBuff(temp,u,10.0,RefineWeapons.buff,Base[i].baseTroops.level,0)
set h = h.next
endloop
endif
exitwhen i == 4
endloop
set u = null
set temp = null
endfunction
private function RefineDefencesC takes nothing returns nothing
local unit u = GetTriggerUnit()
local Team t = GetPlayerTeamEx(GetTriggerPlayer())
local real cd = BlzGetUnitAbilityCooldownRemaining(t.warHall,'A0BK')
local integer i = 0
local unit temp
local Link h
call BlzStartUnitAbilityCooldown(u,RW_ID,120.00)
if cd == 0 then
call BlzStartUnitAbilityCooldown(t.warHall,'A0BK',10.00)
else
call BlzStartUnitAbilityCooldown(t.warHall,'A0BK',cd + 10.00)
endif
call SetUnitAnimation(u,"spell")
if t == 1 then
call Message.ShowToForce(t.forceP," Activated "+"|c00fdfd00"+"Refine Defences|r.",MESSAGE_STYLE_HORDE)
call StartSound(gg_snd_HordeWarCry)
else
call Message.ShowToForce(t.forceP," Activated "+"|c00fdfd00"+"Refine Defences|r.",MESSAGE_STYLE_ALLIANCE)
call StartSound(gg_snd_AllianceWarCry)
endif
loop
set i = i + 1
if Base[i].owner == t then
call UnitAddBuff(Base[i].tower,u,10.0,RefineDefences.buff,Base[i].baseTroops.level,0)
endif
exitwhen i == 4
endloop
set i = 0
loop
set i = i + 1
if GoldMine[i].owner == t then
set h = GoldMine[i].defenders.units.head
loop
exitwhen h == 0
set temp = GetUnitByIndex(h.data)
call UnitAddBuff(temp,u,10.0,RefineDefences.buff,Base[i].baseTroops.level,0)
set h = h.next
endloop
endif
exitwhen i == 4
endloop
set u = null
set temp = null
endfunction
struct ShockwaveMissile extends array
private static method onCollide takes Missile missile, unit hit returns boolean
if FILT_UNIT_ENEMY(hit,missile.owner) then
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypePure,"",0,0)
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real x, real y returns Missile
local real xu = GetUnitX(source)
local real yu = GetUnitY(source)
local real a = Angle(xu,yu,x,y)
local real d = 1100
local Missile missile
set x = xu + d * Cos(a)
set y = yu + d * Sin(a)
set missile = Missile.createXYZ(xu,yu,50.00,x,y,50.00)
set missile.source = source
set missile.collision = 150
set missile.owner = GetOwningPlayer(source)
set missile.damage = 150 + 5 * GameLoop.Minutes
set missile.speed = 20.00
set missile.model = "war3mapImported\\FireWave.mdx"
set missile.scale = 1.2
call ShockwaveMissile.launch(missile)
return missile
endfunction
private function Shockwave takes nothing returns nothing
call SetupMissile(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function HeroicStrikeCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real time = tb.real[3]
local real dmg
local unit temp
local real x
local real y
local player p
local Team te
local group g
local AoE aoe
local integer sw = 0
local effect sfx = null
if GetUnitCurrentOrder(u) == ORDER_stomp then
set time = time + 0.03125
set tb.real[3] = time
if time >= 1.3 then
set sw = 1
set x = tb.real[1]
set y = tb.real[2]
set p = GetOwningPlayer(u)
set te = GetPlayerTeamEx(p)
set g = NewGroup()
set dmg = 250 + 5.00 * GameLoop.Minutes
if te == 1 then
set sfx = AddSpecialEffect(HEROIC_SFX1,x,y)
else
set sfx = AddSpecialEffect(HEROIC_SFX2,x,y)
endif
call BlzSetSpecialEffectScale(sfx,1.2)
call DestroyEffect(sfx)
call GroupEnumUnitsInRange(g,x,y,250.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call KPJUnit.create(temp,0,0,0.80,400.00,KPJDefaultConfig2,KPJ_TYPE_JUMP)
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypePure,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
else
if time == 1.15 then
call SetUnitTimeScale(u,2.0)
endif
endif
else
set sw = 1
endif
if sw == 1 then
set aoe = tb.integer[5]
call aoe.destroy()
call DestroyEffect(tb.effect[4])
call SetUnitTimeScale(u,1.0)
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
endif
set t = null
endfunction
private function HeroicStrike takes nothing returns nothing
local unit u = GetTriggerUnit()
local Table tb = Table.create()
local Team t = GetUnitTeam(u)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local integer id = GetUnitTypeId(u)
local AoE aoe = AoE.create(x,y,null,250)
set tb.unit[0] = u
set tb.real[1] = x
set tb.real[2] = y
set tb.real[3] = 0.03125
set tb.effect[4] = AddSpecialEffectTarget("Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl",u,"weapon")
set tb.integer[5] = aoe
if id == 'H00T' then
call SetUnitAnimationByIndex(u,5)
call SetUnitTimeScale(u,0.30)
call BlzSetSpecialEffectColor(aoe.sfx,255,0,0)
elseif id == 'H00W' then
call SetUnitAnimationByIndex(u,8)
call SetUnitTimeScale(u,0.30)
call BlzSetSpecialEffectColor(aoe.sfx,0,0,255)
endif
call AIExtras_AILeaveZone.evaluate(2/t,x,y,250.0)
call TimerStart(NewTimerEx(tb),0.03125,true,function HeroicStrikeCallback)
set u = null
endfunction
public function Setup takes nothing returns nothing
call RegisterSpellEffectEvent(RW_ID, function RefineWeaponsC)
call RegisterSpellEffectEvent(RD_ID, function RefineDefencesC)
call RegisterSpellEffectEvent(SW_ID, function Shockwave)
call RegisterSpellEffectEvent(HS_ID, function HeroicStrike)
endfunction
endscope
library LineSegmentEnumeration /* v2.1a -- hiveworkshop.com/threads/line-segment-enumeration-v1-1.286552/
Information
¯¯¯¯¯¯¯¯¯¯¯
Allows to enumerate widgets inside a line segment with an offset.
So basicly it will result in a rect, but which is also allowed to be rotated.
Mechanics
¯¯¯¯¯¯¯¯¯
(Issue:)
The problem with normal jass rects is that they aren't defined by 4 points, but only by 4 values: x/y -min/max.
The result is that a jass rect is never rotated, so it's always paralel to the x/y axis.
But when we draw a line from point A to point B we might also create a non-axix-parelel rect, and then
we can't use the normal rect natives from jass anymore to find out if a point is inside the rect.
(Solution:)
To solve this problem the system does following:
jass rect: rectangular defined by 4 values (axis paralel)
custom rect: the real rectangular that is defined by user (not axis parelel)
1. Create a big jass rect that is big enough so we can ensure to enum all widgets that are potentialy inside our custom rect. (Enum_Group)
This Enum_Group will contain all wanted units, but may also contain not wanted units.
2. We rotate the custom rect around Point B, by angle "theta", so it gets now a normal, non-rotated rect. (axis parelel)
3. We loop through Enum_Group, and rotate all widget's coordinates also by the same "theta" value around Point B.
4. Now what happened is that the custom rect was manipulated so it got axis parelel. And we also used the same maths
to manipulate the x/y coordinate of our widgets, so the relation between the custom rect and the widget is still the very same.
But what we can do now is to use native jass logics to check if the widget is within the bounds of the rotated custom rect
with only comparing it's x/y coordinates with the rect's x/y -min/max coodinates.
Note: this approach is not the most performant one, but it doesn't work with custom types. So if you already work with for example
struct rects or other polygons, and you care for trigomnomig orientation you can write straight forward functions to check if a point
is inside a quadrilateral, as standalone function.
*/
// --- API ---
//! novjass
struct LineSegment
static method EnumUnits takes group whichgroup, real ax, real ay, real bx, real by, real offset returns nothing
static method EnumDestructables takes real ax, real ay, real bx, real by, real offset returns nothing
// after enumerated destructables you have access to:
static integer DestructableCounter // starts with index "0"
static destructable array Destructable
static method EnumItems takes real ax, real ay, real bx, real by, real offset returns nothing
// after enumerated items you have access to:
static integer ItemCounter // starts with index "0"
static destructable array Item
//! endnovjass
// ==== End API ====
struct LineSegment extends array
private static constant rect RECT = Rect(0, 0, 0, 0)
private static constant group GROUP = CreateGroup()
public static method EnumUnits takes group whichgroup, real ax, real ay, real bx, real by, real offset returns nothing
local real angle = Atan2(by - ay, bx - ax)
local real theta = ModuloReal(angle, bj_PI/2)
local real thetaSin
local real thetaCos
local unit u
local real x
local real y
local real x_new
local real y_new
local real maxX
local real maxY
local real minX
local real minY
local real x1
local real y1
local real x2
local real y2
local real x3
local real y3
local real x4
local real y4
// Enum all potential units
if ax > bx then
set maxX = ax + offset
set minX = bx - offset
else
set maxX = bx + offset
set minX = ax - offset
endif
if ay > by then
set maxY = ay + offset
set minY = by - offset
else
set maxY = by + offset
set minY = ay - offset
endif
call SetRect(RECT, minX, minY, maxX, maxY)
call GroupEnumUnitsInRect(GROUP, RECT, null)
// Create and rotate rect around point B, so it gets unrotated
set angle = angle - theta
set angle = angle*-1
set thetaSin = Sin(-theta)
set thetaCos = Cos(-theta)
set x_new = (ax-bx)*thetaCos - (ay-by)*thetaSin + bx
set y_new = (ax-bx)*thetaSin + (ay-by)*thetaCos + by
set x1 = x_new + offset*Cos(angle - bj_PI*0.5)
set y1 = y_new + offset*Sin(angle - bj_PI*0.5)
set x2 = x_new + offset*Cos(angle + bj_PI*0.5)
set y2 = y_new + offset*Sin(angle + bj_PI*0.5)
set x3 = bx + offset*Cos(angle - bj_PI*0.5)
set y3 = by + offset*Sin(angle - bj_PI*0.5)
set x4 = bx + offset*Cos(angle + bj_PI*0.5)
set y4 = by + offset*Sin(angle + bj_PI*0.5)
// define max/min values of the new non-rotated rect
if x1 > x2 then
set maxX = RMaxBJ(x1, x3)
set minX = RMinBJ(x2, x4)
else
set maxX = RMaxBJ(x2, x4)
set minX = RMinBJ(x1, x3)
endif
if y1 > y2 then
set maxY = RMaxBJ(y1, y3)
set minY = RMinBJ(y2, y4)
else
set maxY = RMaxBJ(y2, y4)
set minY = RMinBJ(y1, y3)
endif
// enum through all tracked units, rotate it around B, and check if it's inside bounds
call GroupClear(whichgroup)
loop
set u = FirstOfGroup(GROUP)
exitwhen u == null
set x = GetUnitX(u)
set y = GetUnitY(u)
set x_new = (x-bx)*thetaCos - (y-by)*thetaSin + bx
set y_new = (x-bx)*thetaSin + (y-by)*thetaCos + by
if x_new >= minX and x_new <= maxX and y_new >= minY and y_new <= maxY then
call GroupAddUnit(whichgroup, u)
endif
call GroupRemoveUnit(GROUP, u)
endloop
endmethod
//! textmacro LSE_WIDGET takes TYPE, NAME
private static integer $NAME$Counter_p = -1
private static $TYPE$ array $NAME$_p
public static integer $NAME$Counter = -1
public static $TYPE$ array $NAME$
private static method on$NAME$Filter takes nothing returns nothing
set $NAME$Counter_p = $NAME$Counter_p + 1
set $NAME$_p[$NAME$Counter_p] = GetEnum$NAME$()
endmethod
public static method Enum$NAME$s takes real ax, real ay, real bx, real by, real offset returns nothing
local real angle = Atan2(by - ay, bx - ax)
local real theta = ModuloReal(angle, bj_PI/2)
local real thetaSin
local real thetaCos
local $TYPE$ t
local real x
local real y
local real x_new
local real y_new
local real maxX
local real maxY
local real minX
local real minY
local real x1
local real y1
local real x2
local real y2
local real x3
local real y3
local real x4
local real y4
// Enum all potential widgets
if ax > bx then
set maxX = ax + offset
set minX = bx - offset
else
set maxX = bx + offset
set minX = ax - offset
endif
if ay > by then
set maxY = ay + offset
set minY = by - offset
else
set maxY = by + offset
set minY = ay - offset
endif
call SetRect(RECT, minX, minY, maxX, maxY)
set $NAME$Counter_p = -1
call Enum$NAME$sInRect(RECT, null, function thistype.on$NAME$Filter)
// Create and rotate rect around point B, so it gets unrotated
set angle = angle - theta
set angle = angle*-1
set thetaSin = Sin(-theta)
set thetaCos = Cos(-theta)
set x_new = (ax-bx)*thetaCos - (ay-by)*thetaSin + bx
set y_new = (ax-bx)*thetaSin + (ay-by)*thetaCos + by
set x1 = x_new + offset*Cos(angle - bj_PI*0.5)
set y1 = y_new + offset*Sin(angle - bj_PI*0.5)
set x2 = x_new + offset*Cos(angle + bj_PI*0.5)
set y2 = y_new + offset*Sin(angle + bj_PI*0.5)
set x3 = bx + offset*Cos(angle - bj_PI*0.5)
set y3 = by + offset*Sin(angle - bj_PI*0.5)
set x4 = bx + offset*Cos(angle + bj_PI*0.5)
set y4 = by + offset*Sin(angle + bj_PI*0.5)
// define max/min values of the new non-rotated rect
if x1 > x2 then
set maxX = RMaxBJ(x1, x3)
set minX = RMinBJ(x2, x4)
else
set maxX = RMaxBJ(x2, x4)
set minX = RMinBJ(x1, x3)
endif
if y1 > y2 then
set maxY = RMaxBJ(y1, y3)
set minY = RMinBJ(y2, y4)
else
set maxY = RMaxBJ(y2, y4)
set minY = RMinBJ(y1, y3)
endif
// enum through all tracked widgets, rotate it around B, and check if it's inside bounds
set $NAME$Counter = -1
loop
exitwhen $NAME$Counter_p < 0
set t = $NAME$_p[$NAME$Counter_p]
set x = Get$NAME$X(t)
set y = Get$NAME$Y(t)
set x_new = (x-bx)*thetaCos - (y-by)*thetaSin + bx
set y_new = (x-bx)*thetaSin + (y-by)*thetaCos + by
if x_new >= minX and x_new <= maxX and y_new >= minY and y_new <= maxY then
set $NAME$Counter = $NAME$Counter + 1
set $NAME$[$NAME$Counter] = t
endif
set $NAME$_p[$NAME$Counter_p] = null
set $NAME$Counter_p = $NAME$Counter_p - 1
endloop
endmethod
//! endtextmacro
//! runtextmacro LSE_WIDGET("destructable", "Destructable")
//! runtextmacro LSE_WIDGET("item", "Item")
endstruct
endlibrary
globals
//strange ones at bottom
constant integer ORDER_OFFSET=851970
constant integer ORDER_wandillusion=852274
constant integer ORDER_areadetection=852270
constant integer ORDER_eclipse=852621
constant integer ORDER_absorb=852529
constant integer ORDER_acidbomb=852662
constant integer ORDER_acolyteharvest=852185
constant integer ORDER_AImove=851988
constant integer ORDER_ambush=852131
constant integer ORDER_ancestralspirit=852490
constant integer ORDER_ancestralspirittarget=852491
constant integer ORDER_animatedead=852217
constant integer ORDER_antimagicshell=852186
constant integer ORDER_attack=851983
constant integer ORDER_attackground=851984
constant integer ORDER_attackonce=851985
constant integer ORDER_attributemodskill=852576
constant integer ORDER_auraunholy=852215
constant integer ORDER_auravampiric=852216
constant integer ORDER_autodispel=852132
constant integer ORDER_autodispeloff=852134
constant integer ORDER_autodispelon=852133
constant integer ORDER_autoentangle=852505
constant integer ORDER_autoentangleinstant=852506
constant integer ORDER_autoharvestgold=852021
constant integer ORDER_autoharvestlumber=852022
constant integer ORDER_avatar=852086
constant integer ORDER_avengerform=852531
constant integer ORDER_awaken=852466
constant integer ORDER_banish=852486
constant integer ORDER_barkskin=852135
constant integer ORDER_barkskinoff=852137
constant integer ORDER_barkskinon=852136
constant integer ORDER_battleroar=852599
constant integer ORDER_battlestations=852099
constant integer ORDER_bearform=852138
constant integer ORDER_berserk=852100
constant integer ORDER_blackarrow=852577
constant integer ORDER_blackarrowoff=852579
constant integer ORDER_blackarrowon=852578
constant integer ORDER_blight=852187
constant integer ORDER_blink=852525
constant integer ORDER_blizzard=852089
constant integer ORDER_bloodlust=852101
constant integer ORDER_bloodlustoff=852103
constant integer ORDER_bloodluston=852102
constant integer ORDER_board=852043
constant integer ORDER_breathoffire=852580
constant integer ORDER_breathoffrost=852560
constant integer ORDER_build=851994
constant integer ORDER_burrow=852533
constant integer ORDER_cannibalize=852188
constant integer ORDER_carrionscarabs=852551
constant integer ORDER_carrionscarabsinstant=852554
constant integer ORDER_carrionscarabsoff=852553
constant integer ORDER_carrionscarabson=852552
constant integer ORDER_carrionswarm=852218
constant integer ORDER_chainlightning=852119
constant integer ORDER_channel=852600
constant integer ORDER_charm=852581
constant integer ORDER_chemicalrage=852663
constant integer ORDER_cloudoffog=852473
constant integer ORDER_clusterrockets=852652
constant integer ORDER_coldarrows=852244
constant integer ORDER_coldarrowstarg=852243
constant integer ORDER_controlmagic=852474
constant integer ORDER_corporealform=852493
constant integer ORDER_corrosivebreath=852140
constant integer ORDER_coupleinstant=852508
constant integer ORDER_coupletarget=852507
constant integer ORDER_creepanimatedead=852246
constant integer ORDER_creepdevour=852247
constant integer ORDER_creepheal=852248
constant integer ORDER_creephealoff=852250
constant integer ORDER_creephealon=852249
constant integer ORDER_creepthunderbolt=852252
constant integer ORDER_creepthunderclap=852253
constant integer ORDER_cripple=852189
constant integer ORDER_curse=852190
constant integer ORDER_curseoff=852192
constant integer ORDER_curseon=852191
constant integer ORDER_cyclone=852144
constant integer ORDER_darkconversion=852228
constant integer ORDER_darkportal=852229
constant integer ORDER_darkritual=852219
constant integer ORDER_darksummoning=852220
constant integer ORDER_deathanddecay=852221
constant integer ORDER_deathcoil=852222
constant integer ORDER_deathpact=852223
constant integer ORDER_decouple=852509
constant integer ORDER_defend=852055
constant integer ORDER_detectaoe=852015
constant integer ORDER_detonate=852145
constant integer ORDER_devour=852104
constant integer ORDER_devourmagic=852536
constant integer ORDER_disassociate=852240
constant integer ORDER_disenchant=852495
constant integer ORDER_dismount=852470
constant integer ORDER_dispel=852057
constant integer ORDER_divineshield=852090
constant integer ORDER_doom=852583
constant integer ORDER_drain=852487
constant integer ORDER_dreadlordinferno=852224
constant integer ORDER_dropitem=852001
constant integer ORDER_drunkenhaze=852585
constant integer ORDER_earthquake=852121
constant integer ORDER_eattree=852146
constant integer ORDER_elementalfury=852586
constant integer ORDER_ensnare=852106
constant integer ORDER_ensnareoff=852108
constant integer ORDER_ensnareon=852107
constant integer ORDER_entangle=852147
constant integer ORDER_entangleinstant=852148
constant integer ORDER_entanglingroots=852171
constant integer ORDER_etherealform=852496
constant integer ORDER_evileye=852105
constant integer ORDER_faeriefire=852149
constant integer ORDER_faeriefireoff=852151
constant integer ORDER_faeriefireon=852150
constant integer ORDER_fanofknives=852526
constant integer ORDER_farsight=852122
constant integer ORDER_fingerofdeath=852230
constant integer ORDER_firebolt=852231
constant integer ORDER_flamestrike=852488
constant integer ORDER_flamingarrows=852174
constant integer ORDER_flamingarrowstarg=852173
constant integer ORDER_flamingattack=852540
constant integer ORDER_flamingattacktarg=852539
constant integer ORDER_flare=852060
constant integer ORDER_forceboard=852044
constant integer ORDER_forceofnature=852176
constant integer ORDER_forkedlightning=852586
constant integer ORDER_freezingbreath=852195
constant integer ORDER_frenzy=852561
constant integer ORDER_frenzyoff=852563
constant integer ORDER_frenzyon=852562
constant integer ORDER_frostarmor=852225
constant integer ORDER_frostarmoroff=852459
constant integer ORDER_frostarmoron=852458
constant integer ORDER_frostnova=852226
constant integer ORDER_getitem=851981
constant integer ORDER_gold2lumber=852233
constant integer ORDER_grabtree=852511
constant integer ORDER_harvest=852018
constant integer ORDER_heal=852063
constant integer ORDER_healingspray=852664
constant integer ORDER_healingward=852109
constant integer ORDER_healingwave=852501
constant integer ORDER_healoff=852065
constant integer ORDER_healon=852064
constant integer ORDER_hex=852502
constant integer ORDER_holdposition=851993
constant integer ORDER_holybolt=852092
constant integer ORDER_howlofterror=852588
constant integer ORDER_humanbuild=851995
constant integer ORDER_immolation=852177
constant integer ORDER_impale=852555
constant integer ORDER_incineratearrow=852670
constant integer ORDER_incineratearrowoff=852672
constant integer ORDER_incineratearrowon=852671
constant integer ORDER_inferno=852232
constant integer ORDER_innerfire=852066
constant integer ORDER_innerfireoff=852068
constant integer ORDER_innerfireon=852067
constant integer ORDER_instant=852200
constant integer ORDER_invisibility=852069
constant integer ORDER_lavamonster=852667
constant integer ORDER_lightningshield=852110
constant integer ORDER_load=852046
constant integer ORDER_loadarcher = 852142
constant integer ORDER_loadcorpse=852050
constant integer ORDER_loadcorpseinstant=852053
constant integer ORDER_locustswarm=852556
constant integer ORDER_lumber2gold=852234
constant integer ORDER_magicdefense=852478
constant integer ORDER_magicleash=852480
constant integer ORDER_magicundefense=852479
constant integer ORDER_manaburn=852179
constant integer ORDER_manaflareoff=852513
constant integer ORDER_manaflareon=852512
constant integer ORDER_manashieldoff=852590
constant integer ORDER_manashieldon=852589
constant integer ORDER_massteleport=852093
constant integer ORDER_mechanicalcritter=852564
constant integer ORDER_metamorphosis=852180
constant integer ORDER_militia=852072
constant integer ORDER_militiaconvert=852071
constant integer ORDER_militiaoff=852073
constant integer ORDER_militiaunconvert=852651
constant integer ORDER_mindrot=852565
constant integer ORDER_mirrorimage=852123
constant integer ORDER_monsoon=852591
constant integer ORDER_mount=852469
constant integer ORDER_mounthippogryph=852143
constant integer ORDER_move=851986
constant integer ORDER_nagabuild=852467
constant integer ORDER_neutraldetectaoe=852023
constant integer ORDER_neutralinteract=852566
constant integer ORDER_neutralspell=852630
constant integer ORDER_nightelfbuild=851997
constant integer ORDER_orcbuild=851996
constant integer ORDER_parasite=852601
constant integer ORDER_parasiteoff=852603
constant integer ORDER_parasiteon=852602
constant integer ORDER_patrol=851990
constant integer ORDER_phaseshift=852514
constant integer ORDER_phaseshiftinstant=852517
constant integer ORDER_phaseshiftoff=852516
constant integer ORDER_phaseshifton=852515
constant integer ORDER_phoenixfire=852481
constant integer ORDER_phoenixmorph=852482
constant integer ORDER_poisonarrows=852255
constant integer ORDER_poisonarrowstarg=852254
constant integer ORDER_polymorph=852074
constant integer ORDER_possession=852196
constant integer ORDER_preservation=852568
constant integer ORDER_purge=852111
constant integer ORDER_rainofchaos=852237
constant integer ORDER_rainoffire=852238
constant integer ORDER_raisedead=852197
constant integer ORDER_raisedeadoff=852199
constant integer ORDER_raisedeadon=852198
constant integer ORDER_ravenform=852155
constant integer ORDER_recharge=852157
constant integer ORDER_rechargeoff=852159
constant integer ORDER_rechargeon=852158
constant integer ORDER_rejuvination=852160
constant integer ORDER_renew=852161
constant integer ORDER_renewoff=852163
constant integer ORDER_renewon=852162
constant integer ORDER_repair=852024
constant integer ORDER_repairoff=852026
constant integer ORDER_repairon=852025
constant integer ORDER_replenish=852542
constant integer ORDER_replenishlife=852545
constant integer ORDER_replenishlifeoff=852547
constant integer ORDER_replenishlifeon=852546
constant integer ORDER_replenishmana=852548
constant integer ORDER_replenishmanaoff=852550
constant integer ORDER_replenishmanaon=852549
constant integer ORDER_replenishoff=852544
constant integer ORDER_replenishon=852543
constant integer ORDER_request_hero=852239
constant integer ORDER_requestsacrifice=852201
constant integer ORDER_restoration=852202
constant integer ORDER_restorationoff=852204
constant integer ORDER_restorationon=852203
constant integer ORDER_resumebuild=851999
constant integer ORDER_resumeharvesting=852017
constant integer ORDER_resurrection=852094
constant integer ORDER_returnresources=852020
constant integer ORDER_revenge=852241
constant integer ORDER_revive=852039
constant integer ORDER_roar=852164
constant integer ORDER_robogoblin=852656
constant integer ORDER_root=852165
constant integer ORDER_sacrifice=852205
constant integer ORDER_sanctuary=852569
constant integer ORDER_scout=852181
constant integer ORDER_selfdestruct=852040
constant integer ORDER_selfdestructoff=852042
constant integer ORDER_selfdestructon=852041
constant integer ORDER_sentinel=852182
constant integer ORDER_setrally=851980
constant integer ORDER_shadowsight=852570
constant integer ORDER_shadowstrike=852527
constant integer ORDER_shockwave=852125
constant integer ORDER_silence=852592
constant integer ORDER_sleep=852227
constant integer ORDER_slow=852075
constant integer ORDER_slowoff=852077
constant integer ORDER_slowon=852076
constant integer ORDER_smart=851971
constant integer ORDER_soulburn=852668
constant integer ORDER_soulpreservation=852242
constant integer ORDER_spellshield=852571
constant integer ORDER_spellshieldaoe=852572
constant integer ORDER_spellsteal=852483
constant integer ORDER_spellstealoff=852485
constant integer ORDER_spellstealon=852484
constant integer ORDER_spies=852235
constant integer ORDER_spiritlink=852499
constant integer ORDER_spiritofvengeance=852528
constant integer ORDER_spirittroll=852573
constant integer ORDER_spiritwolf=852126
constant integer ORDER_stampede=852593
constant integer ORDER_standdown=852113
constant integer ORDER_starfall=852183
constant integer ORDER_stasistrap=852114
constant integer ORDER_steal=852574
constant integer ORDER_stomp=852127
constant integer ORDER_stoneform=852206
constant integer ORDER_stop=851972
constant integer ORDER_submerge=852604
constant integer ORDER_summonfactory=852658
constant integer ORDER_summongrizzly=852594
constant integer ORDER_summonphoenix=852489
constant integer ORDER_summonquillbeast=852595
constant integer ORDER_summonwareagle=852596
constant integer ORDER_tankdroppilot=852079
constant integer ORDER_tankloadpilot=852080
constant integer ORDER_tankpilot=852081
constant integer ORDER_taunt=852520
constant integer ORDER_thunderbolt=852095
constant integer ORDER_thunderclap=852096
constant integer ORDER_tornado=852597
constant integer ORDER_townbelloff=852083
constant integer ORDER_townbellon=852082
constant integer ORDER_tranquility=852184
constant integer ORDER_transmute=852665
constant integer ORDER_unavatar=852087
constant integer ORDER_unavengerform=852532
constant integer ORDER_unbearform=852139
constant integer ORDER_unburrow=852534
constant integer ORDER_uncoldarrows=852245
constant integer ORDER_uncorporealform=852494
constant integer ORDER_undeadbuild=851998
constant integer ORDER_undefend=852056
constant integer ORDER_undivineshield=852091
constant integer ORDER_unetherealform=852497
constant integer ORDER_unflamingarrows=852175
constant integer ORDER_unflamingattack=852541
constant integer ORDER_unholyfrenzy=852209
constant integer ORDER_unimmolation=852178
constant integer ORDER_unload=852047
constant integer ORDER_unloadall=852048
constant integer ORDER_unloadallcorpses=852054
constant integer ORDER_unloadallinstant=852049
constant integer ORDER_unpoisonarrows=852256
constant integer ORDER_unravenform=852156
constant integer ORDER_unrobogoblin=852657
constant integer ORDER_unroot=852166
constant integer ORDER_unstableconcoction=852500
constant integer ORDER_unstoneform=852207
constant integer ORDER_unsubmerge=852605
constant integer ORDER_unsummon=852210
constant integer ORDER_unwindwalk=852130
constant integer ORDER_vengeance=852521
constant integer ORDER_vengeanceinstant=852524
constant integer ORDER_vengeanceoff=852523
constant integer ORDER_vengeanceon=852522
constant integer ORDER_volcano=852669
constant integer ORDER_voodoo=852503
constant integer ORDER_ward=852504
constant integer ORDER_waterelemental=852097
constant integer ORDER_wateryminion=852598
constant integer ORDER_web=852211
constant integer ORDER_weboff=852213
constant integer ORDER_webon=852212
constant integer ORDER_whirlwind=852128
constant integer ORDER_windwalk=852129
constant integer ORDER_wispharvest=852214
constant integer ORDER_scrollofspeed=852285
constant integer ORDER_cancel=851976
constant integer ORDER_moveslot1=852002
constant integer ORDER_moveslot2=852003
constant integer ORDER_moveslot3=852004
constant integer ORDER_moveslot4=852005
constant integer ORDER_moveslot5=852006
constant integer ORDER_moveslot6=852007
constant integer ORDER_useslot1=852008
constant integer ORDER_useslot2=852009
constant integer ORDER_useslot3=852010
constant integer ORDER_useslot4=852011
constant integer ORDER_useslot5=852012
constant integer ORDER_useslot6=852013
constant integer ORDER_skillmenu=852000
constant integer ORDER_stunned=851973
constant integer ORDER_instant1=851991 //?
constant integer ORDER_instant2=851987 //?
constant integer ORDER_instant3=851975 //?
constant integer ORDER_instant4=852019 //?
endglobals
library UnitRecycler /* v1.3b
|=============|
| Author: AGD |
|=============|
*/requires /*
*/ReviveUnit /* http://www.hiveworkshop.com/threads/snippet-reviveunit.186696/
*/optional Table /* http://www.hiveworkshop.com/threads/snippet-new-table.188084/
*/optional TimerUtilsEx /* http://www.wc3c.net/showthread.php?t=101322
*/optional RegisterPlayerUnitEvent /* http://www.hiveworkshop.com/threads/snippet-registerevent-pack.250266/
This system is important because CreateUnit() is one of the most processor-intensive function in
the game and there are reports that even after they are removed, they still leave some bit of memory
consumption (0.04 KB) on the RAM. Therefore it would be very helpful if you can minimize unit
creation or so. This system also allows you to recycle dead units to avoid permanent 0.04 KB memory
leak for each future CreateUnit() call. */
//! novjass
[Credits]
Aniki - For suggesting ideas on further improvements
|-----|
| API |
|-----|
function GetRecycledUnit takes player owner, integer rawCode, real x, real y, real facing returns unit/*
- Returns unit of specified ID from the stock of recycled units. If there's none in the stock that
matched the specified unit's rawcode, it will create a new unit instead
- Returns null if the rawcode's unit-type is a hero or non-existent
*/function GetRecycledUnitEx takes player owner, integer rawCode, real x, real y, real facing returns unit/*
- Works similar to GetRecycledUnit() except that if the input rawcode's unit-type is a hero, it will
be created via CreateUnit() instead
- You can use this as an alternative to CreateUnit()
*/function RecycleUnit takes unit u returns boolean/*
- Recycles the specified unit and returns a boolean value depending on the success of the operation
- Does nothing to hero units
*/function RecycleUnitEx takes unit u returns boolean/*
- Works similar to RecycleUnit() except that if <u> is not recyclable, it will be removed via
RemoveUnit() instead
- You can use this as an alternative to RemoveUnit()
*/function RecycleUnitDelayed takes unit u, real delay returns nothing/*
- Recycles the specified unit after <delay> seconds
*/function RecycleUnitDelayedEx takes unit u, real delay returns nothing/*
- Works similar to RecycleUnitDelayed() except that it calls RecycleUnitEx() instead of RecycleUnit()
*/function UnitAddToStock takes integer rawCode returns boolean/*
- Creates a unit of type ID and adds it to the stock of recycled units then returns a boolean value
depending on the success of the operation
*///! endnovjass
//CONFIGURATION SECTION
globals
/* The owner of the stocked/recycled units
*/ private constant player OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
/* Determines if dead units will be automatically recycled
after a delay designated by the <constant function
DeathTime below>
*/ private constant boolean AUTO_RECYCLE_DEAD = true
/* Error debug message prefix
*/ private constant string ERROR_PREFIX = "|CFFFF0000Operation Failed: "
endglobals
/* The delay before dead units will be recycled in case AUTO_RECYCLE_DEAD == true */
static if AUTO_RECYCLE_DEAD then
private constant function DeathTime takes unit u returns real
/*if <condition> then
return someValue
elseif <condition> then
return someValue
endif */
return 8.00
endfunction
endif
/* When recycling a unit back to the stock, these resets will be applied to the
unit. You can add more actions to this or you can delete this textmacro if you
don't need it. */
//END OF CONFIGURATION
/*==== Do not do changes below this line if you're not so sure on what you're doing ====*/
native UnitAlive takes unit u returns boolean
globals
private keyword S
private integer count = 0
private real unitCampX
private real unitCampY
private integer array stack
private boolean array stacked
endglobals
private function GetIndex takes integer rawCode returns integer
static if LIBRARY_Table then
local integer i = S.table.integer[rawCode]
if i == 0 then
set count = count + 1
set S.table.integer[rawCode] = count
set i = count
endif
else
local integer i = LoadInteger(S.hash, -1, rawCode)
if i == 0 then
set count = count + 1
call SaveInteger(S.hash, -1, rawCode, count)
set i = count
endif
endif
return i
endfunction
static if DEBUG_MODE then
private function Debug takes string msg returns nothing
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "|CFFFFCC00[Unit Recycler]|R " + msg)
endfunction
endif
function GetRecycledUnit takes player owner, integer rawCode, real x, real y, real facing returns unit
local integer i
if not IsHeroUnitId(rawCode) then
set i = GetIndex(rawCode)
if stack[i] == 0 then
set bj_lastCreatedUnit = CreateUnit(owner, rawCode, x, y, facing)
debug call Debug(GetUnitName(bj_lastCreatedUnit) + " stock is empty, creating new " + GetUnitName(bj_lastCreatedUnit))
else
static if LIBRARY_Table then
set bj_lastCreatedUnit = S.hash[i].unit[stack[i]]
else
set bj_lastCreatedUnit = LoadUnitHandle(S.hash, i, stack[i])
endif
set stacked[GetUnitUserData(bj_lastCreatedUnit)] = false
//call PauseUnit(bj_lastCreatedUnit, false)
call ShowUnit(bj_lastCreatedUnit,true)
call UnitIgnoreAlarm(bj_lastCreatedUnit,false)
call SetUnitOwner(bj_lastCreatedUnit, owner, true)
call SetUnitPosition(bj_lastCreatedUnit, x, y)
call SetUnitFacing(bj_lastCreatedUnit, facing)
set stack[i] = stack[i] - 1
debug call Debug("Retrieving " + GetUnitName(bj_lastCreatedUnit) + " from stock")
endif
debug if bj_lastCreatedUnit == null then
debug call Debug(ERROR_PREFIX + "Specified unit-type does not exist")
debug endif
else
debug call Debug(ERROR_PREFIX + "Attemp to retrieve a hero unit")
return null
endif
return bj_lastCreatedUnit
endfunction
function GetRecycledUnitEx takes player owner, integer rawCode, real x, real y, real facing returns unit
if not IsHeroUnitId(rawCode) then
return GetRecycledUnit(owner, rawCode, x, y, facing)
endif
debug call Debug("Cannot retrieve a hero unit, creating new unit")
return CreateUnit(owner, rawCode, x, y, facing)
endfunction
function RecycleUnit takes unit u returns boolean
local integer rawCode = GetUnitTypeId(u)
local integer uDex = GetUnitUserData(u)
local integer i
if not IsHeroUnitId(rawCode) and not stacked[uDex] and u != null then
set i = GetIndex(rawCode)
if not UnitAlive(u) and not ReviveUnit(u) then
debug call Debug(ERROR_PREFIX + "Unable to recycle unit: Unable to revive dead unit")
return false
endif
set stacked[uDex] = true
//call PauseUnit(u, true)
call UnitRemoveAllBuffs(u)
call flushUnitData(u)
call BonusStruct.ResetAll(u,uDex)
call UnitIgnoreAlarm(u,true)
call ShowUnit(u,false)
call SetUnitOwner(u, OWNER, true)
call SetUnitX(u, unitCampX)
call SetUnitY(u, unitCampY)
call SetUnitFacing(u, 270)
call SetWidgetLife(u, GetUnitState(u, UNIT_STATE_MAX_LIFE))
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA))
set stack[i] = stack[i] + 1
static if LIBRARY_Table then
set S.hash[i].unit[stack[i]] = u
else
call SaveUnitHandle(S.hash, i, stack[i], u)
endif
debug call Debug("Successfully recycled " + GetUnitName(u))
return true
debug else
debug if stacked[uDex] then
debug call Debug(ERROR_PREFIX + "Attempt to recycle an already recycled unit")
debug elseif u == null then
debug call Debug(ERROR_PREFIX + "Attempt to recycle a null unit")
debug else
debug call Debug(ERROR_PREFIX + "Attempt to recycle a hero unit")
debug endif
endif
return false
endfunction
function RecycleUnitEx takes unit u returns boolean
if not RecycleUnit(u) then
call RemoveUnit(u)
debug call Debug("Cannot recycle the specified unit, removing unit")
return false
endif
return true
endfunction
//! textmacro DELAYED_RECYCLE_TYPE takes EX
private function RecycleTimer$EX$ takes nothing returns nothing
local timer t = GetExpiredTimer()
static if LIBRARY_TimerUtilsEx then
call RecycleUnit$EX$(Index[GetTimerData(t)].u)
call ReleaseTimer(t)
else
local integer key = GetHandleId(t)
static if LIBRARY_Table then
call RecycleUnit$EX$(S.hash[0].unit[key])
call S.hash[0].remove(key)
else
call RecycleUnit$EX$(LoadUnitHandle(S.hash, 0, key))
call RemoveSavedHandle(S.hash, 0, key)
endif
call DestroyTimer(t)
endif
set t = null
endfunction
function RecycleUnitDelayed$EX$ takes unit u, real delay returns nothing
static if LIBRARY_TimerUtilsEx then
call TimerStart(NewTimerEx(GetUnitUserData(u)), delay, false, function RecycleTimer$EX$)
else
local timer t = CreateTimer()
static if LIBRARY_Table then
set S.hash[0].unit[GetHandleId(t)] = u
else
call SaveUnitHandle(S.hash, 0, GetHandleId(t), u)
endif
call TimerStart(t, delay, false, function RecycleTimer$EX$)
set t = null
endif
endfunction
//! endtextmacro
//! runtextmacro DELAYED_RECYCLE_TYPE("")
//! runtextmacro DELAYED_RECYCLE_TYPE("Ex")
function UnitAddToStock takes integer rawCode returns boolean
local unit u
local integer i
if not IsHeroUnitId(rawCode) then
set u = CreateUnit(OWNER, rawCode, unitCampX, unitCampY, 270)
if u != null then
set i = GetIndex(rawCode)
call SetUnitX(u, unitCampX)
call SetUnitY(u, unitCampY)
//call PauseUnit(u, true)
call ShowUnit(u,false)
set stacked[GetUnitUserData(u)] = true
set stack[i] = stack[i] + 1
static if LIBRARY_Table then
set S.hash[i].unit[stack[i]] = u
else
call SaveUnitHandle(S.hash, i, stack[i], u)
endif
debug call Debug("Adding " + GetUnitName(u) + " to stock")
return true
debug else
debug call Debug(ERROR_PREFIX + "Attemp to stock a null unit")
endif
set u = null
debug else
debug call Debug(ERROR_PREFIX + "Attemp to stock a hero unit")
endif
return false
endfunction
static if AUTO_RECYCLE_DEAD then
private function OnDeath takes nothing returns nothing
local unit u = GetTriggerUnit()
if not IsUnitType(u, UNIT_TYPE_HERO) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitType(u, UNIT_TYPE_SUMMONED) and not IsUnitIllusion(u) and GetUnitAbilityLevel(u,'A07B') == 0 then
call RecycleUnitDelayed(u, DeathTime(u))
endif
set u = null
endfunction
endif
private module Init
static if LIBRARY_Table then
static TableArray hash
static Table table
else
static hashtable hash = InitHashtable()
endif
private static method onInit takes nothing returns nothing
local rect bounds = GetWorldBounds()
static if AUTO_RECYCLE_DEAD then
static if LIBRARY_RegisterPlayerUnitEvent then
static if RPUE_VERSION_NEW then
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function OnDeath)
else
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function OnDeath)
endif
else
local trigger t = CreateTrigger()
local code c = function OnDeath
local integer i = 16
loop
set i = i - 1
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_DEATH, null)
exitwhen i == 0
endloop
call TriggerAddCondition(t, Filter(c))
set t = null
endif
endif
static if LIBRARY_Table then
set hash = TableArray[0x2000]
set table = Table.create()
endif
// Hides recycled units at the top of the map beyond reach of the camera
set unitCampX = 6528
set unitCampY = -6907
call RemoveRect(bounds)
set bounds = null
endmethod
endmodule
private struct S extends array
implement Init
endstruct
endlibrary
library FieldOfView
//*********************************************************************
//* =================================
//* FieldOfView 1.0.3 (by MoCo)
//* =================================
//*
//* This library provides 2 functions:
//*
//* - IsUnitInSightOfUnit(unit observer, unit target, real fieldOfView)
//* Checks if unit 'target' is within the field of view cone of unit 'observer'
//*
//* - IsUnitBehindUnit(unit unitToCheck, unit target, real fieldOfView)
//* Checks if unit 'unitToCheck' is behind unit 'target' within fieldOfView
//*
//*
//* Setup:
//* ======
//* Copy this library to your map.
//*
//*
//* Usage:
//* ======
//* Use the parameter fieldOfView to set the field of view (FoV) that should be used for the detection function.
//* The parameter needs to be set to half of the total field of view you want the unit to use.
//* For example, if you want a unit to have a total field of view cone of 180°, you need to use a parameter value of 90
//*
//* Note that the natural human field of view is about 135°, so you could use a value of 67.5 here.
//*
//* See the FovTester script for practical examples on how to use the functions.
//*
//*
//********************************************************************
function IsPointInSightOfAngle takes real face, real xo, real yo, real xt, real yt, real fov returns boolean
local real angle = bj_RADTODEG*Atan2(yt - yo, xt - xo)
return not (RAbsBJ(face - angle) > fov and RAbsBJ(face - angle - 360.) > fov)
endfunction
function IsPointInSightOfUnit takes unit observer, real xt, real yt, real fov returns boolean
local real face = GetUnitFacing(observer)
local real angle = bj_RADTODEG*Atan2(yt - GetUnitY(observer), xt - GetUnitX(observer))
return not (RAbsBJ(face - angle) > fov and RAbsBJ(face - angle - 360.) > fov)
endfunction
function IsUnitInSightOfUnit takes unit observer, unit target, real fov returns boolean
local real face = GetUnitFacing(observer)
local real angle = bj_RADTODEG*Atan2(GetUnitY(target) - GetUnitY(observer), GetUnitX(target) - GetUnitX(observer))
return not (RAbsBJ(face - angle) > fov and RAbsBJ(face - angle - 360.) > fov)
endfunction
function IsUnitBehindUnit takes unit unitToCheck, unit target, real fov returns boolean
local real face = GetUnitFacing(target)
local real angle = bj_RADTODEG*Atan2(GetUnitY(target) - GetUnitY(unitToCheck), GetUnitX(target) - GetUnitX(unitToCheck))
return not (RAbsBJ(face - angle) > fov and RAbsBJ(face - angle - 360.) > fov)
endfunction
endlibrary
library RapidSound requires optional TimerUtils
globals
// Actually, just leave this value
private constant real MIN_DELAY_FACTOR = 4.0
endglobals
/* v1.6
Description
¯¯¯¯¯¯¯¯¯¯¯
Allows you to play sounds rapidly and flawlessly without limit.
Remember one sound file can only have one RSound instance.
External Dependencies
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
(Optional)
TimerUtils by Vexorian
wc3c.net/showthread.php?t=101322
User API
¯¯¯¯¯¯¯¯
struct RSound
Instantiate an RapidSound instance
| static method create takes string fileName, boolean is3D, boolean autoStop, integer inRate, integer outRate returns thistype
autoStop => stop when sound is out of range
inRate => fade in rate
outRate => fade out rate
Play the sound at given coordinate
| method play takes real x, real y, real z, integer volume returns nothing
Stop sound
| method stop takes boolean fadeOut returns nothing
Destroy RapidSound instance
| method kill takes nothing returns nothing
Sound file duration (in second)
| method operator duration takes nothing returns real
Resource Link
¯¯¯¯¯¯¯¯¯¯¯¯¯
hiveworkshop.com/threads/snippet-rapidsound.258991/
*/
struct RSound
private static constant integer MAX_COUNT = 4
private static integer Counter = -1
private static string array StrLib
private static thistype array StrDex
private integer ct
private integer lib
private integer dex
private real dur
private sound array snd[thistype.MAX_COUNT]
private timer array tmr[thistype.MAX_COUNT]
method operator duration takes nothing returns real
return .dur*MIN_DELAY_FACTOR
endmethod
method kill takes nothing returns nothing
local integer i
set .ct = .ct - 1
if .ct == 0 then
set i = 0
loop
exitwhen i == MAX_COUNT
call StopSound(.snd[i], true, false)
static if LIBRARY_TimerUtils then
call ReleaseTimer(.tmr[i])
else
call DestroyTimer(.tmr[i])
endif
set .snd[i] = null
set .tmr[i] = null
set i = i + 1
endloop
set StrLib[.lib] = StrLib[Counter]
set StrDex[.lib] = StrDex[Counter]
set Counter = Counter - 1
call deallocate()
endif
endmethod
method stop takes boolean fadeOut returns nothing
local integer i = 0
loop
exitwhen i == MAX_COUNT
call StopSound(.snd[i], false, fadeOut)
set i = i + 1
endloop
endmethod
method playForTeam takes real x, real y, real z, integer volume, Team t returns nothing
set .dex = .dex + 1
if .dex == MAX_COUNT then
set .dex = 0
endif
if TimerGetRemaining(.tmr[.dex]) == 0 then
call StopSound(.snd[.dex], false, false)
call SetSoundPosition(.snd[.dex], x, y, z)
call SetSoundDistanceCutoff(.snd[.dex], 1600)
call SetSoundVolume(.snd[.dex], 0)
if IsPlayerInForce(Game.LocalPlayer,t.forceP) then
call SetSoundVolume(.snd[.dex], volume)
endif
call StartSound(.snd[.dex])
call TimerStart(.tmr[.dex], .dur, false, null)
endif
endmethod
method playForPlayer takes real x, real y, real z, integer volume, player p returns nothing
set .dex = .dex + 1
if .dex == MAX_COUNT then
set .dex = 0
endif
if TimerGetRemaining(.tmr[.dex]) == 0 then
call StopSound(.snd[.dex], false, false)
call SetSoundPosition(.snd[.dex], x, y, z)
call SetSoundDistanceCutoff(.snd[.dex], 1600)
call SetSoundVolume(.snd[.dex], 0)
if Game.LocalPlayer == p then
call SetSoundVolume(.snd[.dex], volume)
endif
call StartSound(.snd[.dex])
call TimerStart(.tmr[.dex], .dur, false, null)
endif
endmethod
method play takes real x, real y, real z, integer volume returns nothing
set .dex = .dex + 1
if .dex == MAX_COUNT then
set .dex = 0
endif
if TimerGetRemaining(.tmr[.dex]) == 0 then
call StopSound(.snd[.dex], false, false)
call SetSoundPosition(.snd[.dex], x, y, z)
call SetSoundVolume(.snd[.dex], volume)
call SetSoundDistanceCutoff(.snd[.dex], 1600)
call StartSound(.snd[.dex])
call TimerStart(.tmr[.dex], .dur, false, null)
endif
endmethod
static method create takes string fileName, boolean is3D, boolean autoStop, integer inRate, integer outRate returns thistype
local thistype this
local integer i = 0
local boolean b = true
loop
exitwhen i > Counter
if fileName == StrLib[i] then
set b = false
exitwhen true
endif
set i = i + 1
endloop
if b then
set this = allocate()
set Counter = Counter + 1
set StrLib[Counter] = fileName
set StrDex[Counter] = this
set .ct = 1
set .dex = -1
set .lib = Counter
set .dur = I2R(GetSoundFileDuration(fileName))/(1000.*MIN_DELAY_FACTOR)
set i = 0
loop
exitwhen i == MAX_COUNT
set .snd[i] = CreateSound(fileName, false, is3D, autoStop, inRate, outRate, "")
static if LIBRARY_TimerUtils then
set .tmr[i] = NewTimer()
call TimerStart(.tmr[i], 0, false, null)
call PauseTimer(.tmr[i])
else
set .tmr[i] = CreateTimer()
endif
set i = i + 1
endloop
else
set this = StrDex[i]
set .ct = .ct + 1
endif
return this
endmethod
endstruct
endlibrary
library IsUnitMoving requires UnitIndex, Event
//===========================================================================
// IsUnitMoving
// ============ Created by Xiliger with some script improvements by Bribe
//
//
// This library provides a helpful function that can be used to detect when
// a unit is moving.
//
// API:
//
// function IsUnitMoving takes unit u returns boolean
// function GetMovingUnit takes nothing returns unit
// function GetMovingUnitId takes nothing returns integer
//
// Struct API:
//
// static constant Event MOVE
// > Fires when a unit starts moving.
//
// static constant Event STOP
// > Fires when a unit stops moving.
//
// readonly boolean moving
// > Quick-check if a unit is moving.
//
// readonly boolean allocated
// > Was the unit allocated in the first place?
//
// readonly real x
// > Unit's last-checked x
//
// readonly real y
// > Unit's last-checked y
//
// Requires either:
// UnitIndexer: hiveworkshop.com/forums/showthread.php?t=172090
// or:
// AIDS: thehelper.net/forums/showthread.php?t=130752
// Event: thehelper.net/forums/showthread.php?t=126846
//
// Thanks to Jesus4Lyf for the extremely efficient Timer32 linked-list model
// and to Nestharus for ideas that give IsUnitMoving more power.
//
globals
//-----------------------------------------------------------------------
// Time between coordinate scans. You should increase it if you have move-
// ment-oriented spells/systems with slower timers.
//
private constant real TIMEOUT = 0.03125
private UnitMoving get = 0 // Reference
endglobals
//***************************************************************************
//*
//* Users' API
//*
//***************************************************************************
//===========================================================================
// Returns true when a unit is moving via orders or triggered actions, false
// if the unit is not moving.
//
function IsUnitMoving takes unit u returns boolean
return UnitMoving(GetUnitUserData(u)).moving
endfunction
// Use within a registered event-response to get the moving or stopping unit.
function GetMovingUnit takes nothing returns unit
return GetUnitByIndex(get)
endfunction
function GetMovingUnitId takes nothing returns UnitMoving
return get
endfunction
//***************************************************************************
//*
//* System Struct
//*
//***************************************************************************
struct UnitMoving extends array
static Event MOVE = 0
static Event STOP = 0
readonly real x
readonly real y
readonly boolean moving
readonly boolean allocated
readonly thistype next
readonly thistype prev
public static method index takes nothing returns boolean
local Index i = INDEX_EVENT
local unit ut = i.u
local thistype u = i
if 0 != GetUnitAbilityLevel(ut, 'Amov') then
set thistype(0).next.prev = u
set u.next = thistype(0).next
set thistype(0).next = u
set u.x = GetUnitX(ut)
set u.y = GetUnitY(ut)
set u.allocated = true
endif
set ut = null
return false
endmethod
public static method deindex takes nothing returns boolean
local Index i = INDEX_EVENT
local thistype u = i
if u.allocated then
set u.moving = false
set u.allocated = false
set u.prev.next = u.next
set u.next.prev = u.prev
set u.prev = 0
endif
return false
endmethod
public static method scan takes nothing returns nothing
local thistype u = thistype(0).next
local unit ut
local real x
local real y
loop
exitwhen 0 == u
set ut = GetUnitByIndex(u)
set x = GetUnitX(ut)
set y = GetUnitY(ut)
if x != u.x or y != u.y then
set u.x = x
set u.y = y
if not u.moving then
// The unit was stopped but is now moving.
set u.moving = true
set get = u
call thistype.MOVE.fire()
endif
elseif u.moving then
// The unit was moving but is now stopped.
set u.moving = false
set get = u
call thistype.STOP.fire()
endif
set u = u.next
endloop
set ut = null
endmethod
endstruct
public function Setup takes nothing returns nothing
set UnitMoving.MOVE = Event.create()
set UnitMoving.STOP = Event.create()
call RegisterOnIndexEvent(function UnitMoving.index)
call RegisterOnDeIndexEvent(function UnitMoving.deindex)
call TimerStart(CreateTimer(), TIMEOUT, true, function UnitMoving.scan)
endfunction
endlibrary
library MissileRecycler initializer PreInit requires optional UnitIndexer, optional UnitDex, optional UnitIndexerGUI /*
MissileRecycler v 1.4.0.1
=========================================================================
Credits:
-------------------------------------------------------------------------
Written by Bribe
Vexorian, Anitarf and iNfraNe for the dummy.mdx model file
Nestharus for the Queue data structure and for finding that paused units
consume very few CPU resources.
=========================================================================
Introduction:
-------------------------------------------------------------------------
Recycling dummy units is important because the CreateUnit call is one of,
if not the, most processor-intensive native in the entire game. Creating
just a couple dozen dummy units in a single thread causes a visible frame
glitch for that instant. The overhead is even higher if you are using a
Unit Indexing library in the map which causes some extra evaluations per
new unit.
There are also reports of removed units leaving a little trail of RAM
surplus in their wake. I have not been able to reproduce this so I don't
know how serious it is.
I was motivated to create this system because removed units might be un-
safe in very large numbers and CreateUnit is a very heavy process.
The thing that makes this system different than others is the fact that
it considers the facing angle of the dummies being recycled, which I have
never seen another system even attempt before this. Since then,
MissileRecycler has inspired Anitarf to update XE with the same angle-retaining
capability and Nestharus has created Dummy. Considering the facing angle is
important because it takes 0.73 seconds for the unit to turn around,
which - when overlooked - looks especially weird if you are creating a unit-trail
or if you are shooting arrow-shaped objects as projectiles. For fireball effects or
effects that generally don't depend on facing angle, this system would be
a bit wasteful.
With default settings and the worst-case-scenario, it will take 0.09 seconds for
the projectile to turn to the angle you need. This is 1/8 of the normal worst case
scenario if you weren't recycling dummies considering facing. On average, it takes
roughly 0.045 seconds to turn to the angle you need (which is not noticable).
However, I have made this completely configurable and you are
able to change the values to whatever needs you have.
=========================================================================
Calibration Guide:
-------------------------------------------------------------------------
The thing that surprised me the most about this system was, no matter how
complex it turned out, it became very configurable. So I should let you
know what the constants do so you know if/how much you want to modify.
constant real DEATH_TIME = 2.0 //seconds
- Should not be less than the maximum time a death animation needs to play.
Should not be lower than .73 to ensure enough time to turn.
Should not be too high otherwise the dummies will take too long to recycle.
constant integer ANG_N = 8
- How many different angles are recognized by the system. Don't do
360 different angles because then you're going to have thousands of dummy
units stored and that's ridiculous, the game lags enough at 1000 units.
Increasing ANG_N increases realism but decreases the chance that a dummy
unit will be available to be recycled. I don't recommend making this any
lower, and the max I'd recommend would be 16.
constant integer ANG_STORAGE_MAX = 12
- How many dummy units are stored per angle. This limit is important
because you might have a spike at one point in the game where many units
are created, which could result in too high of a dummy population.
In general, I advise that the product of ANG_N x ANG_STORAGE_MAX does
not exceed 100 or 200. More than that is excessive, but you can
hypothetically have it up to 8190 if Warcraft 3's memory management
were better.
Preloads ANG_N x ANG_STORAGE_MAX dummy units. Preloading dummies is
useful as it dumps a lot of CreateUnit calls in initialization where you
won't see a frame glitch. In the 1.4 update, preloading is done 0 seconds
into the game to ensure any Indexers have already initialized.
private function ToggleIndexer takes boolean flag returns nothing
- Put what you need in here to disable/enable any indexer in your
map. if flag is true, enable indexer. If false, disable.
=========================================================================
API Guide:
-------------------------------------------------------------------------
You obviously need some functions so you can get a recycled dummy unit or
recycle it. Therefore I provide these:
function GetRecycledMissile
takes real x, real y, real z, real facing
returns unit
Returns a new dummy unit that acts as a projectile missile. The args
are simply the last three arguments you'd use for a CreateUnit call,
with the addition of a z parameter to represent the flying height -
it isn't the absolute z but relative to the ground because it uses
SetUnitFlyHeight on that value directly.
function RecycleMissile
takes unit u
returns nothing
When you are done with that dummy unit, recycle it via this function.
This function is pretty intelligent and resets that unit's animation
and its facing angle so you don't have to.
*/
//=======================================================================
// Save the map, then delete the exclaimation mark in the following line.
// Make sure that you don't have an object in your map with the rawcode
// 'dumi' and also configure the model path (war3mapImported\dummy.mdl)
// to the dummy.mdx model created by Vexorian.
///! external ObjectMerger w3u ewsp dumi unam "Missile Dummy" ubui "" uhom 1 ucol 0.01 umvt "None" umvr 1.00 utar "" uspa "" umdl "war3mapImported\dummy.mdl" umxr 0.00 umxp 0.00 ushr 0 uerd 0.00 udtm 0.00 ucbs 0.00 uble 0.00 uabi "Aloc,Amrf"
//Thanks to Vexorian that Optimizer 5.0 no longer kills natives
native UnitAlive takes unit id returns boolean
globals
//-------------------------------------------------------------------
// You must configure the dummy unit with the one created from the
// ObjectMerger statement above.
//
private constant integer DUMMY_ID = 'dumi' //The rawcode of the dummy unit.
private player OWNER = Player(15) //The owner of the dummy unit.
private constant integer ANG_N = 10 //# of indexed angles. Higher value increases realism but decreases recycle frequency.
private constant integer ANG_STORAGE_MAX = 5 //Max dummies per indexed angle. I recommend lowering this if you increase ANG_N.
private constant real DEATH_TIME = 2. //Allow the special effect on
//the unit to complete its "death" animation in this timeframe. Must
//be higher than 0.74 seconds to allow the unit time to turn. This
//number should not be lower than the maximum death-animation time of
//your missile-units' effect attachments, just to be safe.
endglobals
private function ToggleIndexer takes boolean flag returns nothing
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = flag
elseif LIBRARY_UnitIndexerGUI then
set udg_UnitIndexerEnabled = flag
elseif LIBRARY_UnitDex then
set UnitDex.Enabled = flag
endif
endfunction
globals
private constant integer ANG_VAL = 360 / ANG_N //Generate angle value from ANG_N.
private constant integer ANG_MID = ANG_VAL / 2 //The middle value of angle value.
//Misc vars
private unit array stack //Recycled dummy units.
private real array timeStamp //Prevents early recycling of units.
private integer array queueNext
private integer array queueLast
private integer recycle = 0
private timer gameTime = CreateTimer() //Used for visual continuity.
private integer array queueStack
private integer queueStackN = 0 //Used to avoid searching the queues.
endglobals
static if DEBUG_MODE then
private function Print takes string s returns nothing
//Un-comment this next line if you want to know how the system works:
//call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 999, "[MissileRecycler] " + s)
endfunction
endif
//=======================================================================
// Get a recycled dummy missile unit. If there are no recycled dummies
// that are already facing the angle you need, it creates a new dummy for
// you.
//
function GetRecycledMissile takes real x, real y, real z, real facing returns unit
local integer i = ModuloInteger(R2I(facing), 360) / ANG_VAL
local integer this = queueNext[i]
local unit u
if this != 0 and TimerGetElapsed(gameTime) >= timeStamp[this] then
//Dequeue this
set queueNext[i] = queueNext[this]
if queueNext[i] == 0 then
set queueLast[i] = i
endif
//Recycle this index
set queueLast[this] = recycle
set recycle = this
//Add queue index to available stack
set queueStack[queueStackN] = i
set queueStackN = queueStackN + 1
//Old unit will return as new
set u = stack[this]
call BlzSetUnitFacingEx(u, facing)
call SetUnitUserData(u, 0)
//Reset the dummy's properties.
call SetUnitVertexColor(u, 255, 255, 255, 255)
call SetUnitAnimationByIndex(u, 90)
call SetUnitScale(u, 1, 0, 0)
//call PauseUnit(u, false) -- you can disable "resets" that you don't need to worry about.
debug call Print("Recycling")
else
debug call Print("Creating new")
call ToggleIndexer(false)
set u = CreateUnit(OWNER, DUMMY_ID, x, y, facing)
call ToggleIndexer(true)
//call PauseUnit(u, true)
endif
call SetUnitX(u, x)
call SetUnitY(u, y)
call SetUnitFlyHeight(u, z, 0)
set bj_lastCreatedUnit = u
set u = null
return bj_lastCreatedUnit
endfunction
//=======================================================================
// You should recycle the dummy missile unit when its job is done.
//
function RecycleMissile takes unit u returns nothing
local integer i
local integer this = recycle
if GetUnitTypeId(u) == DUMMY_ID and UnitAlive(u) and GetUnitUserData(u) != -1 then
if queueStackN == 0 then
debug call Print("Stack is full - removing surplus unit")
call UnitApplyTimedLife(u, 'BTLF', DEATH_TIME)
return
endif
//Recycle this
set recycle = queueLast[this]
//Index the dummy unit to an available facing angle.
//Get the last vacant angle index.
set queueStackN = queueStackN - 1
set i = queueStack[queueStackN]
//Enqueue this
set queueNext[queueLast[i]] = this
set queueLast[i] = this
set queueNext[this] = 0
//Allow a time barrier for the effect to destroy/turn to complete.
set timeStamp[this] = TimerGetElapsed(gameTime) + DEATH_TIME
set stack[this] = u
call SetUnitFacing(u, i * ANG_VAL + ANG_MID)
//Prevent double-free of this unit.
call SetUnitUserData(u, -1)
debug else
debug call BJDebugMsg("[MissileRecycler] Error: Attempt to recycle invalid unit.")
endif
endfunction
//=======================================================================
// I didn't need this function after all
//
function RecycleMissileDelayed takes unit u, real r returns nothing
call RecycleMissile(u)
endfunction
//=======================================================================
// Map the dummy units to their facing angles (map below is if ANG_N is
// 4 and ANG_STORAGE_MAX is 3).
//
// angle[0] (0) - [4] [5] [6]
// angle[1] (90) - [7] [8] [9]
// angle[2] (180) - [10][11][12]
// angle[3] (270) - [13][14][15]
//
private function Init takes nothing returns nothing
local integer end
local integer i = ANG_N
local integer n = i
local integer angle
local real x = 6528
local real y = -6907
local unit u
call ToggleIndexer(false)
loop
set i = i - 1
set queueNext[i] = n
set angle = i * ANG_VAL + ANG_MID
set end = n + ANG_STORAGE_MAX
set queueLast[i] = end - 1
loop
set queueNext[n] = n + 1
set u = CreateUnit(OWNER, DUMMY_ID, x, y, angle)
set stack[n] = u
call PauseUnit(u, true)
call SetUnitUserData(u, -1)
set n = n + 1
exitwhen n == end
endloop
set queueNext[n - 1] = 0
exitwhen i == 0
endloop
call ToggleIndexer(true)
call TimerStart(gameTime, 1000000., false, null)
set u = null
endfunction
private function PreInit takes nothing returns nothing
static if LIBRARY_UnitIndexerGUI then
call OnUnitIndexerInitialized(function Init)
else
call Init()
endif
endfunction
endlibrary
library Missile /* version 2.5.1
*************************************************************************************
*
* Creating custom projectiles in Warcraft III.
*
* Major goal:
* No unessary external requirements.
* Implements code optional.
*
* Philosophy:
* I want that feature --> Compiler writes that code into your map script.
* I don't want that --> Compiler ignores that code completly.
*
* Important:
* Take yourself 2 minutes time to setup Missile correctly.
* Otherwise I can't guarantee, that Missile works the way you want.
* Once the setup is done, you can check out some examples and Missile will be easy
* to use for everyone. I promise it.
*
* Do the setup at:
*
* 1.) Import instruction
* 2.) Global configuration
* 3.) Function configuration
*
* Credits to Dirac, emjlr3, AceHart, Bribe, Wietlol,
* Nestharus, Maghteridon96, Vexorian and Zwiebelchen.
*
*************************************************************************************
*
* */ requires /*
*
* - Missile requires nothing.
*
*************************************************************************************
*
* Optional requirements listed can reduce overall code generation,
* add safety mechanisms, decrease overhead and optimize handle management.
* For a better overview I put them into blocks.
*
* I recommend to use at least one per block in your map.
*
* a) For best debug results: ( Useful )
* */ optional ErrorMessage /* github.com/nestharus/JASS/tree/master/jass/Systems/ErrorMessage
*
* b) Fatal error protection: ( Case: unit out moves of world bounds )
* - WorldBounds is safer than BoundSentinel.
* - WorldBounds adds more overhead than BoundSentinel.
* - Using none of these two forces Missile to switch from SetUnitX/Y to the SetUnitPosition native.
* */ optional WorldBounds /* githubusercontent.com/nestharus/JASS/master/jass/Systems/WorldBounds/script.j
* */ optional BoundSentinel /* wc3c.net/showthread.php?t=102576
*
* c) Handle recycling: ( Performace gain, memory management )
* - uses MissileRecylcer > Dummy > xedummy.
* */ optional MissileRecycler /* hiveworkshop.com/forums/jass-resources-412/system-missilerecycler-206086/
* */ optional Dummy /* github.com/nestharus/JASS/blob/master/jass/Systems/Dummy/Dummy.w3x
* */ optional xedummy /* wc3c.net/showthread.php?t=101150
*
* d) Unit indexing: ( Avoid an onIndex event )
* - not required for Missile. Only if you use one already.
* */ optional UnitIndexer /* github.com/nestharus/JASS/tree/master/jass/Systems/Unit%20Indexer
*
************************************************************************************
*
* 1. Import instruction
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* • Copy Missile into to your map.
* • You need a dummy unit, using Vexorians "dummy.mdx".
* This unit must use the locust and crow form ability. ( Aloc & Amrf )
* ¯¯¯¯
*
* 2. Global configuration
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Seven constants to setup!
*/
globals
/**
* Missiles are moved periodically. An interval of 1./32. is recommended.
* • Too short timeout intervals may cause performance issues.
* • Too large timeout intervals may look fishy.
*/
public constant real TIMER_TIMEOUT = 1./32.
/**
* Owner of all Missile dummies. Should be a neutral player in your map.
*/
public constant player NEUTRAL_PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
/**
* Raw code of the dummy unit. Object Editor ( F6 )
* • Must be correct, otherwise missile dummies can neither be recycled nor destroyed.
* • Units of other type ids will not be thrown into the recycler bin.
*/
public constant integer DUMMY_UNIT_ID = 'dumi'
/**
* The maximum collision size used in your map. If unsure use 197. ( Town hall collision )
* • Applies for all types of widgets.
* • A precise value can improve Missile's performance,
* since smaller values enumerate less widgtes per loop per missile.
*/
public constant real MAXIMUM_COLLISION_SIZE = 45.
/**
* Collision types for missiles. ( Documentation only )
* Missile decides internally each loop which type of collision is required.
* • Uses circular collision dectection for speed < collision. ( Good accuracy, best performance )
* • Uses rectangle collision for speed >= collision. ( Best accuracy, normal performance )
*/
public constant integer COLLISION_TYPE_CIRCLE = 0
public constant integer COLLISION_TYPE_RECTANGLE = 1
/**
* Determine when rectangle collision is required to detect nearby widgets.
* • The smaller the factor the earlier rectangle collision is used. ( by default 1. )
* • Formula: speed >= collision*Missile_COLLISION_ACCURACY_FACTOR
*/
public constant real COLLISION_ACCURACY_FACTOR = 1.
// Optional toogles:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Set booleans listed below to "true" and the compiler will write
// the feature into your map. Otherwise this code is completly ignored.
// • Yay, I want that --> "true"
// • Naah that's useless for me --> "false"
/**
* USE_COLLISION_Z_FILTER enables z axis checks for widget collision. ( Adds minimal overhead )
* Use it when you need:
* • Missiles flying over or under widgets.
* • Determine between flying and walking units.
*/
public constant boolean USE_COLLISION_Z_FILTER = false
/**
* WRITE_DELAYED_MISSILE_RECYCLING enables a delayed dummy recycling system. ( Very recommended )
* Use it if:
* • You use a dummy recycling library like MissileRecycler, Dummy or xedummy.
* • You want to properly display death animations of effects added to missiles.
*/
public constant boolean WRITE_DELAYED_MISSILE_RECYCLING = true
/**
* DELAYED_MISSILE_DEATH_ANIMATION_TIME is the delay in seconds
* Missile holds back a dummy, before recycling it.
* • The time value does not have to be precise.
* • Requires WRITE_DELAYED_MISSILE_RECYCLING = true
*/
private constant real DELAYED_MISSILE_DEATH_ANIMATION_TIME = 2.
/**
* USE_DESTRUCTABLE_FILTER and USE_ITEM_FILTER are redundant constants from previous Missile versions.
* They do nothing, but remain for backwards compatibilty.
* From Missile version 1.5 on all widget collisions are always enabled.
*/
public constant boolean USE_DESTRUCTABLE_FILTER = true
public constant boolean USE_ITEM_FILTER = true
endglobals
/*
* 3. Function configuration
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Four functions to setup!
*/
/**
* GetUnitBodySize(unit) returns a fictional value for z - axis collision.
* You have two options:
* • One constant value shared over all units.
* • Dynamic values based on handle id, type id, unit user data, scaling or other parameters.
*/
function GetUnitBodySize takes unit whichUnit returns real
return 100.// Other example: return LoadReal(hash, GetHandleId(whichUnit), KEY_UNIT_BODY_SIZE)
endfunction
/**
* Same as GetUnitBodySize, but for destructables.
* Using occluder height is an idea of mine. Of course you can use your own values.
*/
function GetDestructableHeight takes destructable d returns real
return GetDestructableOccluderHeight(d)// Other example: return 100.
endfunction
/**
* Same as GetUnitBodySize, but for items.
* Again it's up to you to figure out a fictional item height.
*/
function GetItemHeight takes item i returns real
return 16.
endfunction
/**
* Unit indexers and missiles ( Only if you don't use a dummy recycling library )
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* It is most likely intended that projectiles don't run through a unit indexing process.
* ToogleUnitIndexer runs:
* • Directly before a dummy is created.
* • Directly after dummy unit creation.
*
* Please return the previous setup of your indexing tool ( enabled, disabled ),
* so Missile can properly reset it to the original state.
*/
private function ToogleUnitIndexer takes boolean enable returns boolean
local boolean prev = true//UnitIndexer.enabled
// set UnitIndexer.enabled = enable
return prev
endfunction
/**
* 4. API
* ¯¯¯¯¯¯
*/
//! novjass ( Disables the compiler until the next endnovjass )
// Custom type Missile for your projectile needs.
struct Missile extends array
// Constants:
// ==========
//
readonly static constant string ORIGIN = "origin"
// • Attach point name for fxs on dummies.
readonly static constant real HIT_BOX = (2./3.)
// • Fictional hit box for homing missiles.
// while 0 would be the toe and 1 the head of a unit.
// Available creators:
// ===================
//
static method createEx takes unit missileDummy, real impactX, real impactY, real impactZ returns Missile
// • Core creator method.
// • May launches any unit.
// • Units of type Missile_DUMMY_UNIT_ID get recycled in the end.
static method create takes real x, real y, real z, real angleInRadians, real distanceToTravel, real endZ returns Missile
// • Converts arguments to fit into createEx, then calls createEx.
static method createXYZ takes real x, real y, real z, real impactX, real impactY, real impactZ returns Missile
// • Converts arguments to fit into createEx, then calls createEx.
// Available destructors:
// ======================
//
return true
// • Core destructor.
// • Returning true in any of the interface methods of the MissileStruct module
// will destroy that instance instantly.
method destroy takes nothing returns nothing
// • Destroys the missile during the next timer callback.
method terminate takes nothing returns nothing
// • Destroys the missile instantly.
// Fields you can set and read directly:
// =====================================
//
unit source
unit target // For homing missiles.
real distance // Distance traveled.
player owner // Pseudo owner for faster onCollide evaluation. The proper dummy owner remains PLAYER_NEUTRAL_PASSIVE.
real speed // Vector lenght for missile movement in plane x / y. ( DOES NOT TAKE THE TIMER TIMEOUT IN ACCOUNT )
real acceleration
real damage
real turn // Set a turn rate for missiles.
integer data // For data transfer set and read data.
boolean recycle // Is automatically set to true, when a Missile reaches it's destination.
boolean wantDestroy // Set wantDestroy to true, to destroy a missile during the next timer callback.
// Neither collision nor collisionZ accept values below zero.
real collision // Collision size in plane x / y.
real collisionZ // Collision size in z - axis. ( deprecated )
// Fields you can only read:
// =========================
//
readonly boolean allocated
readonly unit dummy// The dummy unit of this missile.
// Position members for you needs.
readonly MissilePosition origin// Grants access to readonly members of MissilePosition,
readonly MissilePosition impact// which are "x", "y", "z", "angle", "distance", "slope" and the pitch angle "alpha".
// Furthermore method origin.move(x, y, z) and impact.move(x, y, z).
readonly real terrainZ
readonly real x
readonly real y
readonly real z
readonly real angle// Current angle in radians.
// Method operators for set and read:
// ==================================
//
method operator model= takes string modelFile returns nothing
method operator model takes nothing returns string
// • Adds an effect handle on a missile dummy to it's "origin".
// • You can read the file path.
// • For multiple effects access "this.dummy" in your struct.
method operator scale= takes real value returns nothing
method operator scale takes nothing returns real
// • Set and read the scaling of the dummy unit.
method operator curve= takes real value returns nothing
method operator curve takes nothing returns real
// • Enables curved movement for your missile. ( Pass in radians, NOT degrees )
// • Do not pass in PI/2.
method operator arc= takes real value returns nothing
method operator arc takes nothing returns real
// • Enables arcing movement for your missile. ( Pass in radians, NOT degrees )
// • Do not pass in PI/2.
// Methods for missile movement:
// =============================
//
method bounce takes nothing returns nothing
// • Moves the MissilePosition "origin" to the current missile coordinates.
// • Resets the distance traveled to 0.
method deflect takes real tx, real ty returns nothing
// • Deflect the missile towards tx, ty. Then calls bounce.
method deflectEx takes real tx, real ty, real tz returns nothing
// • Deflect the missile towards tx, ty, tz. Then calls bounce.
method flightTime2Speed takes real duration returns nothing
// • Converts a fly time to a vector lenght for member "speed".
// • Does not take acceleration into account. ( Disclaimer )
method setMovementSpeed takes real value returns nothing
// • Converts Warcraft III movement speed to a vector lenght for member "speed".
// Methods for missile collision: ( all are hashtable entries )
// ==============================
// By default a widget can only be hit once per missile.
//
method hitWidget takes widget w returns nothing
// • Saves a widget in the memory as hit by this instance.
method hasHitWidget takes widget w returns boolean
// • Returns true, if "w" has been hit by this instance.
method removeHitWidget takes widget w returns nothing
// • Removes a widget from this missile's memory for widget collision. ( Can hit "w" again )
method flushHitWidgets takes nothing returns nothing
// • Flushes a missile's memory for widget collision. ( All widgets can be hit again )
method enableHitAfter takes widget w, real seconds returns nothing
// • Automatically calls removeHitWidget(w) after "seconds" time. ( Can hit "w" again after given time )
// Module MissileStruct:
// =====================
//
module MissileLaunch // ( optional )
module MissileStruct
// • Enables the entire missile interface for that struct.
// Interface in structs: ( Must implement module MissileStruct )
// =====================
//
// • Write one, many or all of the static method below into your struct.
// • Missiles launched in this struct will run those methods, when their events fire.
//
// • All of those static methods must return a boolean.
// a) return true --> destroys the missile instance instantly.
// b) return false --> keep on flying.
// Available static method:
// ========================
//
static method onCollide takes Missile missile, unit hit returns boolean
// • Runs for units in collision range of a missile.
static method onDestructable takes Missile missile, destructable hit returns boolean
// • Runs for destructables in collision range of a missile.
static method onItem takes Missile missile, item hit returns boolean
// • Runs for items in collision range of a missile.
static method onTerrain takes Missile missile returns boolean
// • Runs when a missile collides with the terrain. ( Ground and cliffs )
static method onFinish takes Missile missile returns boolean
// • Runs only when a missile reaches it's destination.
// • However does not run, if a Missile is destroyed in another method.
static method onPeriod takes Missile missile returns boolean
// • Runs every Missile_TIMER_TIMEOUT seconds.
static method onRemove takes Missile missile returns boolean
// • Runs when a missile is destroyed.
// • Unlike onFinish, onRemove will runs ALWAYS when a missile is destroyed!!!
//
// For onRemove the returned boolean has a unique meaning:
// • Return true will recycle this missile delayed. ( Only if WRITE_DELAYED_MISSILE_RECYCLING = true )
// • Return false will recycle this missile right away.
static method launch takes Missile toLaunch returns nothing
// • Well ... Launches this Missile.
// • Missile "toLaunch" will behave as declared in the struct. ( static methods from above )
// Misc: ( From the global setup )
// =====
//
// Constants:
// ==========
//
public constant real TIMER_TIMEOUT
public constant player NEUTRAL_PASSIVE
public constant integer DUMMY_UNIT_ID
public constant real MAXIMUM_COLLISION_SIZE
public constant boolean USE_COLLISION_Z_FILTER
public constant boolean WRITE_DELAYED_MISSILE_RECYCLING
public constant boolean USE_DESTRUCTABLE_FILTER
public constant boolean USE_ITEM_FILTER
readonly static constant string ORIGIN
readonly static constant real HIT_BOX
// Functions:
// ==========
//
public function GetLocZ takes real x, real y returns real
function GetUnitBodySize takes unit whichUnit returns real
function GetDestructableHeight takes destructable d returns real
function GetItemHeight takes item i returns real
//========================================================================
// Missile system. Make changes carefully.
//========================================================================
//! endnovjass ( Enables the compiler )
// Hello and welcome to Missile.
// I wrote a guideline for every piece of code inside Missile, so you
// can easily understand how the it gets compiled and evaluated.
//
// Let's go!
globals
// Core constant handle variables of Missile.
private constant trigger CORE = CreateTrigger()
private constant trigger MOVE = CreateTrigger()
private constant timer TMR = CreateTimer()
private constant location LOC = Location(0., 0.)
private constant rect RECT = Rect(0., 0., 0., 0.)
private constant group GROUP = CreateGroup()
private constant hashtable HASH = InitHashtable()
// For starting and stopping the timer.
private integer active = 0
// Arrays for data structure.
private integer array instances
private Missile array missileList
private boolexpr array expression
private triggercondition array condition
private integer array remove
private boolean array destroying
private boolean array recycling
private integer array nextNode
private integer array prevNode
// Internal widget filter functions.
private boolexpr destFilter
private boolexpr itemFilter
private boolexpr unitFilter
endglobals
public function GetLocZ takes real x, real y returns real
call MoveLocation(LOC, x, y)
return GetLocationZ(LOC)
endfunction
// For WRITE_DELAYED_MISSILE_RECYCLING = true Missile will hold back
// dummies for DELAYED_MISSILE_DEATH_ANIMATION_TIME before they are recylced. ( Code placed in a static if )
//
//! runtextmacro optional WRITE_MISSILE_RECYCLE_BIN("WRITE_DELAYED_MISSILE_RECYCLING", "DELAYED_MISSILE_DEATH_ANIMATION_TIME")
// The code of WRITE_MISSILE_POSITION_CODE boxes a missiles position and does the required trigonometry.
//
//! runtextmacro WRITE_MISSILE_POSITION_CODE()
// Missiles structure works like a linked list with the folling methods:
// allocateCollection(), allocateNode(), insertFront(node) and remove()
//
private keyword MissileStructure
struct Missile extends array
implement MissileStructure
// Constants:
// ==========
//
// Attach point name for effects created by model=.
readonly static constant string ORIGIN = "origin"
// Set a ficitional hit box in range of 0 to 1,
// while 0 is the toe and 1 the head of a unit.
readonly static constant real HIT_BOX = (2./3.)
// DEBUG_MODE only members:
// ========================
//
// Checks for double launching. Throws an error message.
debug boolean launched
// Private members:
// ================
//
// The position of a missile using curve= does not
// match the position used by Missile's trigonometry.
// Therefore we need this member two times.
// Readable x / y / z for your needs and posX / posY for cool mathematics.
private real posX
private real posY
private real dist// distance
// Readonly members:
// =================
//
// Prevents a double free case.
readonly boolean allocated
// The dummy unit.
readonly unit dummy
// Position members for your needs.
readonly MissilePosition origin// Grants access to readonly members of MissilePosition,
readonly MissilePosition impact// which are "x", "y", "z", "angle", "distance", "slope" and "alpha".
readonly real terrainZ
readonly real x
readonly real y
readonly real z
readonly real angle// Current angle
readonly real prevX
readonly real prevY
readonly real prevZ
// Collision detection type. ( Evaluated new in each loop )
readonly integer collisionType// Current collision type ( circular or rectangle )
// Members you can set:
// ====================
//
unit source
unit target // For homing missiles.
real distance // Distance traveled.
player owner // Pseudo owner for faster onCollide evaluation. The proper dummy owner is PLAYER_NEUTRAL_PASSIVE.
real speed // Vector lenght for missile movement in plane x / y.
real acceleration
real damage
integer data // For data transfer set and read data.
integer level
boolean recycle // Is set to true, when a Missile reaches it's destination.
real turn // Sets a turn rate for a missile.
real collision // Collision size in plane x / y.
// Setting collision z is deprecated since Missile v2.5.
method operator collisionZ= takes real value returns nothing
endmethod
method operator collisionZ takes nothing returns real
return collision
endmethod
// Operator overloading:
// =====================
//
// Special effect on the missile dummy. For multiple effect attaching, access unit "dummy" directly.
private effect sfx
private string path
method operator model= takes string file returns nothing
if sfx != null then
call DestroyEffect(sfx)
set sfx = null
endif
// null and ""
if StringLength(file) > 0 then
set sfx = AddSpecialEffectTarget(file, dummy, ORIGIN)
set path = file
else
set path = null
endif
endmethod
method operator model takes nothing returns string
return path
endmethod
real open
// Enables curved movement for your missile.
// Remember that the result of Tan(PI/2) is infinity.
method operator curve= takes real value returns nothing
set open = Tan(value)*origin.distance
endmethod
method operator curve takes nothing returns real
return Atan(open/origin.distance)
endmethod
real height
// Enables arcing movement for your missile.
method operator arc= takes real value returns nothing
set height = Tan(value)*origin.distance/4
endmethod
method operator arc takes nothing returns real
return Atan(4*height/origin.distance)
endmethod
private real scaling
method operator scale= takes real value returns nothing
call SetUnitScale(dummy, value, 0., 0.)
set scaling = value
endmethod
method operator scale takes nothing returns real
return scaling
endmethod
// Methods:
// ========
//
method bounce takes nothing returns nothing
call origin.move(x, y, z)
set dist = 0.
endmethod
method deflect takes real tx, real ty returns nothing
local real a = 2.*Atan2(ty - y, tx - x) + bj_PI - angle
call impact.move(x + (origin.distance - dist)*Cos(a), y + (origin.distance - dist)*Sin(a), impact.z)
call bounce()
endmethod
method deflectEx takes real tx, real ty, real tz returns nothing
call impact.move(impact.x, impact.y, tz)
call deflect(tx, ty)
endmethod
method flightTime2Speed takes real duration returns nothing
set speed = RMaxBJ(0.00000001, (origin.distance - dist)*Missile_TIMER_TIMEOUT/RMaxBJ(0.00000001, duration))
endmethod
method setMovementSpeed takes real value returns nothing
set speed = value*Missile_TIMER_TIMEOUT
endmethod
boolean wantDestroy// For "true" a missile is destroyed on the next timer callback. 100% safe.
method destroy takes nothing returns nothing
set wantDestroy = true
endmethod
// Instantly destroys a missile.
method terminate takes nothing returns nothing
if allocated then
call remove()
call impact.destroy()
call origin.destroy()
call DestroyEffect(sfx)
call FlushChildHashtable(HASH, this)
if GetUnitTypeId(dummy) == Missile_DUMMY_UNIT_ID then
// MissileRecycler > Dummy > xe.
static if LIBRARY_MissileRecycler then
call RecycleMissile(dummy)
elseif LIBRARY_Dummy and Dummy.create.exists then
call Dummy[dummy].destroy()
elseif LIBRARY_xedummy and xedummy.release.exists then
call xedummy.release(dummy)
else
call RemoveUnit(dummy)
endif
endif
set sfx = null
set source = null
set target = null
set dummy = null
set owner = null
endif
endmethod
// Runs in createEx.
//! textmacro MISSILE_RESET_ALL_MEMBERS
set path = null
set speed = 0.
set acceleration = 0.
set distance = 0.
set damage = 0.
set dist = 0.
set height = 0.
set turn = 0.
set open = 0.
set collision = 0.
set collisionType = 0
set stackSize = 0
set scaling = 1.
set wantDestroy = false
set recycle = false
set data = 0
set level = 0
//! endtextmacro
// Launches a dummy of your choice.
static method createEx takes unit missileDummy, real impactX, real impactY, real impactZ returns thistype
local thistype this = thistype.allocateNode()
local real originX = GetUnitX(missileDummy)
local real originY = GetUnitY(missileDummy)
local real originZ = GetUnitFlyHeight(missileDummy)
//
//! runtextmacro MISSILE_RESET_ALL_MEMBERS()
//
set origin = MissilePosition.create(originX, originY, originZ)
set impact = MissilePosition.create(impactX, impactY, impactZ)
call MissilePosition.link(origin, impact)
set posX = originX
set posY = originY
set x = originX
set y = originY
set z = originZ
set angle = origin.angle
set dummy = missileDummy
call SetUnitFlyHeight(missileDummy, originZ, 0.)
call SaveUnitHandle(HASH, this, GetHandleId(missileDummy), missileDummy)
//
static if LIBRARY_ErrorMessage then
debug call ThrowWarning(GetUnitTypeId(missileDummy) == 0, "Missile", "createEx", "missileDummy", this, "Invalid missile dummy unit ( null )!")
endif
debug set launched = false
return this
endmethod
// Freaky static if ensures these libraries really don't exist.
static if not LIBRARY_MissileRecycler and not LIBRARY_Dummy and not Dummy.create.exists and not LIBRARY_xe_dummy and not xe_dummy.new.exists then
private static method newMissileUnit takes real x, real y, real z, real face returns unit
local boolean prev = ToogleUnitIndexer(false)
set bj_lastCreatedUnit = CreateUnit(Missile_NEUTRAL_PASSIVE, Missile_DUMMY_UNIT_ID , x, y, face)
call ToogleUnitIndexer(prev)
call SetUnitX(bj_lastCreatedUnit, x)
call SetUnitY(bj_lastCreatedUnit, y)
call UnitAddAbility(bj_lastCreatedUnit, 'Amrf')
call SetUnitFlyHeight(bj_lastCreatedUnit, z, 0.)
call PauseUnit(bj_lastCreatedUnit, true)
return bj_lastCreatedUnit
endmethod
endif
// MissileRecylcer > Dummy > xe > Missile.
//! textmacro MISSILE_GET_DUMMY_FROM_LIBRARY
static if LIBRARY_MissileRecycler then
return createEx(GetRecycledMissile(x, y, z, angle*bj_RADTODEG), impactX, impactY, impactZ)
elseif LIBRARY_Dummy and Dummy.create.exists then
local Dummy dummy = Dummy.create(x, y, angle*bj_RADTODEG)
call SetUnitFlyHeight(dummy.unit, z, 0.)
return createEx(dummy.unit, impactX, impactY, impactZ)
elseif LIBRARY_xedummy and xedummy.new.exists then
set bj_lastCreatedUnit = xedummy.new(Missile_NEUTRAL_PASSIVE, x, y, angle*bj_RADTODEG)
call SetUnitFlyHeight(bj_lastCreatedUnit, z, 0.)
return createEx(bj_lastCreatedUnit, impactX, impactY, impactZ)
else
return createEx(Missile.newMissileUnit(x, y, z, angle*bj_RADTODEG), impactX, impactY, impactZ)
endif
//! endtextmacro
// Wrapper to createEx.
static method create takes real x, real y, real z, real angle, real distance, real impactZ returns thistype
local real impactX = x + distance*Cos(angle)
local real impactY = y + distance*Sin(angle)
// Get the dummy unit.
//! runtextmacro MISSILE_GET_DUMMY_FROM_LIBRARY()
endmethod
// Wrapper to createEx.
static method createXYZ takes real x, real y, real z, real impactX, real impactY, real impactZ returns thistype
local real angle = Atan2(impactY - y, impactX - x)
// Get the dummy unit.
//! runtextmacro MISSILE_GET_DUMMY_FROM_LIBRARY()
endmethod
// Missile motion takes place every Missile_TIMER_TIMEOUT
// before accessing each active struct.
static Missile temp = 0
static method move takes nothing returns boolean
local integer loops = 0 // Current iteration.
local integer limit = 150 // Set iteration border per trigger evaluation to avoid hitting the operation limit.
local thistype this = thistype.temp
local MissilePosition p
local real a
local real d
local unit u
local real newX
local real newY
local real vel
local real point
local real pitch
loop
exitwhen 0 == this or loops == limit
set p = origin
// Save previous, respectively current missile position.
set prevX = x
set prevY = y
set prevZ = z
// Evaluate the collision type.
set vel = speed
set speed = vel + acceleration
if vel < collision*Missile_COLLISION_ACCURACY_FACTOR then
set collisionType = Missile_COLLISION_TYPE_CIRCLE
else
set collisionType = Missile_COLLISION_TYPE_RECTANGLE
endif
// Update missile guidance to its intended target.
set u = target
if u != null then
if 0 == GetUnitTypeId(u) then
set target = null
else
call origin.move(x, y, z)
call impact.move(GetUnitX(u), GetUnitY(u), GetUnitFlyHeight(u) + GetUnitBodySize(u)*Missile.HIT_BOX)
set dist = 0
set height = 0
set curve = 0
endif
endif
set a = p.angle
// Update the missile facing angle depending on the turn ratio.
if 0. != turn and Cos(angle - a) < Cos(turn) then
if 0. > Sin(a - angle) then
set angle = angle - turn
else
set angle = angle + turn
endif
else
set angle = a
endif
// Update the missile position on the parabola.
set d = p.distance// origin - impact distance.
set recycle = dist + vel >= d
if recycle then// Maximum distance reached.
set point = d
set distance = distance + d - dist
else
set distance = distance + vel
set point = dist + vel
endif
set dist = point
set newX = posX + vel*Cos(angle)
set newY = posY + vel*Sin(angle)
set posX = newX
set posY = newY
// Update point(x/y) if a curving trajectory is defined.
set u = dummy
if 0. != open and target == null then
set vel = 4*open*point*(d - point)/p.square
set a = angle + bj_PI/2
set newX = newX + vel*Cos(a)
set newY = newY + vel*Sin(a)
set a = angle + Atan(-((4*open)*(2*point - d))/p.square)
else
set a = angle
endif
set x = newX
set y = newY
// Update pos z if an arc or height is set.
call MoveLocation(LOC, newX, newY)
set terrainZ = GetLocationZ(LOC)
set pitch = p.alpha
if 0. == height and 0. == pitch then
set z = p.z - terrainZ
else
set z = p.z - terrainZ + p.slope*point
if 0. != height and target == null then
set z = z + (4*height*point*(d - point)/p.square)
set pitch = pitch - Atan(((4*height)*(2*point - d))/p.square)*bj_RADTODEG
endif
endif
// Update the pitch angle of the dummy unit.
if GetUnitTypeId(u) == Missile_DUMMY_UNIT_ID then
call SetUnitAnimationByIndex(u, R2I(pitch + 90.5))
endif
// Move the missile dummy via native.
call SetUnitFlyHeight(u, z, 0.)
call SetUnitFacing(u, a*bj_RADTODEG)
// WorldBounds > BoundSentinel.
static if not LIBRARY_BoundSentinel and not LIBRARY_WorldBounds then
if RectContainsCoords(bj_mapInitialPlayableArea, newX, newY) then
call SetUnitX(u, newX)
call SetUnitY(u, newY)
endif
elseif LIBRARY_WorldBounds then
if newX < WorldBounds.maxX and newX > WorldBounds.minX and newY < WorldBounds.maxY and newY > WorldBounds.minY then
call SetUnitX(u, newX)
call SetUnitY(u, newY)
endif
else
call SetUnitX(u, newX)
call SetUnitY(u, newY)
endif
set loops = loops + 1
set this = nextNode[this]
endloop
set u = null
set thistype.temp = this
return this == 0
endmethod
// Widget collision API:
// =====================
//
// Runs automatically on widget collision.
method hitWidget takes widget w returns nothing
if w != null then
call SaveWidgetHandle(HASH, this, GetHandleId(w), w)
endif
endmethod
// All widget which have been hit return true.
method hasHitWidget takes widget w returns boolean
return HaveSavedHandle(HASH, this, GetHandleId(w))
endmethod
// Removes a widget from the missile's memory of hit widgets. ( This widget can be hit again )
method removeHitWidget takes widget w returns nothing
if w != null then
call RemoveSavedHandle(HASH, this, GetHandleId(w))
endif
endmethod
// Flushes a missile's memory for collision. ( All widgets can be hit again )
method flushHitWidgets takes nothing returns nothing
call FlushChildHashtable(HASH, this)
call hitWidget(dummy)
endmethod
// Tells missile to call removeHitWidget(w) after "seconds" time.
// Does not apply to widgets, which are already hit by this missile.
readonly integer stackSize
method enableHitAfter takes widget w, real seconds returns nothing
local integer id = GetHandleId(w)
if w != null then
if not HaveSavedInteger(HASH, this, id) then
call SaveInteger(HASH, this, id, stackSize)
call SaveInteger(HASH, this, stackSize, id)
set stackSize = stackSize + 1
endif
call SaveReal(HASH, this, id, seconds)// Set time.
endif
endmethod
method updateStack takes nothing returns nothing
local integer dex = 0
local integer id
local real time
loop
exitwhen dex == stackSize
set id = LoadInteger(HASH, this, dex)
set time = LoadReal(HASH, this, id) - Missile_TIMER_TIMEOUT
if time <= 0. or not HaveSavedHandle(HASH, this, id) then
set stackSize = stackSize - 1
set id = LoadInteger(HASH, this, stackSize)
call SaveInteger(HASH, this, dex, id)
call SaveInteger(HASH, this, id, dex)
// Enables hit.
call RemoveSavedHandle(HASH, this, id)
// Remove data from stack.
call RemoveSavedReal(HASH, this, id)
call RemoveSavedInteger(HASH, this, id)
call RemoveSavedInteger(HASH, this, stackSize)
else
call SaveReal(HASH, this, id, time)
set dex = dex + 1
endif
endloop
endmethod
// Widget collision code:
// ======================
//
private static boolean circle = true
//
// 1.) Rectangle collision for fast moving missiles with small collision radius.
//
// Runs for destructables and items in a rectangle.
// Checks if widget w is in collision range of a missile.
// Is not precise in z - axis collision.
private method isWidgetInRectangle takes widget w, real wz, real distance returns boolean
local real wx = GetWidgetX(w)
local real wy = GetWidgetY(w)
local real dz = Missile_GetLocZ(wx, wy) - terrainZ
local real dx = x - prevX
local real dy = y - prevY
local real s = (dx*(wx - prevX) + dy*(wy - prevY))/(dx*dx + dy*dy)
if s < 0. then
set s = 0.
elseif s > 1 then
set s = 1.
endif
set dx = (prevX + s*dx) - wx
set dy = (prevY + s*dy) - wy
return dx*dx + dy*dy <= distance*distance and dz + wz >= z - distance and dz <= z + distance
endmethod
//
// 2.) Circular collision detection for all other missiles.
//
// Returns true for widgets in a xyz collision range.
private method isWidgetInRange takes widget w, real wz, real distance returns boolean
local real wx = GetWidgetX(w)
local real wy = GetWidgetY(w)
local real dz = Missile_GetLocZ(wx, wy) - terrainZ
// collision in plane x and y, collision in z axis.
return IsUnitInRangeXY(dummy, wx, wy, distance) and dz + wz >= z - distance and dz <= z + distance
endmethod
//
// 3.) Action functions inside the widget enumeration thread.
//
// Runs for every enumerated destructable.
// • Directly filters out already hit destructables.
// • Distance formula based on the Pythagorean theorem.
//
private static method filterDests takes nothing returns boolean
local destructable d = GetFilterDestructable()
local boolean b = false
if not HaveSavedHandle(HASH, temp, GetHandleId(d)) then
if circle then
set b = temp.isWidgetInRange(d, GetDestructableHeight(d), temp.collision)
else
set b = temp.isWidgetInRectangle(d, GetDestructableHeight(d), temp.collision)
endif
endif
set d = null
return b
endmethod
//
// Runs for every enumerated item.
// • Directly filters out already hit items.
// • Distance formula based on the Pythagorean theorem.
// • Items have a fix collision size of 16.
//
private static method filterItems takes nothing returns boolean
local item i = GetFilterItem()
local boolean b = false
if not HaveSavedHandle(HASH, temp, GetHandleId(i)) then
if circle then // Item in missile collision size or item pathing in missile range.
set b = temp.isWidgetInRange(i, GetItemHeight(i), RMaxBJ(temp.collision, 16.))
else
set b = temp.isWidgetInRectangle(i, GetItemHeight(i), RMaxBJ(temp.collision, 16.))
endif
endif
set i = null
return b
endmethod
//
// 4.) Filter function for rectangle unit collision.
//
// Runs for every enumerated units.
// • Filters out units which are not in collision range in plane x / y.
// • Inlined and therefore a bit faster than item and destructable collision.
//
private static method filterUnits takes nothing returns boolean
local thistype this = thistype.temp
local unit u = GetFilterUnit()
local real dx
local real dy
local real s
local boolean is = false
if not HaveSavedHandle(HASH, this, GetHandleId(u)) then
set dx = x - prevX
set dy = y - prevY
set s = (dx*(GetUnitX(u) - prevX) + dy*(GetUnitY(u)- prevY))/(dx*dx + dy*dy)
if s < 0. then
set s = 0.
elseif s > 1. then
set s = 1.
endif
set is = IsUnitInRangeXY(u, prevX + s*dx, prevY + s*dy, collision)
endif
set u = null
return is
endmethod
//
// 5.) Proper rect preparation.
//
// For rectangle.
private method prepareRectRectangle takes nothing returns nothing
local real x1 = prevX
local real y1 = prevY
local real x2 = x
local real y2 = y
local real d = collision + Missile_MAXIMUM_COLLISION_SIZE
// What is min, what is max ...
if x1 < x2 then
if y1 < y2 then
call SetRect(RECT, x1 - d, y1 - d, x2 + d, y2 + d)
else
call SetRect(RECT, x1 - d, y2 - d, x2 + d, y1 + d)
endif
elseif y1 < y2 then
call SetRect(RECT, x2 - d, y1 - d, x1 + d, y2 + d)
else
call SetRect(RECT, x2 - d, y2 - d, x1 + d, y1 + d)
endif
endmethod
//
// For circular.
private method prepareRectCircle takes nothing returns nothing
local real d = collision + Missile_MAXIMUM_COLLISION_SIZE
call SetRect(RECT, x - d, y - d, x + d, y + d)
endmethod
//
// 5.) API for the MissileStruct iteration.
//
method groupEnumUnitsRectangle takes nothing returns nothing
call prepareRectRectangle()
set thistype.temp = this
call GroupEnumUnitsInRect(GROUP, RECT, unitFilter)
endmethod
//
// Prepares destructable enumeration, then runs enumDests.
method checkDestCollision takes code func returns nothing
set circle = collisionType == Missile_COLLISION_TYPE_CIRCLE
if circle then
call prepareRectCircle()
else
call prepareRectRectangle()
endif
//
set thistype.temp = this
call EnumDestructablesInRect(RECT, destFilter, func)
endmethod
//
// Prepares item enumeration, then runs enumItems.
method checkItemCollision takes code func returns nothing
set circle = collisionType == Missile_COLLISION_TYPE_CIRCLE
if circle then
call prepareRectCircle()
else
call prepareRectRectangle()
endif
//
set thistype.temp = this
call EnumItemsInRect(RECT, itemFilter, func)
endmethod
static if Missile_WRITE_DELAYED_MISSILE_RECYCLING then
method nullBefore takes nothing returns nothing
set dummy = null
endmethod
endif
// Does not check for 'Aloc' and 'Amrf' as they could be customized.
private static method onInit takes nothing returns nothing
static if LIBRARY_ErrorMessage then
debug local boolean prev = ToogleUnitIndexer(false)
debug local unit dummy = CreateUnit(Missile_NEUTRAL_PASSIVE, Missile_DUMMY_UNIT_ID, 0., 0., 0.)
debug call ToogleUnitIndexer(prev)
//
debug call ThrowError((GetUnitTypeId(dummy) != Missile_DUMMY_UNIT_ID), "Missile", "DEBUG_MISSILE", "type id", 0, "Global setup for public integer DUMMY_UNIT_ID is incorrect! This map currently can't use Missile!")
debug call ThrowError((Missile_MAXIMUM_COLLISION_SIZE < 0), "Missile", "DEBUG_MISSILE", "collision", 0, "Global setup for public real MAXIMUM_COLLISION_SIZE is incorrect, below zero! This map currently can't use Missile!")
debug call RemoveUnit(dummy)
debug set dummy = null
endif
//
set unitFilter = Filter(function thistype.filterUnits)
set destFilter = Filter(function thistype.filterDests)
set itemFilter = Filter(function thistype.filterItems)
call TriggerAddCondition(MOVE, Condition(function thistype.move))
endmethod
endstruct
// You made it to the end of Missile, but we are not finished.
// Do you remember about the data structure, the delayed recycler
// and of course our interface module "MissileStruct"
//
// This comes now!
// Debug code taken from List ( full credits to Nestharus )
private module MissileStructure
private static thistype collectionCount = 0
private static thistype nodeCount = 0
static if LIBRARY_ErrorMessage then
debug private boolean isNode
debug private boolean isCollection
endif
private thistype _list
method operator list takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "list", "thistype", this, "Attempted To Read Null Node.")
debug call ThrowError(not isNode, "MissileStructure", "list", "thistype", this, "Attempted To Read Invalid Node.")
endif
return _list
endmethod
private thistype _next
method operator next takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "next", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "MissileStructure", "next", "thistype", this, "Attempted To Read Invalid Node.")
endif
return _next
endmethod
private thistype _prev
method operator prev takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "prev", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "MissileStructure", "prev", "thistype", this, "Attempted To Read Invalid Node.")
endif
return _prev
endmethod
private thistype _first
method operator first takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "first", "thistype", this, "Attempted To Read Null List.")
debug call ThrowError(not isCollection, "MissileStructure", "first", "thistype", this, "Attempted To Read Invalid List.")
endif
return _first
endmethod
private thistype _last
method operator last takes nothing returns thistype
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "MissileStructure", "last", "thistype", this, "Attempted To Read Null List.")
debug call ThrowError(not isCollection, "MissileStructure", "last", "thistype", this, "Attempted To Read Invalid List.")
endif
return _last
endmethod
static method allocateCollection takes nothing returns thistype
local thistype this = thistype(0)._first
if (0 == this) then
static if LIBRARY_ErrorMessage then
debug call ThrowError(collectionCount == 8191, "MissileStructure", "allocateCollection", "thistype", 0, "Overflow.")
endif
set this = collectionCount + 1
set collectionCount = this
else
set thistype(0)._first = _first
endif
static if LIBRARY_ErrorMessage then
debug set isCollection = true
endif
set _first = 0
return this
endmethod
static method allocateNode takes nothing returns thistype
local thistype this = thistype(0)._next
if (0 == this) then
static if LIBRARY_ErrorMessage then
debug call ThrowError(nodeCount == 8191, "MissileStructure", "allocateNode", "thistype", 0, "Overflow.")
endif
set this = nodeCount + 1
set nodeCount = this
else
set thistype(0)._next = _next
endif
set allocated = true
return this
endmethod
method insertFront takes thistype node returns thistype
// Extra static unique list for missile motion.
set nextNode[node] = 0
set prevNode[node] = prevNode[0]
set nextNode[prevNode[0]] = node
set prevNode[0] = node
static if LIBRARY_ErrorMessage then
debug call ThrowError(this == 0, "List", "push", "thistype", this, "Attempted To Push On To Null List.")
debug call ThrowError(not isCollection, "List", "push", "thistype", this, "Attempted To Push On To Invalid List.")
debug set node.isNode = true
endif
set node._list = this
if (_first == 0) then
set _first = node
set _last = node
set node._next = 0
else
set _first._prev = node
set node._next = _first
set _first = node
endif
set node._prev = 0
return node
endmethod
method remove takes nothing returns nothing
local thistype node = this
set this = node._list
static if LIBRARY_ErrorMessage then
debug call ThrowError(node == 0, "MissileStructure", "remove", "thistype", this, "Attempted To Remove Null Node.")
debug call ThrowError(not node.isNode, "MissileStructure", "remove", "thistype", this, "Attempted To Remove Invalid Node (" + I2S(node) + ").")
debug set node.isNode = false
endif
set node._list = 0
if (0 == node._prev) then
set _first = node._next
else
set node._prev._next = node._next
endif
if (0 == node._next) then
set _last = node._prev
else
set node._next._prev = node._prev
endif
set node._next = thistype(0)._next
set thistype(0)._next = node
set node.allocated = false
// Static unique list for missile motion.
set nextNode[prevNode[node]] = nextNode[node]
set prevNode[nextNode[node]] = prevNode[node]
endmethod
endmodule
// Boolean expressions per struct:
// ===============================
//
// Condition function for the core trigger evaluation. ( Runs for all struct using module MissileStruct )
private function MissileCreateExpression takes integer structId, code func returns nothing
set expression[structId] = Condition(func)
endfunction
// Creates a collection for a struct. ( Runs for all struct using module MissileStruct )
private function MissileCreateCollection takes integer structId returns nothing
set missileList[structId] = Missile.allocateCollection()
endfunction
// Core:
// =====
//
// Fires every Missile_TIMER_TIMEOUT.
private function Fire takes nothing returns nothing
local integer i = remove[0]
set remove[0] = 0
loop
exitwhen 0 == i
if recycling[i] then
call TriggerRemoveCondition(CORE, condition[i])
set condition[i] = null
set active = active - 1
endif
set destroying[i] = false
set recycling[i] = false
set i = remove[i]
endloop
if 0 == active then
call PauseTimer(TMR)
else
// Move all launched missiles.
set Missile.temp = nextNode[0]
set i = 0
loop
exitwhen TriggerEvaluate(MOVE)
exitwhen i == 60// Moved over 8910 missiles, something buggy happened.
set i = i + 1 // This case is impossible, hence never happens. But if I'm wrong, which also never happens
endloop // then the map 100% crashes. i == 66 will prevent the game crash and Missile will start to
// to debug itself over the next iterations.
// Access all structs using module MissileStruct.
static if DEBUG_MODE and LIBRARY_ErrorMesssage then
if not TriggerEvaluate(CORE) then
call ThrowWarning(true, "Missile", "Fire", "op limit", 0, /*
*/"You just ran into a op limit!
The op limit protection of Missile is insufficient for your map.
The code of the missile module can't run in one thread and must be splitted.
If unsure make a post in the official 'The Hive Workshop' forum thread of Missile!")
endif
else
call TriggerEvaluate(CORE)
endif
endif
endfunction
// Conditionally starts the timer.
private function StartPeriodic takes integer structId returns nothing
if 0 == instances[structId] or destroying[structId] then
if destroying[structId] then
set recycling[structId] = false
else
if 0 == active then
call TimerStart(TMR, Missile_TIMER_TIMEOUT, true, function Fire)
endif
set active = active + 1
set condition[structId] = TriggerAddCondition(CORE, expression[structId])
endif
endif
set instances[structId] = instances[structId] + 1
endfunction
// Conditionally stops the timer in the next callback.
private function StopPeriodic takes integer structId returns nothing
set instances[structId] = instances[structId] - 1
if 0 == instances[structId] and condition[structId] != null then
if not destroying[structId] and not recycling[structId] then
set destroying[structId] = true
set recycling[structId] = true
set remove[structId] = remove[0]
set remove[0] = structId
endif
endif
endfunction
// Modules:
// ========
//
// You want to place module MissileLaunch at the very top of your struct.
module MissileLaunch
static method launch takes Missile missile returns nothing
static if LIBRARY_ErrorMessage then
debug call ThrowError(missile.launched, "thistype", "launch", "missile.launched", missile, "This missile was already launched before!")
endif
debug set missile.launched = true
//
call missileList[thistype.typeid].insertFront(missile)
call StartPeriodic(thistype.typeid)
endmethod
endmodule
module MissileTerminate
// Called from missileIterate. "P" to avoid code collision.
static method missileTerminateP takes Missile node returns nothing
if node.allocated then
static if thistype.onRemove.exists then
static if Missile_WRITE_DELAYED_MISSILE_RECYCLING and RecycleBin.recycle.exists then
if thistype.onRemove(node) and GetUnitTypeId(node.dummy) == Missile_DUMMY_UNIT_ID then
call RecycleBin.recycle(node.dummy)
call node.nullBefore()
endif
else
call thistype.onRemove(node)
endif
endif
call node.terminate()
call StopPeriodic(thistype.typeid)
endif
endmethod
endmodule
// Allows you to inject missile in certain stages of the motion process.
module MissileAction
static if DEBUG_MODE then
// Runs check during compile time.
static if thistype.onMissile.exists then
Error Message from library Missile in struct thistype !
thistype.onMissile is a reserved name for Missile, once you implemented MissileStruct.
thistype.onMissile is currently not supported by library Missile.
Please delete or re-name that method.
endif
endif
static if thistype.onItem.exists then
private static method missileActionItem takes nothing returns nothing
local item i = GetEnumItem()
local Missile this = Missile.temp
if this.allocated then
call SaveItemHandle(HASH, this, GetHandleId(i), i)
if thistype.onItem(this, i) then
call missileTerminateP(this)
endif
endif
set i = null
endmethod
endif
static if thistype.onDestructable.exists then
private static method missileActionDest takes nothing returns nothing
local destructable d = GetEnumDestructable()
local Missile this = Missile.temp
if this.allocated then
call SaveDestructableHandle(HASH, this, GetHandleId(d), d)
if thistype.onDestructable(this, d) then
call missileTerminateP(this)
endif
endif
set d = null
endmethod
endif
// Runs every Missile_TIMER_TIMEOUT for this struct.
static method missileIterateP takes nothing returns boolean
local Missile this = missileList[thistype.typeid].first
local Missile node
local real collideZ
local boolean b
local unit u
loop
exitwhen 0 == this
set node = this.next// The linked list should not lose the next node.
if this.wantDestroy then
call thistype.missileTerminateP(this)
else
if this.stackSize > 0 then
call this.updateStack()
endif
// Runs unit collision.
static if thistype.onCollide.exists then
if this.allocated and 0. < this.collision then
set b = this.collisionType == Missile_COLLISION_TYPE_RECTANGLE
if b then
call this.groupEnumUnitsRectangle()
else
call GroupEnumUnitsInRange(GROUP, this.x, this.y, this.collision + Missile_MAXIMUM_COLLISION_SIZE, null)
endif
loop
set u = FirstOfGroup(GROUP)
exitwhen u == null
call GroupRemoveUnit(GROUP, u)
if not HaveSavedHandle(HASH, this, GetHandleId(u)) then
if IsUnitInRange(u, this.dummy, this.collision) or b then
// Eventually run z collision checks.
static if Missile_USE_COLLISION_Z_FILTER then
set collideZ = Missile_GetLocZ(GetUnitX(u), GetUnitY(u)) + GetUnitFlyHeight(u) - this.terrainZ
if (collideZ + GetUnitBodySize(u) >= this.z - this.collisionZ) and (collideZ <= this.z + this.collisionZ) then
// Mark as hit.
call SaveUnitHandle(HASH, this, GetHandleId(u), u)
if thistype.onCollide(this, u) then
call thistype.missileTerminateP(this)
exitwhen true
endif
endif
else
// Runs unit collision without z collision checks.
call SaveUnitHandle(HASH, this, GetHandleId(u), u)
if thistype.onCollide(this, u) then
call thistype.missileTerminateP(this)
exitwhen true
endif
endif
endif
endif
endloop
endif
endif
// Runs destructable collision.
static if thistype.onDestructable.exists then
// Check if the missile is not terminated.
if this.allocated and 0. < this.collision then
call this.checkDestCollision(function thistype.missileActionDest)
endif
endif
// Runs item collision.
static if thistype.onItem.exists then
// Check if the missile is not terminated.
if this.allocated and 0. < this.collision then
call this.checkItemCollision(function thistype.missileActionItem)
endif
endif
// Runs when the destination is reached.
if this.recycle and this.allocated then
static if thistype.onFinish.exists then
if thistype.onFinish(this) then
call thistype.missileTerminateP(this)
endif
else
call thistype.missileTerminateP(this)
endif
endif
// Runs on terrian collision.
static if thistype.onTerrain.exists then
if this.allocated and 0. > this.z and thistype.onTerrain(this) then
call missileTerminateP(this)
endif
endif
// Runs every Missile_TIMER_TIMEOUT.
static if thistype.onPeriod.exists then
if this.allocated and thistype.onPeriod(this) then
call missileTerminateP(this)
endif
endif
endif
set this = node
endloop
set u = null
static if DEBUG_MODE and LIBRARY_ErrorMessage then
return true
else
return false
endif
endmethod
endmodule
module MissileStruct
implement MissileLaunch
implement MissileTerminate
implement MissileAction
private static method onInit takes nothing returns nothing
call MissileCreateCollection(thistype.typeid)
call MissileCreateExpression(thistype.typeid, function thistype.missileIterateP)
endmethod
endmodule
// Missile position:
// =================
//
// Simple trigonometry.
//! textmacro WRITE_MISSILE_POSITION_CODE
struct MissilePosition extends array
private static integer array recycler
private static integer alloc = 0
// Readonly members you can access.
readonly real x
readonly real y
readonly real z
readonly real angle
readonly real distance
readonly real square
readonly real slope
readonly real alpha
// Creates an origin - impact link.
private thistype ref
private static method math takes thistype a, thistype b returns nothing
local real dx
local real dy
loop
set dx = b.x - a.x
set dy = b.y - a.y
set dx = dx*dx + dy*dy
set dy = SquareRoot(dx)
exitwhen dx != 0. and dy != 0.
set b.x = b.x + .01
set b.z = b.z - Missile_GetLocZ(b.x -.01, b.y) + Missile_GetLocZ(b.x, b.y)
endloop
set a.square = dx
set a.distance = dy
set a.angle = Atan2(b.y - a.y, b.x - a.x)
set a.slope = (b.z - a.z)/dy
set a.alpha = Atan(a.slope)*bj_RADTODEG
// Set b.
if b.ref == a then
set b.angle = a.angle + bj_PI
set b.distance = dy
set b.slope = -a.slope
set b.alpha = -a.alpha
set b.square = dx
endif
endmethod
static method link takes thistype a, thistype b returns nothing
set a.ref = b
set b.ref = a
call math(a, b)
endmethod
method move takes real toX, real toY, real toZ returns nothing
set x = toX
set y = toY
set z = toZ + Missile_GetLocZ(toX, toY)
if ref != this then
call math(this, ref)
endif
endmethod
method destroy takes nothing returns nothing
set recycler[this] = recycler[0]
set recycler[0] = this
endmethod
static method create takes real x, real y, real z returns MissilePosition
local thistype this = recycler[0]
if 0 == this then
set alloc = alloc + 1
set this = alloc
else
set recycler[0] = recycler[this]
endif
set ref = this
call move(x, y, z)
return this
endmethod
endstruct
//! endtextmacro
// Delayed dummy recycling:
// ========================
//
// Ensures proper fx death animations.
//! textmacro WRITE_MISSILE_RECYCLE_BIN takes DO_THIS, AFTER_TIME
static if $DO_THIS$ then
private struct RecycleBin extends array
private static constant timer t = CreateTimer()
private static integer max = 0
private static unit array dummy
private static real array time
private static method onPeriodic takes nothing returns nothing
local integer dex = 0
loop
exitwhen dex == thistype.max
set thistype.time[dex] = thistype.time[dex] - 1
if 0 >= thistype.time[dex] then
static if LIBRARY_MissileRecycler then
call RecycleMissile(thistype.dummy[dex])
elseif Dummy.create.exists and LIBRARY_Dummy then
call Dummy[thistype.dummy[dex]].destroy()
elseif LIBRARY_xedummy and xedummy.release.exists then
call xedummy.release(thistype.dummy[dex])
else
call RemoveUnit(thistype.dummy[dex])
endif
set thistype.dummy[dex] = null
set thistype.max = thistype.max - 1
set thistype.dummy[dex] = thistype.dummy[thistype.max]
set thistype.time[dex] = thistype.time[thistype.max]
set thistype.dummy[thistype.max] = null
set dex = dex - 1
if 0 == thistype.max then
call PauseTimer(thistype.t)
endif
endif
set dex = dex + 1
endloop
endmethod
static method recycle takes unit toRecycle returns nothing
if 0 == thistype.max then
call TimerStart(thistype.t, 1., true, function thistype.onPeriodic)
endif
set thistype.dummy[max] = toRecycle
set thistype.time[max] = $AFTER_TIME$ + TimerGetRemaining(thistype.t)
set thistype.max = thistype.max + 1
endmethod
endstruct
endif
//! endtextmacro
// The end!
endlibrary
library Event
//2.0.1.1
/////////////////////////////////////////////////////////////////////////
//function CreateEvent takes nothing returns integer
//function TriggerRegisterEvent takes trigger t, integer ev returns nothing
//function RegisterEvent takes boolexpr c, integer ev returns nothing
//function FireEvent takes integer ev returns nothing
//struct Event extends array
//static method create takes nothing returns thistype
//method registerTrigger takes trigger t returns nothing
//method register takes boolexpr c returns nothing
//method fire takes nothing returns nothing
/////////////////////////////////////////////////////////////////////////
globals
private real eventv = 0
endglobals
struct Event extends array
private static integer count = 0
private static trigger array trig
private static boolexpr array bc
static method create takes nothing returns thistype
set count = count + 1
return count
endmethod
method registerTrigger takes trigger t returns nothing
call TriggerRegisterVariableEvent(t, SCOPE_PRIVATE + "eventv", EQUAL, this)
endmethod
method register takes boolexpr c returns nothing
if (null==bc[this]) then
set bc[this]=c
set trig[this] = CreateTrigger()
else
set bc[this]=Or(bc[this],c)
call TriggerClearConditions(trig[this])
endif
call TriggerAddCondition(trig[this], bc[this])
endmethod
method fire takes nothing returns nothing
set eventv = 0
set eventv = this
call TriggerEvaluate(trig[this])
endmethod
endstruct
function TriggerRegisterEvent takes trigger t, Event ev returns nothing
call ev.registerTrigger(t)
endfunction
function RegisterEvent takes boolexpr c, Event ev returns nothing
call ev.register(c)
endfunction
function FireEvent takes Event ev returns nothing
call ev.fire()
endfunction
endlibrary
//============================================================================
// SpellEffectEvent
// - Version 1.1.0.0
//
// API
// ---
// RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
// RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
// Optional
// --------
// Table: hiveworkshop.com/forums/showthread.php?t=188084
//
library SpellEffectEvent requires RegisterPlayerUnitEvent,AbilityLibrary optional Table
//============================================================================
//============================================================================
module msev
public static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
set tb = TableArray[7]
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_ENDCAST)
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_FINISH)
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_HERO_SKILL)
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_CHANNEL)
call TriggerAddCondition(t,Condition(function thistype.Actions))
set t = null
endmethod
endmodule
struct SEE extends array
static TableArray tb
static method Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer uid = GetUnitTypeId(u)
local integer id = GetSpellAbilityId()
local eventid ev = GetTriggerEventId()
local integer eid
local Ability a = 0
local real evalue
local boolean hero
local boolean ite
local integer i
local unit t
local real x
local real y
local Item it
if uid == 'u001' then
set ev = null
set u = null
return
endif
if ev == EVENT_PLAYER_UNIT_SPELL_EFFECT then
set t = GetSpellTargetUnit()
set ite = BlzGetAbilityBooleanField(GetSpellAbility(),ABILITY_BF_ITEM_ABILITY)
set hero = BlzGetAbilityBooleanField(GetSpellAbility(),ABILITY_BF_HERO_ABILITY)
if t != null then
if GetUnitAbilityLevel(t,'A077') != 0 then
set evalue = EnchantEffect.Get(EFFECT_FIRE_GUARD,t)
if BlzGetUnitAbilityCooldownRemaining(t,'A077') == 0 then
if IsUnitEnemy(t,GetTriggerPlayer()) then
call BlzStartUnitAbilityCooldown(t,'A077',evalue)
call MissileFireGuard(t,u)
endif
endif
endif
endif
if ite or hero then
if GetUnitAbilityLevel(u,'A03V') != 0 then
set evalue = EnchantEffect.Get(EFFECT_METEOR,u)
if GetRandomInt(1,100) <= R2I(evalue) and BlzGetAbilityManaCost(id,GetUnitAbilityLevel(u,id)) != 0 then
if t != null then
call ItemEvents_CastMeteoricAttack.evaluate(u,GetUnitX(t),GetUnitY(t))
else
set x = GetSpellTargetX()
set y = GetSpellTargetY()
if x != null then
call ItemEvents_CastMeteoricAttack.evaluate(u,x,y)
else
call ItemEvents_CastMeteoricAttack.evaluate(u,GetUnitX(u),GetUnitY(u))
endif
endif
endif
endif
endif
set t = null
set eid = 1
elseif ev == EVENT_PLAYER_UNIT_SPELL_CAST then
set eid = 2
elseif ev == EVENT_PLAYER_UNIT_SPELL_ENDCAST then
set eid = 3
elseif ev == EVENT_PLAYER_UNIT_SPELL_FINISH then
set eid = 5
elseif ev == EVENT_PLAYER_HERO_SKILL and not IsUnitIllusion(u) then
set eid = 4
set id = GetLearnedSkill()
set u = GetLearningUnit()
set a = Ability.GetUnitAbilityByID(id,u)
if a != 0 then
call a.updateTooltip(true)
endif
elseif ev == EVENT_PLAYER_UNIT_SPELL_CHANNEL then
set eid = 6
endif
if tb[eid].trigger.has(id) then
call TriggerEvaluate(tb[eid].trigger[id])
if eid == 1 then
set a = Ability.GetUnitAbilityByID(id,u)
if a != 0 then
call ItemEvents_HeroSpellEvent.execute(u,id)
endif
call CooldownProcess(u,id)
endif
endif
set ev = null
set u = null
endmethod
implement msev
endstruct
//============================================================================
function RemoveSpellEffectEvent takes integer abil returns nothing
call DestroyTrigger(SEE.tb[1].trigger[abil])
call SEE.tb[1].remove(abil)
endfunction
function RegisterSpellEffectEvent takes integer abil, code func returns nothing
if not SEE.tb[1].handle.has(abil) then
set SEE.tb[1].trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(SEE.tb[1].trigger[abil], Filter(func))
endfunction
function RegisterSpellCastEvent takes integer abil, code func returns nothing
if not SEE.tb[2].handle.has(abil) then
set SEE.tb[2].trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(SEE.tb[2].trigger[abil], Filter(func))
endfunction
function RegisterSpellEndCastEvent takes integer abil, code func returns nothing
if not SEE.tb[3].handle.has(abil) then
set SEE.tb[3].trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(SEE.tb[3].trigger[abil], Filter(func))
endfunction
function RegisterSpellLearn takes integer abil, code func returns nothing
if not SEE.tb[4].handle.has(abil) then
set SEE.tb[4].trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(SEE.tb[4].trigger[abil], Filter(func))
endfunction
function RegisterSpellFinishCastEvent takes integer abil, code func returns nothing
if not SEE.tb[5].handle.has(abil) then
set SEE.tb[5].trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(SEE.tb[5].trigger[abil], Filter(func))
endfunction
function RegisterSpellChannelEvent takes integer abil, code func returns nothing
if not SEE.tb[6].handle.has(abil) then
set SEE.tb[6].trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(SEE.tb[6].trigger[abil], Filter(func))
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 = bj_MAX_PLAYERS
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 Table /* made by Bribe, special thanks to Vexorian & Nestharus, version 4.1.0.1.
One map, one hashtable. Welcome to NewTable 4.1.0.1
This newest iteration of Table introduces the new HashTable struct.
You can now instantiate HashTables which enables the use of large
parent and large child keys, just like a standard hashtable. Previously,
the user would have to instantiate a Table to do this on their own which -
while doable - is something the user should not have to do if I can add it
to this resource myself (especially if they are inexperienced).
This library was originally called NewTable so it didn't conflict with
the API of Table by Vexorian. However, the damage is done and it's too
late to change the library name now. To help with damage control, I
have provided an extension library called TableBC, which bridges all
the functionality of Vexorian's Table except for 2-D string arrays &
the ".flush(integer)" method. I use ".flush()" to flush a child hash-
table, because I wanted the API in NewTable to reflect the API of real
hashtables (I thought this would be more intuitive).
API
------------
struct Table
| static method create takes nothing returns Table
| create a new Table
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush all stored values inside of it
|
| method remove takes integer key returns nothing
| remove the value at index "key"
|
| method operator []= takes integer key, $TYPE$ value returns nothing
| assign "value" to index "key"
|
| method operator [] takes integer key returns $TYPE$
| load the value at index "key"
|
| method has takes integer key returns boolean
| whether or not the key was assigned
|
----------------
struct TableArray
| static method operator [] takes integer array_size returns TableArray
| create a new array of Tables of size "array_size"
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush and destroy it
|
| method operator size takes nothing returns integer
| returns the size of the TableArray
|
| method operator [] takes integer key returns Table
| returns a Table accessible exclusively to index "key"
*/
globals
private integer less = 0 //Index generation for TableArrays (below 0).
private integer more = 8190 //Index generation for Tables.
//Configure it if you use more than 8190 "key" variables in your map (this will never happen though).
private hashtable ht = InitHashtable()
private key sizeK
private key listK
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return sizeK
endmethod
static method operator list takes nothing returns Table
return listK
endmethod
endstruct
private struct handles extends array
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private struct agents extends array
method operator []= takes integer key, agent value returns nothing
call SaveAgentHandle(ht, this, key, value)
endmethod
endstruct
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSaved$SUPER$(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSaved$SUPER$(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! textmacro NEW_ARRAY takes FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$Handle(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$Handle(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//Run these textmacros to include the entire hashtable API as wrappers.
//Don't be intimidated by the number of macros - Vexorian's map optimizer is
//supposed to kill functions which inline (all of these functions inline).
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
//New textmacro to allow table.integer[] syntax for compatibility with textmacros that might desire it.
//! runtextmacro NEW_ARRAY_BASIC("Integer", "Integer", "integer")
//! runtextmacro NEW_ARRAY("Player", "player")
//! runtextmacro NEW_ARRAY("Widget", "widget")
//! runtextmacro NEW_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_ARRAY("Item", "item")
//! runtextmacro NEW_ARRAY("Unit", "unit")
//! runtextmacro NEW_ARRAY("Ability", "ability")
//! runtextmacro NEW_ARRAY("Timer", "timer")
//! runtextmacro NEW_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_ARRAY("Force", "force")
//! runtextmacro NEW_ARRAY("Group", "group")
//! runtextmacro NEW_ARRAY("Location", "location")
//! runtextmacro NEW_ARRAY("Rect", "rect")
//! runtextmacro NEW_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_ARRAY("Sound", "sound")
//! runtextmacro NEW_ARRAY("Effect", "effect")
//! runtextmacro NEW_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_ARRAY("Quest", "quest")
//! runtextmacro NEW_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_ARRAY("Button", "button")
//! runtextmacro NEW_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_ARRAY("Image", "image")
//! runtextmacro NEW_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_ARRAY("Region", "region")
//! runtextmacro NEW_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_ARRAY("Hashtable", "hashtable")
//! runtextmacro NEW_ARRAY("Frame", "framehandle")
struct Table extends array
// Implement modules for intuitive syntax (tb.handle; tb.unit; etc.)
implement realm
implement integerm
implement booleanm
implement stringm
implement playerm
implement widgetm
implement destructablem
implement itemm
implement unitm
implement abilitym
implement timerm
implement triggerm
implement triggerconditionm
implement triggeractionm
implement eventm
implement forcem
implement groupm
implement locationm
implement rectm
implement boolexprm
implement soundm
implement effectm
implement unitpoolm
implement itempoolm
implement questm
implement questitemm
implement defeatconditionm
implement timerdialogm
implement leaderboardm
implement multiboardm
implement multiboarditemm
implement trackablem
implement dialogm
implement buttonm
implement texttagm
implement lightningm
implement imagem
implement ubersplatm
implement regionm
implement fogstatem
implement fogmodifierm
implement hashtablem
implement framehandlem
method operator handle takes nothing returns handles
return this
endmethod
method operator agent takes nothing returns agents
return this
endmethod
//set this = tb[GetSpellAbilityId()]
method operator [] takes integer key returns Table
return LoadInteger(ht, this, key) //return this.integer[key]
endmethod
//set tb[389034] = 8192
method operator []= takes integer key, Table tb returns nothing
call SaveInteger(ht, this, key, tb) //set this.integer[key] = tb
endmethod
//set b = tb.has(2493223)
method has takes integer key returns boolean
return HaveSavedInteger(ht, this, key) //return this.integer.has(key)
endmethod
//call tb.remove(294080)
method remove takes integer key returns nothing
call RemoveSavedInteger(ht, this, key) //call this.integer.remove(key)
endmethod
//Remove all data from a Table instance
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
endmethod
//local Table tb = Table.create()
static method create takes nothing returns Table
local Table this = dex.list[0]
if this == 0 then
set this = more + 1
set more = this
else
set dex.list[0] = dex.list[this]
call dex.list.remove(this) //Clear hashed memory
endif
set dex.list[this] = -1
return this
endmethod
// Removes all data from a Table instance and recycles its index.
//
// call tb.destroy()
//
method destroy takes nothing returns nothing
if dex.list[this] != -1 then
debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
return
endif
call this.flush()
set dex.list[this] = dex.list[0]
set dex.list[0] = this
endmethod
//! runtextmacro optional TABLE_BC_METHODS()
endstruct
//! runtextmacro optional TABLE_BC_STRUCTS()
struct TableArray extends array
//Returns a new TableArray to do your bidding. Simply use:
//
// local TableArray ta = TableArray[array_size]
//
static method operator [] takes integer array_size returns TableArray
local Table tb = dex.size[array_size] //Get the unique recycle list for this array size
local TableArray this = tb[0] //The last-destroyed TableArray that had this array size
debug if array_size <= 0 then
debug call BJDebugMsg("TypeError: Invalid specified TableArray size: " + I2S(array_size))
debug return 0
debug endif
if this == 0 then
set this = less - array_size
set less = this
else
set tb[0] = tb[this] //Set the last destroyed to the last-last destroyed
call tb.remove(this) //Clear hashed memory
endif
set dex.size[this] = array_size //This remembers the array size
return this
endmethod
//Returns the size of the TableArray
method operator size takes nothing returns integer
return dex.size[this]
endmethod
//This magic method enables two-dimensional[array][syntax] for Tables,
//similar to the two-dimensional utility provided by hashtables them-
//selves.
//
//ta[integer a].unit[integer b] = unit u
//ta[integer a][integer c] = integer d
//
//Inline-friendly when not running in debug mode
//
method operator [] takes integer key returns Table
static if DEBUG_MODE then
local integer i = this.size
if i == 0 then
call BJDebugMsg("IndexError: Tried to get key from invalid TableArray instance: " + I2S(this))
return 0
elseif key < 0 or key >= i then
call BJDebugMsg("IndexError: Tried to get key [" + I2S(key) + "] from outside TableArray bounds: " + I2S(i))
return 0
endif
endif
return this + key
endmethod
//Destroys a TableArray without flushing it; I assume you call .flush()
//if you want it flushed too. This is a public method so that you don't
//have to loop through all TableArray indices to flush them if you don't
//need to (ie. if you were flushing all child-keys as you used them).
//
method destroy takes nothing returns nothing
local Table tb = dex.size[this.size]
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to destroy an invalid TableArray: " + I2S(this))
debug return
debug endif
if tb == 0 then
//Create a Table to index recycled instances with their array size
set tb = Table.create()
set dex.size[this.size] = tb
endif
call dex.size.remove(this) //Clear the array size from hash memory
set tb[this] = tb[0]
set tb[0] = this
endmethod
private static Table tempTable
private static integer tempEnd
//Avoids hitting the op limit
private static method clean takes nothing returns nothing
local Table tb = .tempTable
local integer end = tb + 0x1000
if end < .tempEnd then
set .tempTable = end
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
else
set end = .tempEnd
endif
loop
call tb.flush()
set tb = tb + 1
exitwhen tb == end
endloop
endmethod
//Flushes the TableArray and also destroys it. Doesn't get any more
//similar to the FlushParentHashtable native than this.
//
method flush takes nothing returns nothing
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
debug return
debug endif
set .tempTable = this
set .tempEnd = this + this.size
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
call this.destroy()
endmethod
endstruct
//NEW: Added in Table 4.0. A fairly simple struct but allows you to do more
//than that which was previously possible.
struct HashTable extends array
//Enables myHash[parentKey][childKey] syntax.
//Basically, it creates a Table in the place of the parent key if
//it didn't already get created earlier.
method operator [] takes integer index returns Table
local Table t = Table(this)[index]
if t == 0 then
set t = Table.create()
set Table(this)[index] = t //whoops! Forgot that line. I'm out of practice!
endif
return t
endmethod
//You need to call this on each parent key that you used if you
//intend to destroy the HashTable or simply no longer need that key.
method remove takes integer index returns nothing
local Table t = Table(this)[index]
if t != 0 then
call t.destroy()
call Table(this).remove(index)
endif
endmethod
//Added in version 4.1
method has takes integer index returns boolean
return Table(this).has(index)
endmethod
//HashTables are just fancy Table indices.
method destroy takes nothing returns nothing
call Table(this).destroy()
endmethod
//Like I said above...
static method create takes nothing returns thistype
return Table.create()
endmethod
endstruct
endlibrary
library TimerUtilsEx requires optional Table
/*************************************************
*
* TimerUtilsEx
* v2.1.0.2
* By Vexorian, Bribe & Magtheridon96
*
* Original version by Vexorian.
*
* Flavors:
* Hashtable:
* - RAM: Minimal
* - TimerData: Slow
*
* Array:
* - RAM: Maximal
* - TimerData: Fast
*
* All the functions have O(1) complexity.
* The Array version is the fastest, but the hashtable
* version is the safest. The Array version is still
* quite safe though, and I would recommend using it.
* The system is much slower in debug mode.
*
* Optional Requirement:
* - Table by Bribe
* - hiveworkshop.com/forums/showthread.php?t=188084
*
* API:
* ----
* - function NewTimer takes nothing returns timer
* - Returns a new timer from the stack.
* - function NewTimerEx takes integer i returns timer
* - Returns a new timer from the stack and attaches a value to it.
* - function ReleaseTimer takes timer t returns integer
* - Throws a timer back into the stack. Also returns timer data.
* - function SetTimerData takes timer t, integer value returns nothing
* - Attaches a value to a timer.
* - function GetTimerData takes timer t returns integer
* - Returns the attached value.
*
*************************************************/
// Configuration
globals
// Use hashtable, or fast array?
private constant boolean USE_HASH = false
// Max Number of Timers Held in Stack
private constant integer QUANTITY = 256
endglobals
globals
private timer array tT
private integer tN = 0
endglobals
private module Init
private static method onInit takes nothing returns nothing
static if not USE_HASH then
local integer i = QUANTITY
loop
set i = i - 1
set tT[i] = CreateTimer()
exitwhen i == 0
endloop
set tN = QUANTITY
elseif LIBRARY_Table then
set tb = Table.create()
endif
endmethod
endmodule
// JassHelper doesn't support static ifs for globals.
private struct Data extends array
static if not USE_HASH then
static integer array data
endif
static if LIBRARY_Table then
static Table tb = 0
else
static hashtable ht = InitHashtable()
endif
implement Init
endstruct
// Double free protection
private function ValidTimer takes integer i returns boolean
static if LIBRARY_Table then
return Data.tb.boolean[-i]
else
return LoadBoolean(Data.ht, i, 1)
endif
endfunction
private function Get takes integer id returns integer
debug if not ValidTimer(id) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[TimerUtils]Error: Tried to get data from invalid timer.")
debug endif
static if USE_HASH then
static if LIBRARY_Table then
return Data.tb[id]
else
return LoadInteger(Data.ht, id, 0)
endif
else
return Data.data[id - 0x100000]
endif
endfunction
private function Set takes integer id, integer data returns nothing
debug if not ValidTimer(id) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[TimerUtils]Error: Tried to attach data to invalid timer.")
debug endif
static if USE_HASH then
static if LIBRARY_Table then
set Data.tb[id] = data
else
call SaveInteger(Data.ht, id, 0, data)
endif
else
set Data.data[id - 0x100000] = data
endif
endfunction
function SetTimerData takes timer t, integer data returns nothing
call Set(GetHandleId(t), data)
endfunction
function GetTimerData takes timer t returns integer
return Get(GetHandleId(t))
endfunction
function NewTimerEx takes integer data returns timer
local integer id
if tN == 0 then
static if USE_HASH then
set tT[0] = CreateTimer()
else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[TimerUtils]Error: No Timers In The Stack! You must increase 'QUANTITY'")
return null
endif
else
set tN = tN - 1
endif
set id = GetHandleId(tT[tN])
static if LIBRARY_Table then
set Data.tb.boolean[-id] = true
else
call SaveBoolean(Data.ht, id, 1, true)
endif
call Set(id, data)
return tT[tN]
endfunction
function NewTimer takes nothing returns timer
return NewTimerEx(0)
endfunction
function ReleaseTimer takes timer t returns integer
local integer id = GetHandleId(t)
local integer data = 0
// Pause the timer just in case.
call PauseTimer(t)
// Make sure the timer is valid.
if ValidTimer(id) then
// Get the timer's data.
set data = Get(id)
// Unmark handle id as a valid timer.
static if LIBRARY_Table then
call Data.tb.boolean.remove(-id)
else
call RemoveSavedBoolean(Data.ht, id, 1)
endif
//If it's not run in USE_HASH mode, this next block is useless.
static if USE_HASH then
//At least clear hash memory while it's in the recycle stack.
static if LIBRARY_Table then
call Data.tb.remove(id)
else
call RemoveSavedInteger(Data.ht, id, 0)
endif
// If the recycle limit is reached
if tN == QUANTITY then
// then we destroy the timer.
call DestroyTimer(t)
return data
endif
endif
//Recycle the timer.
set tT[tN] = t
set tN = tN + 1
//Tried to pass a bad timer.
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[TimerUtils]Error: Tried to release non-active timer!")
endif
//Return Timer Data.
return data
endfunction
endlibrary
library TimerUtils requires TimerUtilsEx
endlibrary
library CTL /* v1.2.0.1
*************************************************************************************
*
* CTL or Constant Timer Loop provides a loop for constant merged timers of timeout .03125
*
* Similar to T32 but pauses timer when no structs have instances and removes structs
* from timer trigger when those structs have no instances.
*
* This can also create new timers after destroying a previous timer and generates less
* code in the module. It also generates no triggers so long as the module is implemented
* at the top of the struct.
*
************************************************************************************
*
* module CTL
*
* Allows creation/destruction of timers in a struct. Provides instancing of those timers.
*
* - static method create takes nothing returns thistype
* - method destroy takes nothing returns nothing
*
* CTL (optional)
* local variables, code before running any timers
* CTLExpire (not optional)
* timer code
* CTLNull (optional)
* null any locals, runs after all timers
* CTLEnd (not optional)
*
* module CT32
*
* Converts struct into a timer group. Allows the timer group to be started and stopped.
* Instancing and looping through active timers is up to the user.
*
* - static method start takes nothing returns nothing
* - static method stop takes nothing returns nothing
*
* CT32 (not optional)
* timer code
* CT32End (not optional)
*
* struct TimerGroup32 extends array
*
* Allows for the creation of timer groups. Timer instancing and looping is entirely up
* to the user.
*
* - static method create takes code func returns thistype
* - method destroy takes nothing returns nothing
* - method start takes nothing returns nothing
* - method stop takes nothing returns nothing
*
************************************************************************************/
globals
private integer tgc = 0 //timer group count
private integer array tgr //timer group recycler
private integer ic=0 //instance count
private integer tc=0 //timer count
private integer array rf //root first
private integer array n //next
private integer array p //previous
private integer array th //timer head
private integer array ns //next stack
private trigger t=CreateTrigger()
private timer m=CreateTimer()
private triggercondition array ct
private conditionfunc array rc
private boolean array e32 //enabled
private integer array i32r //ct32 recycler
private integer i32cr = 0 //ct32 count recycler
private boolean array ir32 //is recycling
private boolean array id32 //is destroying
endglobals
private function E takes nothing returns nothing
local integer i=ns[0]
set ns[0]=0
loop
exitwhen 0==i
if (0==p[i]) then
if (0==n[i]) then
call TriggerRemoveCondition(t,ct[th[i]])
set ct[th[i]]=null
set tc=tc-1
set rf[th[i]]=0
else
set rf[th[i]]=n[i]
set p[n[i]]=0
endif
else
set p[n[i]]=p[i]
set n[p[i]]=n[i]
endif
set n[i]=n[0]
set n[0]=i
set i=ns[i]
endloop
loop
exitwhen 0 == i32cr
set i32cr = i32cr - 1
set i = i32r[i32cr]
if (not e32[i]) then
call TriggerRemoveCondition(t,ct[i])
set ct[i] = null
if (id32[i]) then
set tgr[i] = tgr[0]
set tgr[0] = i
set id32[i] = false
set e32[i] = false
set ir32[i] = false
endif
endif
endloop
if (0==tc) then
call PauseTimer(m)
else
call TriggerEvaluate(t)
endif
endfunction
private function CT takes integer r returns integer
local integer i
local integer f
if (0==n[0]) then
set i=ic+1
set ic=i
else
set i=n[0]
set n[0]=n[i]
endif
set th[i]=r
set ns[i]=-1
set f=rf[r]
if (0==f) then
set n[i]=0
set p[i]=0
set rf[r]=i
set ct[r]=TriggerAddCondition(t,rc[r])
//set ct[r] = null
if (0==tc) then
call TimerStart(m,.031250000,true,function E)
endif
set tc=tc+1
else
set n[i]=f
set p[i]=0
set p[f]=i
set rf[r]=i
endif
return i
endfunction
private function DT takes integer t returns nothing
debug if (0>ns[t]) then
set ns[t]=ns[0]
set ns[0]=t
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"TIMER LOOP ERROR: ATTEMPT TO DESTROY NULL TIMER")
debug endif
endfunction
private function A takes code c returns integer
local integer i = tgr[0]
if (0 == i) then
set i = tgc + 1
set tgc = i
else
set tgr[0] = tgr[i]
endif
set rc[i]=Condition(c)
return i
endfunction
private function A32 takes integer i returns nothing
if (not e32[i]) then
if (not ir32[i] and not id32[i]) then
set ct[i] = TriggerAddCondition(t, rc[i])
endif
if (0 == tc) then
call TimerStart(m,.031250000,true,function E)
endif
set tc = tc + 1
set e32[i] = true
endif
endfunction
private function SR32 takes integer i returns nothing
if (e32[i]) then
if (not ir32[i] and not id32[i]) then
set i32r[i32cr] = i
set i32cr = i32cr + 1
set ir32[i] = true
endif
set e32[i] = false
set tc = tc - 1
endif
endfunction
private function DT32 takes integer i returns nothing
if (not id32[i]) then
if (not ir32[i]) then
set ir32[i] = true
set tc = tc - 1
set i32r[i32cr] = i
set i32cr = i32cr + 1
set e32[i] = false
endif
set id32[i] = true
endif
endfunction
private keyword r
private keyword e
module CTL
static integer rctl32
static method create takes nothing returns thistype
return CT(rctl32)
endmethod
method destroy takes nothing returns nothing
call DT(this)
endmethod
static method ectl32 takes nothing returns boolean
local thistype this=rf[rctl32]
endmodule
module CTLExpire
implement CTL
loop
exitwhen 0==this
endmodule
module CTLNull
set this=n[this]
endloop
endmodule
module CTLEnd
implement CTLNull
return false
endmethod
private static method onInit takes nothing returns nothing
set rctl32 = A(function thistype.ectl32)
endmethod
endmodule
module CT32
static integer rctl32
static method ectl32 takes nothing returns boolean
endmodule
module CT32End
return false
endmethod
static method start takes nothing returns nothing
call A32(rctl32)
endmethod
static method stop takes nothing returns nothing
call SR32(rctl32)
endmethod
private static method onInit takes nothing returns nothing
set rctl32 = A(function thistype.ectl32)
endmethod
endmodule
struct TimerGroup32 extends array
static method create takes code c returns thistype
return A(c)
endmethod
method destroy takes nothing returns nothing
call DT32(this)
endmethod
method start takes nothing returns nothing
call A32(this)
endmethod
method stop takes nothing returns nothing
call SR32(this)
endmethod
endstruct
endlibrary
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ Alloc ~~ By Sevion ~~ Version 1.09 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is Alloc?
// - Alloc implements an intuitive allocation method for array structs
//
// =Pros=
// - Efficient.
// - Simple.
// - Less overhead than regular structs.
//
// =Cons=
// - Must use array structs (hardly a con).
// - Must manually call OnDestroy.
// - Must use Delegates for inheritance.
// - No default values for variables (use onInit instead).
// - No array members (use another Alloc struct as a linked list or type declaration).
//
// Methods:
// - struct.allocate()
// - struct.deallocate()
//
// These methods are used just as they should be used in regular structs.
//
// Modules:
// - Alloc
// Implements the most basic form of Alloc. Includes only create and destroy
// methods.
//
// Details:
// - Less overhead than regular structs
//
// - Use array structs when using Alloc. Put the implement at the top of the struct.
//
// - Alloc operates almost exactly the same as default structs in debug mode with the exception of onDestroy.
//
// How to import:
// - Create a trigger named Alloc.
// - Convert it to custom text and replace the whole trigger text with this.
//
// Thanks:
// - Nestharus for the method of allocation and suggestions on further merging.
// - Bribe for suggestions like the static if and method names.
// - PurgeandFire111 for some suggestions like the merging of Alloc and AllocX as well as OnDestroy stuff.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library Alloc
module Alloc
private static integer instanceCount = 0
private thistype recycle
private boolean Null
static string allocName = "-"
public method operator isNull takes nothing returns boolean
return Null
endmethod
static method allocate takes nothing returns thistype
local thistype this
if (thistype(0).recycle == 0) then
debug if (instanceCount == JASS_MAX_ARRAY_SIZE) then
debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to allocate too many instances!"+I2S(instanceCount)+": "+allocName)
debug return 0
debug endif
set instanceCount = instanceCount + 1
set this = instanceCount
else
set this = thistype(0).recycle
set thistype(0).recycle = thistype(0).recycle.recycle
endif
set this.recycle = -1
set this.Null = false
return this
endmethod
method deallocate takes nothing returns nothing
if (this.recycle != -1) then
debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to deallocate an invalid instance at [" + I2S(this) + "]!")
debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "ERROR: Something has gone wrong, please send me the replay to my Hiveworkshop account."+allocName)
//call PauseGame(true)
return
endif
set this.Null = true
set this.recycle = thistype(0).recycle
set thistype(0).recycle = this
endmethod
endmodule
endlibrary
library LoadingBar uses TimerUtils
globals
private constant string SFX_BAR = "war3mapImported\\Progressbar.mdx"
private constant player OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
endglobals
struct LoadingBarLoop extends array
private static timer TIMER = null
static LinkedList list = 0
private static method Loop takes nothing returns nothing
local Link h = list.head
local Link n
local LoadingBar lb
local real p
local real x
local real y
loop
exitwhen h == 0
set lb = h.data
set n = h.next
if lb.active then
if lb.target != null then
set x = GetUnitX(lb.target) + lb.xOffset
set y = GetUnitY(lb.target) + lb.yOffset
call BlzSetSpecialEffectX(lb.bar,x)
call BlzSetSpecialEffectY(lb.bar,y)
call BlzSetSpecialEffectHeight(lb.bar,GetLocZ(x,y) + lb.zOffset)
endif
if lb.duration > 0 then
set lb.time = lb.time + 0.03125
set p = 100 * lb.time / lb.duration
call BlzSetSpecialEffectTime(lb.bar,p / 100)
if lb.time >= lb.duration then
call Remove(lb)
endif
endif
endif
set h = n
endloop
endmethod
public static method Remove takes LoadingBar lb returns nothing
if lb.node != 0 then
call list.remove(lb.node)
call lb.destroy()
endif
if list.size == 0 then
call PauseTimer(TIMER)
endif
endmethod
public static method Add takes LoadingBar lb returns nothing
if lb.node == 0 then
set lb.node = list.add(lb)
endif
if list.size == 1 then
call TimerStart(TIMER,0.03125,true,function thistype.Loop)
endif
endmethod
private static method onInit takes nothing returns nothing
set list = LinkedList.create()
set TIMER = NewTimer()
endmethod
endstruct
struct LoadingBar extends array
implement Alloc
effect bar
unit target
real xOffset
real yOffset
real zOffset
boolean active
real time
real duration
LinkedList node
method setLoc takes real x, real y, real z returns nothing
call BlzSetSpecialEffectX(bar,x)
call BlzSetSpecialEffectY(bar,y)
call BlzSetSpecialEffectZ(bar,z)
endmethod
method setSize takes real s returns nothing
call BlzSetSpecialEffectScale(bar,s)
endmethod
method setPercent takes real p returns nothing
set p = p / 100.00
set time = duration * p
call BlzSetSpecialEffectTime(bar,p)
endmethod
method setDuration takes real t returns nothing
set duration = t
set time = 0
call BlzSetSpecialEffectTime(bar,0)
endmethod
method setTarget takes unit t returns nothing
set target = t
endmethod
method setColorPlayer takes player color returns nothing
call BlzSetSpecialEffectColorByPlayer(bar,color)
endmethod
method show takes boolean flag returns nothing
if flag then
call BlzSetSpecialEffectAlpha(bar,255)
else
call BlzSetSpecialEffectAlpha(bar,0)
endif
endmethod
method destroy takes nothing returns nothing
call BlzSetSpecialEffectTimeScale(this.bar,3.00)
call DestroyEffect(bar)
set this.bar = null
set this.target = null
set this.xOffset = 0
set this.yOffset = 0
set this.active = false
if this.node != 0 then
call LoadingBarLoop.list.remove(this.node)
endif
call this.deallocate()
endmethod
static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set this.bar = AddSpecialEffect(SFX_BAR,0,0)
call BlzSetSpecialEffectTimeScale(this.bar, 0)
set time = 0
set node = 0
set duration = 0
set this.active = false
call this.show(false)
call LoadingBarLoop.Add(this)
return this
endmethod
endstruct
endlibrary
globals
LoadingBar LB
endglobals
function Rest takes nothing returns nothing
local unit u = GetPlayerHero(GetTriggerPlayer()).hero
set LB = LoadingBar.create()
set LB.target = u
set LB.zOffset = 150.00
set LB.active = true
set LB.xOffset = -25
call LB.show(true)
call LB.setSize(1.5)
call LB.setPercent(50)
set u = null
endfunction
function Set takes nothing returns nothing
local integer x = S2I(SubString(GetEventPlayerChatString(),6,8))
call LB.setColorPlayer(Player(x))
endfunction
//===========================================================================
function InitTrig_Bar takes nothing returns nothing
local trigger t1 = CreateTrigger( )
local trigger t2 = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( t1, Player(2), "-bar", true )
call TriggerRegisterPlayerChatEvent( t2, Player(2), "-barx", false )
call TriggerAddAction( t1, function Rest )
call TriggerAddAction( t2, function Set )
endfunction
library Queue /* v1.0.0.6
************************************************************************************
*
* */uses/*
*
* */ ErrorMessage /* hiveworkshop.com/forums/submissions-414/snippet-error-message-239210/
*
************************************************************************************
*
* module Queue
*
* Description
* -------------------------
*
* NA
*
* Fields
* -------------------------
*
* readonly static integer sentinel
*
* readonly thistype first
* readonly thistype next
*
* Methods
* -------------------------
*
* static method create takes nothing returns thistype
* method destroy takes nothing returns nothing
* - May only destroy queues
*
* method enqueue takes nothing returns thistype
* method pop takes nothing returns nothing
*
* method clear takes nothing returns nothing
*
* debug static method calculateMemoryUsage takes nothing returns integer
* debug static method getAllocatedMemoryAsString takes nothing returns string
*
************************************************************************************/
module Queue
private static thistype collectionCount = 0
private static thistype nodeCount = 0
debug private boolean isNode
debug private boolean isCollection
private thistype last
private thistype _next
method operator next takes nothing returns thistype
debug call ThrowError(this == 0, "Queue", "next", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "Queue", "next", "thistype", this, "Attempted To Read Invalid Node.")
return _next
endmethod
private thistype _first
method operator first takes nothing returns thistype
debug call ThrowError(this == 0, "Queue", "first", "thistype", this, "Attempted To Read Null Queue.")
debug call ThrowError(not isCollection, "Queue", "first", "thistype", this, "Attempted To Read Invalid Queue.")
return _first
endmethod
static method operator sentinel takes nothing returns integer
return 0
endmethod
private static method allocateCollection takes nothing returns thistype
local thistype this = thistype(0)._first
if (0 == this) then
debug call ThrowError(collectionCount == 8191, "Queue", "allocateCollection", "thistype", 0, "Overflow.")
set this = collectionCount + 1
set collectionCount = this
else
set thistype(0)._first = _first
endif
return this
endmethod
private static method allocateNode takes nothing returns thistype
local thistype this = thistype(0)._next
if (0 == this) then
debug call ThrowError(nodeCount == 8191, "Queue", "allocateNode", "thistype", 0, "Overflow.")
set this = nodeCount + 1
set nodeCount = this
else
set thistype(0)._next = _next
endif
return this
endmethod
static method create takes nothing returns thistype
local thistype this = allocateCollection()
debug set isCollection = true
set _first = 0
return this
endmethod
method enqueue takes nothing returns thistype
local thistype node = allocateNode()
debug call ThrowError(this == 0, "Queue", "enqueue", "thistype", this, "Attempted To Enqueue On To Null Queue.")
debug call ThrowError(not isCollection, "Queue", "enqueue", "thistype", this, "Attempted To Enqueue On To Invalid Queue.")
debug set node.isNode = true
if (_first == 0) then
set _first = node
else
set last._next = node
endif
set last = node
set node._next = 0
return node
endmethod
method pop takes nothing returns nothing
local thistype node = _first
debug call ThrowError(this == 0, "Queue", "pop", "thistype", this, "Attempted To Pop Null Queue.")
debug call ThrowError(not isCollection, "Queue", "pop", "thistype", this, "Attempted To Pop Invalid Queue.")
debug call ThrowError(node == 0, "Queue", "pop", "thistype", this, "Attempted To Pop Empty Queue.")
debug set node.isNode = false
set _first = node._next
set node._next = thistype(0)._next
set thistype(0)._next = node
endmethod
method clear takes nothing returns nothing
debug local thistype node = _first
debug call ThrowError(this == 0, "Queue", "clear", "thistype", this, "Attempted To Clear Null Queue.")
debug call ThrowError(not isCollection, "Queue", "clear", "thistype", this, "Attempted To Clear Invalid Queue.")
static if DEBUG_MODE then
loop
exitwhen node == 0
set node.isNode = false
set node = node._next
endloop
endif
if (_first == 0) then
return
endif
set last._next = thistype(0)._next
set thistype(0)._next = _first
set _first = 0
endmethod
method destroy takes nothing returns nothing
debug call ThrowError(this == 0, "Queue", "destroy", "thistype", this, "Attempted To Destroy Null Queue.")
debug call ThrowError(not isCollection, "Queue", "destroy", "thistype", this, "Attempted To Destroy Invalid Queue.")
static if DEBUG_MODE then
debug call clear()
debug set isCollection = false
else
if (_first != 0) then
set last._next = thistype(0)._next
set thistype(0)._next = _first
endif
endif
set _first = thistype(0)._first
set thistype(0)._first = this
endmethod
static if DEBUG_MODE then
static method calculateMemoryUsage takes nothing returns integer
local thistype start = 1
local thistype end = 8191
local integer count = 0
loop
exitwhen integer(start) > integer(end)
if (integer(start) + 500 > integer(end)) then
return count + checkRegion(start, end)
else
set count = count + checkRegion(start, start + 500)
set start = start + 501
endif
endloop
return count
endmethod
private static method checkRegion takes thistype start, thistype end returns integer
local integer count = 0
loop
exitwhen integer(start) > integer(end)
if (start.isNode) then
set count = count + 1
endif
if (start.isCollection) then
set count = count + 1
endif
set start = start + 1
endloop
return count
endmethod
static method getAllocatedMemoryAsString takes nothing returns string
local thistype start = 1
local thistype end = 8191
local string memory = ""
loop
exitwhen integer(start) > integer(end)
if (integer(start) + 500 > integer(end)) then
if (memory != null) then
set memory = memory + ", "
endif
set memory = memory + checkRegion2(start, end)
set start = end + 1
else
if (memory != null) then
set memory = memory + ", "
endif
set memory = memory + checkRegion2(start, start + 500)
set start = start + 501
endif
endloop
return memory
endmethod
private static method checkRegion2 takes thistype start, thistype end returns string
local string memory = ""
loop
exitwhen integer(start) > integer(end)
if (start.isNode) then
if (memory == null) then
set memory = I2S(start)
else
set memory = memory + ", " + I2S(start) + "N"
endif
endif
if (start.isCollection) then
if (memory == null) then
set memory = I2S(start)
else
set memory = memory + ", " + I2S(start) + "C"
endif
endif
set start = start + 1
endloop
return memory
endmethod
endif
endmodule
endlibrary
library ARGB initializer init
//******************************************************************************
//*
//* ARGB 1.1
//* ====
//* For your color needs.
//*
//* An ARGB object is a by-value struct, this means that assigning copies the
//* contents of the struct and that you don't have to use .destroy(), the
//* downside is that you cannot assign its members (can't do set c.r= 123 )
//*
//* This library should have plenty of uses, for example, if your spell involves
//* some unit recoloring you can allow users to input the color in the config
//* section as 0xAARRGGBB and you can then use this to decode that stuff.
//*
//* You can also easily merge two colors and make fading effects using ARGB.mix
//*
//* There's ARGB.fromPlayer which gets an ARGB object containing the player's
//* color. Then you can use the previous utilities on it.
//*
//* The .str() instance method can recolor a string, and the recolorUnit method
//* will apply the ARGB on a unit
//*
//* For other uses, you can use the .red, .green, .blue and .alpha members to get
//* an ARGB object's color value (from 0 to 255).
//*
//* structs that have a recolor method that takes red,green,blue and alpha as 0.255
//* integers can implement the ARGBrecolor module to gain an ability to quickly
//* recolor using an ARGB object.
//*
//********************************************************************************
//=================================================================================
globals
private string array i2cc
private playercolor pc
endglobals
//this double naming stuff is beginning to make me insane, if only TriggerEvaluate() wasn't so slow...
struct ARGB extends array
static method create takes integer a, integer r, integer g, integer b returns ARGB
return ARGB(b + g*0x100 + r*0x10000 + a*0x1000000)
endmethod
static method fromPlayer takes player p returns ARGB
set pc = GetPlayerColor(p)
if(pc==PLAYER_COLOR_RED) then
return 0xFFFF0303
elseif(pc==PLAYER_COLOR_BLUE) then
return 0xFF0042FF
elseif(pc==PLAYER_COLOR_CYAN) then
return 0xFF1CE6B9
elseif(pc==PLAYER_COLOR_PURPLE) then
return 0xFF540081
elseif(pc==PLAYER_COLOR_YELLOW) then
return 0xFFFFFF01
elseif(pc==PLAYER_COLOR_ORANGE) then
return 0xFFFE8A0E
elseif(pc==PLAYER_COLOR_GREEN) then
return 0xFF20C000
elseif(pc==PLAYER_COLOR_PINK) then
return 0xFFE55BB0
elseif(pc==PLAYER_COLOR_LIGHT_GRAY) then
return 0xFF959697
elseif(pc==PLAYER_COLOR_LIGHT_BLUE) then
return 0xFF7EBFF1
elseif(pc==PLAYER_COLOR_AQUA) then
return 0xFF106246
elseif(pc==PLAYER_COLOR_BROWN) then
return 0xFF4E2A04
elseif(pc==PLAYER_COLOR_MAROON) then
return 0xFF9B0000
elseif(pc==PLAYER_COLOR_NAVY) then
return 0xFF0000C3
endif
return 0xFF111111
endmethod
method operator alpha takes nothing returns integer
if( integer(this) <0) then
return 0x80+(-(-integer(this)+0x80000000))/0x1000000
else
return (integer(this))/0x1000000
endif
endmethod
method operator alpha= takes integer na returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + g*0x100 + r*0x10000 + na*0x1000000)
endmethod
method operator red takes nothing returns integer
local integer c=integer(this)*0x100
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator red= takes integer nr returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + g*0x100 + nr*0x10000 + a*0x1000000)
endmethod
method operator green takes nothing returns integer
local integer c=integer(this)*0x10000
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator green= takes integer ng returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(b + ng*0x100 + r*0x10000 + a*0x1000000)
endmethod
//=======================================================
//
//
method operator blue takes nothing returns integer
local integer c=integer(this)*0x1000000
if(c<0) then
return 0x80+(-(-c+0x80000000))/0x1000000
else
return c/0x1000000
endif
endmethod
method operator blue= takes integer nb returns ARGB
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
return ARGB(nb + g*0x100 + r*0x10000 + a*0x1000000)
endmethod
//====================================================================
// Mixes two colors, s would be a number 0<=s<=1 that determines
// the weight given to color c2.
//
// mix(c1,c2,0) = c1
// mix(c1,c2,1) = c2
// mix(c1,c2,0.5) = Mixing the colors c1 and c2 in equal proportions.
//
static method mix takes ARGB c1, ARGB c2, real s returns ARGB
//widest function ever
return ARGB( R2I(c2.blue*s+c1.blue*(1-s)+0.5) + R2I(c2.green*s+c1.green*(1-s)+0.5)*0x100 + R2I(c2.red*s+c1.red*(1-s)+0.5)*0x10000 + R2I((c2.alpha*s)+(c1.alpha*(1-s))+0.5)*0x1000000)
endmethod
method str takes string s returns string
return "|c"+i2cc[.alpha]+i2cc[.red]+i2cc[.green]+i2cc[.blue]+s+"|r"
endmethod
method recolorUnit takes unit u returns nothing
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
call SetUnitVertexColor(u,r,g,b,a)
endmethod
endstruct
module ARGBrecolor
method ARGBrecolor takes ARGB color returns nothing
local integer a
local integer r
local integer g
local integer b
local integer col=integer(this)
if (col<0) then
set col=-(-col+0x80000000)
set a=0x80+col/0x1000000
set col=col-(a-0x80)*0x1000000
else
set a=col/0x1000000
set col=col-a*0x1000000
endif
set r=col/0x10000
set col=col-r*0x10000
set g=col/0x100
set b=col-g*0x100
call this.recolor(r, g , b, a)
endmethod
endmodule
private function init takes nothing returns nothing
local integer i=0
// Don't run textmacros you don't own!
//! textmacro ARGB_CHAR takes int, chr
set i=0
loop
exitwhen i==16
set i2cc[$int$*16+i]="$chr$"+i2cc[$int$*16+i]
set i2cc[i*16+$int$]=i2cc[i*16+$int$]+"$chr$"
set i=i+1
endloop
//! endtextmacro
//! runtextmacro ARGB_CHAR( "0","0")
//! runtextmacro ARGB_CHAR( "1","1")
//! runtextmacro ARGB_CHAR( "2","2")
//! runtextmacro ARGB_CHAR( "3","3")
//! runtextmacro ARGB_CHAR( "4","4")
//! runtextmacro ARGB_CHAR( "5","5")
//! runtextmacro ARGB_CHAR( "6","6")
//! runtextmacro ARGB_CHAR( "7","7")
//! runtextmacro ARGB_CHAR( "8","8")
//! runtextmacro ARGB_CHAR( "9","9")
//! runtextmacro ARGB_CHAR("10","A")
//! runtextmacro ARGB_CHAR("11","B")
//! runtextmacro ARGB_CHAR("12","C")
//! runtextmacro ARGB_CHAR("13","D")
//! runtextmacro ARGB_CHAR("14","E")
//! runtextmacro ARGB_CHAR("15","F")
endfunction
endlibrary
library LinkedList
struct Link extends array
implement Alloc
Link next
Link prev
integer data
public static method create takes integer data returns Link
local thistype this = thistype.allocate()
set this.data = data
return this
endmethod
public method destroy takes nothing returns nothing
set next = 0
set prev = 0
call this.deallocate()
endmethod
endstruct
struct LinkedList extends array
implement Alloc
Link head
Link last
private integer count
public method contains takes integer data returns boolean
local Link temp = head
loop
exitwhen temp == 0
if temp.data == data then
return true
endif
set temp = temp.next
endloop
return false
endmethod
public method getByIndex takes integer i returns Link
local Link temp = head
local integer c = 1
loop
exitwhen temp == 0
if c == i then
return temp
endif
set c = c + 1
set temp = temp.next
endloop
return 0
endmethod
public method find takes integer data returns Link
local Link temp = head
loop
exitwhen temp == 0
if temp.data == data then
return temp
endif
set temp = temp.next
endloop
return 0
endmethod
public method RemoveEx takes Link link returns nothing
if head == 0 or link == 0 then
return
endif
if link == head then
set head = link.next
set head.prev = 0
elseif link == last then
set last = link.prev
set last.next = 0
else
set link.prev.next = link.next
set link.next.prev = link.prev
endif
set count = count - 1
endmethod
public method remove takes Link link returns nothing
if head == 0 or link == 0 then
return
endif
if link == head then
set head = link.next
set head.prev = 0
endif
if link == last then
set last = link.prev
set last.next = 0
endif
set link.prev.next = link.next
set link.next.prev = link.prev
set count = count - 1
call link.destroy()
endmethod
public method add takes integer data returns Link
local Link link = Link.create(data)
if head == 0 then
set head = link
set last = link
set count = count + 1
return link
endif
set head.prev = link
set link.next = head
set head = link
set count = count + 1
return link
endmethod
public method addLast takes integer data returns Link
local Link link = Link.create(data)
if last == 0 then
call link.destroy()
return add(data)
endif
set last.next = link
set link.prev = last
set last = link
set count = count + 1
return link
endmethod
public method operator size takes nothing returns integer
return this.count
endmethod
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set head = 0
set count = 0
set last = 0
return this
endmethod
public method destroy takes nothing returns nothing
local Link temp = head
local Link delete
loop
exitwhen temp == 0
set delete = temp
set temp = delete.next
call remove(delete)
endloop
set count = 0
set head = 0
set last = 0
call this.deallocate()
endmethod
endstruct
endlibrary
library ErrorMessage /* v1.0.2.0
*************************************************************************************
*
* Issue Compliant Error Messages
*
************************************************************************************
*
* function ThrowError takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
* - In the event of an error the game will be permanently paused
*
* function ThrowWarning takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
*
************************************************************************************/
private struct Fields extends array
static constant string COLOR_RED = "|cffff0000"
static constant string COLOR_YELLOW = "|cffffff00"
static string lastError = null
endstruct
private function Pause takes nothing returns nothing
call PauseGame(true)
endfunction
private function ThrowMessage takes string libraryName, string functionName, string objectName, integer objectInstance, string description, string errorType, string color returns nothing
local string str
local string color_braces = "|cff66FF99"
local string orange = "|cffff6600"
set str = "->\n-> " + color_braces + "{|r " + "Library" + color_braces + "(" + orange + libraryName + color_braces + ")"
if (objectName != null) then
if (objectInstance != 0) then
set str = str + "|r.Object" + color_braces + "(" + orange + objectName + color_braces + " (|rinstance = " + orange + I2S(objectInstance) + color_braces + ") )" + "|r." + "Method" + color_braces + "(" + orange + functionName + color_braces + ")"
else
set str = str + "|r.Object" + color_braces + "(" + orange + objectName + color_braces + ")|r." + "Method" + color_braces + "(" + orange + functionName + color_braces + ")"
endif
else
set str = str + "|r." + "Function" + color_braces + "(" + orange + functionName + color_braces + ")"
endif
set str = str + color_braces + " }|r " + "has thrown an exception of type " + color_braces + "(" + color + errorType + color_braces + ")|r."
set Fields.lastError = str + "\n->\n" + "-> " + color + description + "|r\n->"
endfunction
function ThrowError takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
if (Fields.lastError != null) then
set objectInstance = 1/0
endif
if (expression) then
call ThrowMessage(libraryName, functionName, objectName, objectInstance, description, "Error", Fields.COLOR_RED)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60000,Fields.lastError)
call TimerStart(CreateTimer(), 0, true, function Pause)
set objectInstance = 1/0
endif
endfunction
function ThrowWarning takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
if (Fields.lastError != null) then
set objectInstance = 1/0
endif
if (expression) then
call ThrowMessage(libraryName, functionName, objectName, objectInstance, description, "Warning", Fields.COLOR_YELLOW)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60000,Fields.lastError)
set Fields.lastError = null
endif
endfunction
endlibrary
library NewGroup
globals
private integer count = 0
private group array groups
endglobals
function NewGroup takes nothing returns group
if count == 0 then
return CreateGroup()
endif
set count = count - 1
if count < 0 then
call BJDebugMsg("Triying to get a invalid group")
call PauseGame(true)
return null
else
return groups[count]
endif
endfunction
function ReleaseGroup takes group g returns nothing
call GroupClear(g)
set groups[count] = g
set count = count + 1
endfunction
endlibrary
library TerrainPathability initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//*
//******************************************************************************
//*
//* > function IsTerrainDeepWater takes real x, real y returns boolean
//* > function IsTerrainShallowWater takes real x, real y returns boolean
//* > function IsTerrainLand takes real x, real y returns boolean
//* > function IsTerrainPlatform takes real x, real y returns boolean
//* > function IsTerrainWalkable takes real x, real y returns boolean
//*
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//*
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//*
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//*
//* Variables that can be used from the library:
//* [real] TerrainPathability_X
//* [real] TerrainPathability_Y
//*
globals
private constant real MAX_RANGE = 10.
private constant integer DUMMY_ITEM_ID = 'wolg'
endglobals
globals
private item Item = null
private rect Find = null
private item array Hid
private integer HidMax = 0
public real X = 0.
public real Y = 0.
endglobals
function IsTerrainDeepWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
function IsTerrainShallowWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function IsTerrainLand takes real x, real y returns boolean
return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
endfunction
function IsTerrainPlatform takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
private function HideItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set Hid[HidMax] = GetEnumItem()
call SetItemVisible(Hid[HidMax], false)
set HidMax = HidMax + 1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
//Hide any items in the area to avoid conflicts with our item
call MoveRectTo(Find, x, y)
call EnumItemsInRect(Find ,null, function HideItem)
//Try to move the test item and get its coords
call SetItemPosition(Item, x, y) //Unhides the item
set X = GetItemX(Item)
set Y = GetItemY(Item)
static if LIBRARY_IsTerrainWalkable then
//This is for compatibility with the IsTerrainWalkable library
set IsTerrainWalkable_X = X
set IsTerrainWalkable_Y = Y
endif
call SetItemVisible(Item, false)//Hide it again
//Unhide any items hidden at the start
loop
exitwhen HidMax <= 0
set HidMax = HidMax - 1
call SetItemVisible(Hid[HidMax], true)
set Hid[HidMax] = null
endloop
//Return walkability
return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
private function Init takes nothing returns nothing
set Find = Rect(0., 0., 128., 128.)
set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
call SetItemVisible(Item, false)
endfunction
endlibrary
library ReviveUnit /* 2.0.0.0
***************************************************
*
* Resurrects a unit from his corpse, retaining
* its handle ID, facing, and position.
*
***************************************************
*
* ReviveUnit(unit whichUnit) returns boolean
* - Resurrects the input unit.
*
***************************************************
*
* Configurables
* - Remove the ! from //! after saving.
*/
// external ObjectMerger w3a AHre URez anam "Dummy Resurrection" aher 0 acat "" atat "" Hre1 1 1 aare 1 0 aran 1 0 acdn 1 0 amcs 1 0 atar 1 "Air,Dead,Enemy,Friend,Ground,Neutral"
globals
private constant integer DUMMY = 'n00J'
private constant integer RESURRECT = 'URez'
endglobals
/*
***************************************************
*
* Notes
* - Does not work on units without corpses.
* - The resurrected unit's mana is determined
* by the field: "Mana - Initial Amount"
*
***************************************************
*
* Importing: Automatic
* - Copy and paste this trigger.
* - Save the map, close it, and reopen it
* - Remove the exclamation ! from the object
* merger lines above.
*
* Importing: Manual
* - Copy and paste this trigger.
* - Copy and paste the dummy unit and resurrection
* ability from the object editor.
* - Change the configurable raw codes as necessary.
*
***************************************************/
globals
private unit reviver
private real rx
private real ry
endglobals
function ReviveUnit takes unit u returns boolean
local boolean success
if IsUnitType(u, UNIT_TYPE_HERO) then
return ReviveHero(u, GetUnitX(u), GetUnitY(u), false)
else
call SetUnitX(u, rx)
call SetUnitY(u, ry)
set success = IssueImmediateOrderById(reviver, 852094)
endif
return success
endfunction
private module Init
private static method onInit takes nothing returns nothing
set rx = Game.HIDE_X
set ry = Game.HIDE_Y
set reviver = CreateUnit(Player(15), DUMMY, rx, ry, 0)
call SetUnitPathing(reviver, false)
call UnitAddAbility(reviver, RESURRECT)
endmethod
endmodule
struct Revive extends array
/* For backwards compatibility */
static method Unit takes unit whichUnit returns boolean
return ReviveUnit(whichUnit)
endmethod
implement Init
endstruct
endlibrary
library DummyCaster /* v2.0.0.1
*************************************************************************************
*
* Dummy caster for casting spells
*
* Spells must have 0 cooldown, 92083 range, and cost 0 mana. Spells must be instant and
* can't share the same order as other spells on the dummy caster.
*
*************************************************************************************
*
* */uses/*
* */ optional UnitIndexer /* hiveworkshop.com/forums/jass-functions-413/unit-indexer-172090/
*
************************************************************************************
* SETTINGS
*/
globals
constant integer UNITS_DUMMY_CASTER = 'u001'
/*************************************************************************************
*
* PLAYER_OWNER
*
* Owner of dummy caster
*
*************************************************************************************/
private constant player PLAYER_OWNER = Player(15)
endglobals
/*
************************************************************************************
*
* Dummy at position 32256,32256
*
* struct DummyCaster extends array
*
* method cast takes player castingPlayer, integer abilityLevel, integer order, real x, real y returns boolean
* - call DummyCaster[abilityId].cast(...)
* method castTarget takes player castingPlayer, integer abilityLevel, integer order, widget t returns boolean
* - call DummyCaster[abilityId].castTarget(...)
* method castPoint takes player castingPlayer, integer abilityLevel, integer order, real x, real y returns boolean
* - call DummyCaster[abilityId].castPoint(...)
*
************************************************************************************/
globals
private unit u
endglobals
private module N
private static method onInit takes nothing returns nothing
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled=false
set u=CreateUnit(PLAYER_OWNER,UNITS_DUMMY_CASTER,0,0,0)
set UnitIndexer.enabled=true
else
set u=CreateUnit(PLAYER_OWNER,UNITS_DUMMY_CASTER,0,0,0)
endif
call SetUnitPosition(u, Game.HIDE_X, Game.HIDE_Y)
endmethod
endmodule
struct DummyCaster extends array
implement N
private static method prep takes integer a, player p, integer l returns nothing
call UnitAddAbility(u, a)
if (1 < l) then
call SetUnitAbilityLevel(u, a, l)
endif
if (null != p) then
call SetUnitOwner(u, p, false)
call RemoveGuardPosition(u)
endif
endmethod
private static method finish takes integer a returns nothing
call SetUnitOwner(u, PLAYER_OWNER, false)
call UnitRemoveAbility(u, a)
endmethod
static method cast takes integer id, player p, integer level, integer order, real x, real y returns boolean
local boolean b
call SetUnitX(u, x)
call SetUnitY(u, y)
call prep(id, p, level)
set b = IssueImmediateOrderById(u,order)
call finish(id)
//call SetUnitPosition(u, Game.HIDE_X, Game.HIDE_Y)
return b
endmethod
static method castTarget takes integer id, player p, integer level, integer order, widget t returns boolean
local boolean b
call prep(id, p, level)
set b = IssueTargetOrderById(u,order,t)
call finish(id)
return b
endmethod
static method castPoint takes integer id, player p, integer level, integer order, real x, real y returns boolean
local boolean b
call prep(id, p, level)
set b = IssuePointOrderById(u,order,x,y)
call finish(id)
return b
endmethod
endstruct
endlibrary
library Movespeed /*
Movespeed v1.20
by Flux
Applies a stacking movespeed modification to a unit
through code.
Formula:
New Movespeed = (Default Movespeed + Total FlatBonus)*(1 + Total PercentBonus)
*/ requires /*
(nothing)
*/ optional Table /*
If not found, the system will create 1 hashtable. Hashtables are
limited to 255 per map.
*/ optional TimerUtils /*
If found, timers for duration will be recycled.
******************************
API
******************************
struct Movespeed
static method create(unit, percentBonus, flatBonus)
- Create a Movespeed modification.
EXAMPLE: local Movespeed ms = Movespeed.create(GetTriggerUnit(), 0.15, 0)
method operator duration= takes real time
- Adds a duration to the Movespeed instance.
EXAMPLE: set ms.duration = 15
method change(newPercentBonus, newFlatBonus)
- Change the movespeed modification of a certain instance
EXAMPLE: call ms.change(0.20, 0)
method destroy()
- Remove an instance of movespeed modification.
- Not needed if thhe Movespeed instance has a duration.
-------------------
NOTE:
-------------------
All in-game movespeed modifiers such as Boots of Speed, Endurance Aura, Slow Aura, etc.
will still work with this system, but all of them are always applied last.
Formula:
New Movespeed = ((Default Movespeed + Total FlatBonus)*(1 + Total PercentBonus) + Total in-game FlatBonus)*(1 + Total in-game PercentBonus)
-----------
CREDITS
-----------
Table by Bribe
*/
struct Movespeed extends array
implement Alloc
readonly real pb
readonly real fb
readonly unit u
private timer t
private thistype head
private integer count
private static Table tb
static method calculateMove takes unit u returns nothing
local integer id = GetHandleId(u)
local thistype head
if thistype.tb.has(id) then
set head = thistype.tb[id]
call SetUnitMoveSpeed(u, (GetUnitDefaultMoveSpeed(u) + head.fb)*(1 + head.pb))
else
call SetUnitMoveSpeed(u,GetUnitDefaultMoveSpeed(u))
endif
endmethod
method destroy takes nothing returns nothing
local thistype head = this.head
set head.pb = head.pb - this.pb
set head.fb = head.fb - this.fb
set head.count = head.count - 1
if this.t != null then
call ReleaseTimer(this.t)
set this.t = null
endif
if head.count == 0 then
call thistype.tb.remove(GetHandleId(this.u))
call head.deallocate()
endif
call SetUnitMoveSpeed(u, (GetUnitDefaultMoveSpeed(u) + head.fb)*(1 + head.pb))
call this.deallocate()
endmethod
method change takes real newPercentBonus, integer newFlatBonus returns nothing
local thistype head = this.head
set head.pb = head.pb + newPercentBonus - this.pb
set head.fb = head.fb + newFlatBonus - this.fb
set this.pb = newPercentBonus
set this.fb = newFlatBonus
call SetUnitMoveSpeed(u, (GetUnitDefaultMoveSpeed(u) + head.fb)*(1 + head.pb))
endmethod
static method create takes unit u, real percentBonus, integer flatBonus returns thistype
local thistype this = thistype.allocate()
local integer id = GetHandleId(u)
local thistype head
if thistype.tb.has(id) then
set head = thistype.tb[id]
set head.count = head.count + 1
else
set head = thistype.allocate()
set head.pb = 0
set head.fb = 0
set head.count = 1
set thistype.tb[id] = head
endif
set this.u = u
set this.pb = percentBonus
set this.fb = flatBonus
set this.head = head
set head.pb = head.pb + this.pb
set head.fb = head.fb + this.fb
call SetUnitMoveSpeed(u, (GetUnitDefaultMoveSpeed(u) + head.fb)*(1 + head.pb))
return this
endmethod
private static method expired takes nothing returns nothing
call thistype(GetTimerData(GetExpiredTimer())).destroy()
endmethod
method operator duration= takes real time returns nothing
if this.t == null then
set this.t = NewTimerEx(this)
endif
call TimerStart(this.t, time, false, function thistype.expired)
endmethod
private static method onInit takes nothing returns nothing
set thistype.tb = Table.create()
endmethod
endstruct
endlibrary
library WorldBounds
//struct WorldBounds extends array
//static readonly rect world
// same as GetWorldBounds()
//static readonly region worldRegion
// contains world for triggers
//static readonly real maxX
//static readonly real maxY
//static readonly real minX
//static readonly real minY
//static readonly real centerX
//static readonly real centerY
private module WorldBoundInit
private static method onInit takes nothing returns nothing
set world=GetWorldBounds()
set maxX=GetRectMaxX(world)
set maxY=GetRectMaxY(world)
set minX=GetRectMinX(world)
set minY=GetRectMinY(world)
set centerX=(maxX+minX)/2
set centerY=(minY+maxY)/2
set worldRegion=CreateRegion()
call RegionAddRect(worldRegion,world)
endmethod
endmodule
struct WorldBounds extends array
readonly static real maxX
readonly static real maxY
readonly static real minX
readonly static real minY
readonly static real centerX
readonly static real centerY
readonly static rect world
readonly static region worldRegion
public static method IsPointInMap takes real x, real y returns boolean
return x <= maxX and x >= minX and y <= maxY and y >= minY
endmethod
implement WorldBoundInit
endstruct
endlibrary
//===========================================================================
// Damage Engine lets you detect, amplify, block or nullify damage. It even
// lets you detect if the damage was physical or from a spell. Just reference
// DamageEventAmount/Source/Target or the boolean IsDamageSpell, to get the
// necessary damage event data.
//
// - Detect damage: use the event "DamageEvent Equal to 1.00"
// - To change damage before it's dealt: use the event "DamageModifierEvent Equal to 1.00"
// - Detect damage after it was applied, use the event "AfterDamageEvent Equal to 1.00"
// - Detect spell damage: use the condition "IsDamageSpell Equal to True"
// - Detect zero-damage: use the event "DamageEvent Equal to 2.00" (an AfterDamageEvent will not fire for this)
//
// You can specify the DamageEventType before dealing triggered damage. To prevent an already-improbable error, I recommend running the trigger "ClearDamageEvent (Checking Conditions)" after dealing triggered damage from within a damage event:
// - Set NextDamageType = DamageTypeWhatever
// - Unit - Cause...
// - Trigger - Run ClearDamageEvent (Checking Conditions)
//
// You can modify the DamageEventAmount and the DamageEventType from a "DamageModifierEvent Equal to 1.00" trigger.
// - If the amount is modified to negative, it will count as a heal.
// - If the amount is set to 0, no damage will be dealt.
//
// If you need to reference the original in-game damage, use the variable "DamageEventPrevAmt".
//
//===========================================================================
// Programming note about "integer i" and "udg_DmgEvRecursionN": integer i
// ranges from -1 upwards. "udg_DmgEvRecursionN" ranges from 0 upwards.
// "integer i" is always 1 less than "udg_DmgEvRecursionN"
//
function DmgEvResetVars takes nothing returns nothing
local integer i = udg_DmgEvRecursionN - 2
set udg_DmgEvRecursionN = i + 1
if i >= 0 then
set udg_DamageEventPrevAmt = udg_LastDmgPrevAmount[i]
set udg_DamageEventAmount = udg_LastDmgValue[i]
set udg_DamageEventSource = udg_LastDmgSource[i]
set udg_DamageEventTarget = udg_LastDmgTarget[i]
set udg_IsDamageSpell = udg_LastDmgWasSpell[i]
set udg_DamageEventType = udg_LastDmgPrevType[i]
set udg_DamageEventCode = udg_LastDmgCode[i]
endif
endfunction
function CheckDamagedLifeEvent takes boolean clear returns nothing
if clear then
set udg_NextDamageOverride = false
set udg_NextDamageType = 0
set udg_NextDamageCode = 0
endif
if udg_DmgEvTrig != null then
call DestroyTrigger(udg_DmgEvTrig)
set udg_DmgEvTrig = null
if udg_IsDamageSpell then
call SetWidgetLife(udg_DamageEventTarget, RMaxBJ(udg_LastDamageHP, 0.41))
if udg_LastDamageHP <= 0.405 then
if udg_DamageEventType < 0 then
call SetUnitExploded(udg_DamageEventTarget, true)
endif
//Kill the unit
call DisableTrigger(udg_DamageEventTrigger)
call UnitDamageTarget(udg_DamageEventSource, udg_DamageEventTarget, -999, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
call EnableTrigger(udg_DamageEventTrigger)
endif
elseif GetUnitAbilityLevel(udg_DamageEventTarget, udg_DamageBlockingAbility) > 0 then
call UnitRemoveAbility(udg_DamageEventTarget, udg_DamageBlockingAbility)
call SetWidgetLife(udg_DamageEventTarget, udg_LastDamageHP)
endif
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_AfterDamageEvent = 0.00
set udg_AfterDamageEvent = 1.00
set udg_AfterDamageEvent = 0.00
endif
call DmgEvResetVars()
endif
endfunction
function DmgEvOnAOEEnd takes nothing returns nothing
if udg_DamageEventAOE > 1 then
set udg_AOEDamageEvent = 0.00
set udg_AOEDamageEvent = 1.00
set udg_AOEDamageEvent = 0.00
set udg_DamageEventAOE = 1
endif
set udg_DamageEventLevel = 1
set udg_EnhancedDamageTarget = null
call GroupClear(udg_DamageEventAOEGroup)
endfunction
function DmgEvOnExpire takes nothing returns nothing
set udg_DmgEvStarted = false
call CheckDamagedLifeEvent(true)
//Reset things so they don't perpetuate for AoE/Level target detection
call DmgEvOnAOEEnd()
set udg_DamageEventTarget = null
set udg_DamageEventSource = null
endfunction
function PreCheckDamagedLifeEvent takes nothing returns boolean
call CheckDamagedLifeEvent(true)
return false
endfunction
function OnUnitDamage takes nothing returns boolean
local boolean override = udg_DamageEventOverride
local integer i
local integer e = udg_DamageEventLevel
local integer a = udg_DamageEventAOE
local string s
local real prevAmount
local real life
local real prevLife
local unit u
local unit f
call CheckDamagedLifeEvent(false) //in case the unit state event failed and the 0.00 second timer hasn't yet expired
set i = udg_DmgEvRecursionN - 1 //Had to be moved here due to false recursion tracking
if i < 0 then
//Added 25 July to detect AOE damage or multiple single-target damage
set u = udg_DamageEventTarget
set f = udg_DamageEventSource
elseif i < 16 then
set udg_LastDmgPrevAmount[i]= udg_DamageEventPrevAmt
set udg_LastDmgValue[i] = udg_DamageEventAmount
set udg_LastDmgSource[i] = udg_DamageEventSource
set udg_LastDmgTarget[i] = udg_DamageEventTarget
set udg_LastDmgWasSpell[i] = udg_IsDamageSpell
set udg_LastDmgPrevType[i] = udg_DamageEventType
set udg_LastDmgCode[i] = udg_DamageEventCode
else
set s = "WARNING: Recursion error when dealing damage! Make sure when you deal damage from within a DamageEvent trigger, do it like this:\n\n"
set s = s + "Trigger - Turn off (This Trigger)\n"
set s = s + "Unit - Cause...\n"
set s = s + "Trigger - Turn on (This Trigger)"
//Delete the next couple of lines to disable the in-game recursion crash warnings
call ClearTextMessages()
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.00, 0.00, 999.00, s)
return false
endif
set udg_DmgEvRecursionN = i + 2
set prevAmount = GetEventDamage()
set udg_DamageEventTarget = GetTriggerUnit()
set udg_DamageEventSource = GetEventDamageSource()
set udg_DamageEventAmount = prevAmount
set udg_DamageEventType = udg_NextDamageType
set udg_NextDamageType = 0
set udg_DamageEventOverride = udg_NextDamageOverride
set udg_NextDamageOverride = false
set udg_DamageEventCode = udg_NextDamageCode
set udg_NextDamageCode = 0
if i < 0 then
//Added 25 July to detect AOE damage or multiple single-target damage
if udg_DamageEventType == 0 then
if f == udg_DamageEventSource then
//Source has damaged more than once
if IsUnitInGroup(udg_DamageEventTarget, udg_DamageEventAOEGroup) then
//Added 5 August to improve tracking of enhanced damage against, say, Pulverize
set udg_DamageEventLevel = udg_DamageEventLevel + 1
set udg_EnhancedDamageTarget = udg_DamageEventTarget
else
//Multiple targets hit by this source - flag as AOE
set udg_DamageEventAOE = udg_DamageEventAOE + 1
endif
else
//New damage source - unflag everything
set u = udg_DamageEventSource
set udg_DamageEventSource = f
call DmgEvOnAOEEnd()
set udg_DamageEventSource = u
endif
call GroupAddUnit(udg_DamageEventAOEGroup, udg_DamageEventTarget)
endif
if not udg_DmgEvStarted then
set udg_DmgEvStarted = true
call TimerStart(udg_DmgEvTimer, 0.00, false, function DmgEvOnExpire)
endif
endif
if prevAmount == 0.00 then
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_DamageEventPrevAmt = 0.00
set udg_DamageEvent = 0.00
set udg_DamageEvent = 2.00
set udg_DamageEvent = 0.00
endif
call DmgEvResetVars()
else
set u = udg_DamageEventTarget
set udg_IsDamageSpell = prevAmount < 0.00
if udg_IsDamageSpell then
set prevAmount = -udg_DamageEventAmount
set life = 1.00
set udg_DamageEventAmount = prevAmount*life
endif
set udg_DamageEventPrevAmt = prevAmount
set udg_DamageModifierEvent = 0.00
if not udg_DamageEventOverride then
set udg_DamageModifierEvent = 1.00
if not udg_DamageEventOverride then
set udg_DamageModifierEvent = 2.00
set udg_DamageModifierEvent = 3.00
endif
endif
set udg_DamageEventOverride = override
if udg_DamageEventAmount > 0.00 then
set udg_DamageModifierEvent = 4.00
endif
set udg_DamageModifierEvent = 0.00
if not udg_HideDamageFrom[GetUnitUserData(udg_DamageEventSource)] then
set udg_DamageEvent = 0.00
set udg_DamageEvent = 1.00
set udg_DamageEvent = 0.00
endif
call CheckDamagedLifeEvent(true) //in case the unit state event failed from a recursive damage event
//All events have run and the damage amount is finalized.
set life = GetWidgetLife(u)
set udg_DmgEvTrig = CreateTrigger()
call TriggerAddCondition(udg_DmgEvTrig, Filter(function PreCheckDamagedLifeEvent))
if not udg_IsDamageSpell then
if udg_DamageEventAmount != prevAmount then
set life = life + prevAmount - udg_DamageEventAmount
if GetUnitState(u, UNIT_STATE_MAX_LIFE) < life then
set udg_LastDamageHP = life - prevAmount
call UnitAddAbility(u, udg_DamageBlockingAbility)
endif
call SetWidgetLife(u, RMaxBJ(life, 0.42))
endif
call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, LESS_THAN, RMaxBJ(0.41, life - prevAmount/2.00))
else
set udg_LastDamageHP = GetUnitState(u, UNIT_STATE_MAX_LIFE)
set prevLife = life
if life + prevAmount*0.75 > udg_LastDamageHP then
set life = RMaxBJ(udg_LastDamageHP - prevAmount/2.00, 1.00)
call SetWidgetLife(u, life)
set life = (life + udg_LastDamageHP)/2.00
else
set life = life + prevAmount*0.50
endif
set udg_LastDamageHP = prevLife - (prevAmount - (prevAmount - udg_DamageEventAmount))
call TriggerRegisterUnitStateEvent(udg_DmgEvTrig, u, UNIT_STATE_LIFE, GREATER_THAN, life)
endif
endif
set u = null
set f = null
return false
endfunction
function CreateDmgEvTrg takes nothing returns nothing
set udg_DamageEventTrigger = CreateTrigger()
call TriggerAddCondition(udg_DamageEventTrigger, Filter(function OnUnitDamage))
endfunction
function SetupDmgEv1 takes nothing returns boolean
local Index i = INDEX_EVENT
local unit u = i.u
if GetUnitAbilityLevel(u, 'Aloc') == 0 then
set udg_UnitDamageRegistered[i] = true
call TriggerRegisterUnitEvent(udg_DamageEventTrigger, u, EVENT_UNIT_DAMAGED)
call UnitAddAbility(u, udg_SpellDamageAbility)
call UnitMakeAbilityPermanent(u, true, udg_SpellDamageAbility)
endif
set u = null
return false
endfunction
function SetupDmgEv2 takes nothing returns nothing
local Index i = INDEX_EVENT
local Link h
set udg_HideDamageFrom[i] = false
if udg_UnitDamageRegistered[i] then
set udg_UnitDamageRegistered[i] = false
set udg_DamageEventsWasted = udg_DamageEventsWasted + 1
if udg_DamageEventsWasted == 32 then //After 32 registered units have been removed...
set udg_DamageEventsWasted = 0
//Rebuild the mass EVENT_UNIT_DAMAGED trigger:
call DestroyTrigger(udg_DamageEventTrigger)
call CreateDmgEvTrg()
set h = Index.All.head
loop
exitwhen h == 0
if udg_UnitDamageRegistered[h.data] then
call TriggerRegisterUnitEvent(udg_DamageEventTrigger, Index[h.data].u, EVENT_UNIT_DAMAGED)
endif
set h = h.next
endloop
endif
endif
endfunction
//===========================================================================
function DamageEngineInit takes nothing returns nothing
local unit u = CreateUnit(Player(15), 'uloc', 0, 0, 0)
local integer i = 27
//Create this trigger with UnitIndexEvents in order add and remove units
//as they are created or removed.
call RegisterOnIndexEvent(function SetupDmgEv1)
call RegisterOnDeIndexEvent(function SetupDmgEv2)
//Run the configuration trigger to set all configurables:
if gg_trg_Damage_Engine_Config == null then
//It's possible this InitTrig_ function ran first, in which case use ExecuteFunc.
call ExecuteFunc("Trig_Damage_Engine_Config_Actions")
else
call TriggerExecute(gg_trg_Damage_Engine_Config)
endif
//Create trigger for storing all EVENT_UNIT_DAMAGED events.
call CreateDmgEvTrg()
//Create GUI-friendly trigger for cleaning up after UnitDamageTarget.
set udg_ClearDamageEvent = CreateTrigger()
call TriggerAddCondition(udg_ClearDamageEvent, Filter(function PreCheckDamagedLifeEvent))
//Disable SpellDamageAbility for every player.
loop
set i = i - 1
call SetPlayerAbilityAvailable(Player(i), udg_SpellDamageAbility, false)
exitwhen i == 0
endloop
//Preload abilities.
call UnitAddAbility(u, udg_DamageBlockingAbility)
call UnitAddAbility(u, udg_SpellDamageAbility)
call RemoveUnit(u)
set u = null
endfunction
scope MagicData
public function Setup takes nothing returns nothing
local ItemData id = ItemData.create('wild')
set id.goldCost = 1400
set id.abilityName = "Damage Aura"
set id.abilityText = "Increases nearby friendly units attack damage.(900 AoE)"
set id.tier1Text = "7% Damage"
set id.tier2Text = "11% Damage"
set id.tier3Text = "15% Damage"
set id.abilityID = 'A04W'
call id.AddBonus(BONUS_TYPE_ALL_STATS,"All Stats",3,3)
call id.AddBonus(BONUS_TYPE_HP,"Health Points",50,50)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",50,50)
set id = ItemData.create('sres')
set id.goldCost = 1200
set id.abilityName = "Magic Bulwark"
set id.abilityText = "Gives the target and the wielder a shield that has a chance to block 30% of the Spell Damage. Lasts 6 seconds.(12s CD)"
set id.tier1Text = "10% chance + Block Chance"
set id.tier2Text = "20% chance + Block Chance"
set id.tier3Text = "30% chance + Block Chance"
set id.abilityID = 'A0DB'
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_BLOCK,"Block",20,20)
set id = ItemData.create('shwd')
set id.goldCost = 1400
set id.abilityName = "Move Speed Aura"
set id.abilityText = "Gives a bonus movement speed to nearby allies.(900 AoE)"
set id.tier1Text = "8% Move Speed"
set id.tier2Text = "10% Move Speed"
set id.tier3Text = "12% Move Speed"
set id.abilityID = 'A0AS'
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",5,5)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_EVASION,"Evasion",20,20)
set id = ItemData.create('I00S')
set id.goldCost = 1400
set id.abilityName = "Harvest Magic"
set id.abilityText = "Each 50 spell damage received gives a charge, obtaining all charges heals all allies around (400 AoE).4s Cooldown."
set id.tier1Text = "12 Charges, 150 Heal"
set id.tier2Text = "10 Charges, 175 Heal"
set id.tier3Text = "8 Charges, 200 Heal"
set id.abilityID = 'A060'
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",20,20)
set id = ItemData.create('pmna')
set id.goldCost = 1200
set id.abilityName = "Resistance Aura"
set id.abilityText = "Increases nearby friendly units resistance.(900 AoE)"
set id.tier1Text = "40(6.2%) Resistance"
set id.tier2Text = "60(9.3%) Resistance"
set id.tier3Text = "80(12.5%) Resistance"
set id.abilityID = 'A064'
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",50,50)
call id.AddBonus(BONUS_TYPE_LIFE_REGEN,"Life Regen",2,1)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",20,20)
set id = ItemData.create('fgrd')
set id.goldCost = 1200
set id.abilityName = "Shadow Cover"
set id.abilityText = "Makes the target ally Invisible for 6 seconds. while it lasts reduces all damage received and all damage inflicted.(15s CD)"
set id.tier1Text = "40% damage reduction"
set id.tier2Text = "60% damage reduction"
set id.tier3Text = "80% damage reduction"
set id.abilityID = 'A05G'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",20,20)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",50,50)
set id = ItemData.create('mnst')
set id.goldCost = 1500
set id.abilityName = "Magic Eater"
set id.abilityText = "When activated increases the spell lifesteal lasts 15 seconds.(45s CD)"
set id.tier1Text = "15% Spell Lifesteal"
set id.tier2Text = "25% Spell Lifesteal"
set id.tier3Text = "35% Spell Lifesteal"
set id.abilityID = 'A06H'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",20,20)
set id = ItemData.create('pghe')
set id.goldCost = 1400
set id.abilityName = "Purge"
set id.abilityText = "Dispels debuffs from an allied or buffs from an enemy and slowing his attack and move speed by 20% + 5% for each effect dispelled lasts 4 seconds."
set id.tier1Text = "35s Cooldown, 300 Cast Range"
set id.tier2Text = "30s Cooldown, 500 Cast Range"
set id.tier3Text = "20s Cooldown, 700 Cast Range"
set id.abilityID = 'A05K'
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",5,5)
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",50,50)
call id.AddBonus(BONUS_TYPE_STATUS_RED,"Status Reduction",5,5)
set id = ItemData.create('pgma')
set id.goldCost = 1500
set id.abilityName = "Mirror Image"
set id.abilityText = "Upon cast, dispels all debuffs and creates 2 Illusions of the wielder, lasts 35 seconds (45s CD).|nThe illusions takes 300% of the damage."
set id.tier1Text = "25% dmg dealt"
set id.tier2Text = "50% dmg dealt"
set id.tier3Text = "75% dmg dealt"
set id.abilityID = 'A05R'
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",5,5)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,5)
call id.AddBonus(BONUS_TYPE_EVASION,"Evasion",20,20)
set id = ItemData.create('pnvu')
set id.goldCost = 1400
set id.abilityName = "Spider Net"
set id.abilityText = "Ensnare up to 3 enemies in the target area, dealing magical damage. The duration is 1.2s and varies based on the targets movement speed (18s CD)"
set id.tier1Text = "500 Cast Range, 120 Damage"
set id.tier2Text = "700 Cast Range, 160 Damage"
set id.tier3Text = "900 Cast Range, 200 Damage"
set id.abilityID = 'A05M'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,5)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",50,50)
set id = ItemData.create('pomn')
set id.goldCost = 1200
set id.abilityName = "Savage"
set id.abilityText = "Increases Attack Speed by 120% but reducing attack damage by 25."
set id.tier1Text = "7s Duration, 30s CD"
set id.tier2Text = "10s Duration, 25s CD"
set id.tier3Text = "13s Duration, 20s CD"
set id.abilityID = 'A05N'
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",5,5)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_LIFESTEAL,"Lifesteal",10,5)
set id = ItemData.create('pres')
set id.goldCost = 1500
set id.abilityName = "Malefice"
set id.abilityText = "Converts the target enemy in a useless critter."
set id.tier1Text = "2s duration, 40s CD"
set id.tier2Text = "3s duration, 30s CD"
set id.tier3Text = "4s duration, 20s CD"
set id.abilityID = 'A05O'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_MANA_REGEN,"Mana Regen",2,1)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",50,50)
set id = ItemData.create('infs')
set id.goldCost = 1400
set id.abilityName = "Fel Seal"
set id.abilityText = "Silence the enemy target for 2 seconds, any spell damage or attack (greather than 50) the target receive extends the silence duration by 0.25s. At the end deals damage based on the silenced time."
set id.tier1Text = "30 damage x0.5s of silence, 40s CD"
set id.tier2Text = "40 damage x0.5s of silence, 30s CD"
set id.tier3Text = "50 damage x0.5s of silence, 20s CD"
set id.abilityID = 'A08X'
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",5,5)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,5)
set id = ItemData.create('fgfh')
set id.goldCost = 1500
set id.abilityName = "Slam"
set id.abilityText = "The wielder surges to the target point and slams the ground damaging nearby enemies (270 AoE) slowing their attack and movement speed by 45%, also increasing the duration of negative status by 45%. Lasts 6 seconds."
set id.tier1Text = "150 Damage, 20s CD"
set id.tier2Text = "200 Damage, 18s CD"
set id.tier3Text = "250 Damage, 16s CD"
set id.abilityID = 'A08Y'
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",5,5)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",50,50)
set id = ItemData.create('fgrg')
set id.goldCost = 1500
set id.abilityName = "Unholy Regeneration"
set id.abilityText = "Upon activation adds a % of the wielder´s max Hp/Mp to life/mana regen for 7 seconds."
set id.tier1Text = "2% of Hp/Mp as Regen, 50s CD"
set id.tier2Text = "3% of Hp/Mp as Regen, 40s CD"
set id.tier3Text = "4% of Hp/Mp as Regen, 30s CD"
set id.abilityID = 'A091'
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",50,50)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",50,50)
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",5,5)
set id = ItemData.create('ankh')
set id.goldCost = 1200
set id.abilityName = "Binding Chain"
set id.abilityText = "Disarm the target enemy and slightly pull him towards the wielder for some seconds.(12s CD)"
set id.tier1Text = "3s duration."
set id.tier2Text = "4s duration."
set id.tier3Text = "5s duration."
set id.abilityID = 'A092'
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_EVASION,"Evasion",20,20)
set id = ItemData.create('totw')
set id.goldCost = 1500
set id.abilityName = "Divine Word"
set id.abilityText = "Heals target Hp periodically for 6 seconds, also increases life and mana regeneration by a %, if an enemy is targeted the effect becomes negative. (12s CD)|nGains a charge every time a nearby enemy dies."
set id.tier1Text = "20 dps, 60% Regen"
set id.tier2Text = "20 dps, 120% Regen"
set id.tier3Text = "20 dps, 180% Regen"
set id.abilityID = 'A093'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_LIFE_REGEN,"Life Regen",2,1)
set id = ItemData.create('sand')
set id.goldCost = 1200
set id.abilityName = "Death Pulse"
set id.abilityText = "Each time the wielder deals periodic spell damage, there is a 15% chance to deal a bonus Magical Damage."
set id.tier1Text = "10 - 30 Damage"
set id.tier2Text = "30 - 50 Damage"
set id.tier3Text = "50 - 70 Damage"
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",5,5)
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",20,20)
set id = ItemData.create('srrc')
set id.goldCost = 1200
set id.abilityName = "Cripple"
set id.abilityText = "Cripples the target enemy reducing his Attack and Movement Speed by a % and all damage output, lasts 6 seconds.(16s CD)"
set id.tier1Text = "20% slow, -20% Damage"
set id.tier2Text = "25% slow, -25% Damage"
set id.tier3Text = "30% slow, -30% Damage"
set id.abilityID = 'A09L'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",50,50)
set id = ItemData.create('wlsd')
set id.goldCost = 1400
set id.abilityName = "Vampiric Aura"
set id.abilityText = "Increases nearby allies Lifesteal by a %. (900 AoE)"
set id.tier1Text = "12% Lifesteal"
set id.tier2Text = "18% Lifesteal"
set id.tier3Text = "24% Lifesteal"
set id.abilityID = 'A0A6'
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
set id = ItemData.create('woms')
set id.goldCost = 1200
set id.abilityName = "Unstable Dark"
set id.abilityText = "The inflicted spell damage greather than 75 has 40% chance to create a dark nova that damages the enemies around dealing a % of the damage."
set id.tier1Text = "200 AoE, 60% of the Damage."
set id.tier2Text = "300 AoE, 80% of the Damage."
set id.tier3Text = "400 AoE, 100% of the Damage."
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
call id.AddBonus(BONUS_TYPE_SPELL_LIFESTEAL,"Spell Lifesteal",10,5)
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",20,20)
set id = ItemData.create('wshs')
set id.goldCost = 1200
set id.abilityName = "Cyclone"
set id.abilityText = "Lifts the target friendly unit in a cyclone for 1.4 seconds making him invulnerable, then resets the duration of all positive buffs"
set id.tier1Text = "500 Cast Range, 40s CD"
set id.tier2Text = "700 Cast Range, 30s CD"
set id.tier3Text = "900 Cast Range, 20s CD"
set id.abilityID = 'A095'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_MANA_REGEN,"Mana Regen",2,1)
call id.AddBonus(BONUS_TYPE_LIFE_REGEN,"Life Regen",2,1)
set id = ItemData.create('shar')
set id.goldCost = 1400
set id.abilityName = "Infernal"
set id.abilityText = "Calls down a Infernal that after 1 second impact in the area dealing magical damage and stunning the enemies for 1.35s. The Infernal Hp and damage scales with the main attribute.|nLasts 15 seconds."
set id.tier1Text = "130 Damage, 45s CD"
set id.tier2Text = "200 Damage, 30s CD"
set id.tier3Text = "270 Damage, 15s CD"
set id.abilityID = 'AUin'
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",5,5)
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",5,5)
call id.AddBonus(BONUS_TYPE_MANA_REGEN,"Mana Regen",2,1)
set id = ItemData.create('hlst')
set id.goldCost = 1400
set id.abilityName = "Nature's Call"
set id.abilityText = "Summons the last neutral hostile killed (while the item is not in cooldown) with a bonus HP and damage, lasts 40s.(40s CD)"
set id.tier1Text = "+500 Hp, +20 Damage"
set id.tier2Text = "+1000 Hp, +40 Damage"
set id.tier3Text = "+1500 Hp, +60 Damage"
set id.abilityID = 'A04K'
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",50,50)
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
set id = ItemData.create('pdi2')
set id.goldCost = 1600
set id.abilityName = "Frenzy"
set id.abilityText = "Increases the attack speed at cost of 3% of the target max Hp per second, during this time the hero cannot be stunned or disarmed. (40s CD)"
set id.tier1Text = "40% AS, 4s Duration"
set id.tier2Text = "50% AS, 5s Duration"
set id.tier3Text = "60% AS, 6s Duration"
set id.abilityID = 'A07E'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,10)
call id.AddBonus(BONUS_TYPE_LIFESTEAL,"Lifesteal",10,10)
call id.AddBonus(BONUS_TYPE_LIFE_REGEN,"Life Regen",2,1)
set id = ItemData.create('wcyc')
set id.goldCost = 1600
set id.abilityName = "Icy Blasts"
set id.abilityText = "Increases wielder's armor for 6 seconds, each second apply frost to all enemies around (400 AoE) dealing magical damage.(45s CD)"
set id.tier1Text = "+6 Armor, 40 Damage"
set id.tier2Text = "+8 Armor, 50 Damage"
set id.tier3Text = "+10 Armor, 60 Damage"
set id.abilityID = 'A03D'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",20,20)
set id = ItemData.create('fgsk')
set id.goldCost = 1200
set id.abilityName = "Sea Walker"
set id.abilityText = "When the wielder enters combat increases the movement speed and evasion for 15 seconds, the bonuses increases the more you move. Up to 70 Ms and 96(15.0%) Evasion."
set id.tier1Text = "8s of movement to get the max bonuses"
set id.tier2Text = "7s of movement to get the max bonuses"
set id.tier3Text = "6s of movement to get the max bonuses"
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",5,5)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",5,5)
call id.AddBonus(BONUS_TYPE_MANA_REGEN,"Mana Regen",2,1)
endfunction
endscope
scope MagicBuffs initializer init
globals
Effect SN_EFFECT
endglobals
struct MagicBulwark extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0DC'
set BUFF_DATA.BuffID = 'B05X'
set BUFF_DATA.Name = "Magic Bulwark"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct BindingChain extends array
Lightning l
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call l.destroy()
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real xs
local real ys
local real x
local real y
local real a
if not Status.UnitHasStatus(STATUS_DISARM,b.target) then
set b.removeInside = true
else
set xs = GetUnitX(b.owner)
set ys = GetUnitY(b.owner)
set x = GetUnitX(b.target)
set y = GetUnitY(b.target)
set a = Angle(x,y,xs,ys)
if Distance(xs,ys,x,y) >= 5.0 then
set x = x + 5.0 * Cos(a)
set y = y + 5.0 * Sin(a)
call SetUnitX(b.target,x)
call SetUnitY(b.target,y)
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set l = Lightning.create("WHCH",b.owner,b.target,9999,0.00,120,120)
call l.setLightColor(128,128,128,255)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Binding Chain"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct FelSeal extends array
real time
real dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Undead\\UDeathSmall\\UDeathSmall.mdl",b.target,"chest"))
call CodeDamage.Damage(b.owner,b.target,dmg * (time / 0.50) ,udg_DamageTypeMagic,"",0,0)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if not Status.UnitHasStatus(STATUS_SILENCE,b.target) then
set b.removeInside = true
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 20.00 + 10.00 * b.level
set time = b.duration
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A04G'
set BUFF_DATA.BuffID = 'B05C'
set BUFF_DATA.Name = "Fel Seal"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct SeaWalker extends array
Movespeed ms
integer msTotal
integer evasionTotal
real timeTotal
real time
integer percent
Item itemSW
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,-evasionTotal,0)
call SetItemCharges(itemSW.itemS,0)
call ms.destroy()
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer p
if IsUnitMoving(b.target) then
set time = time + 0.03125
set p = R2I(time/timeTotal * 100)
if ModuloReal(time,1.0) == 0.0 and time <= timeTotal then
call SetItemCharges(itemSW.itemS,R2I(time/1.0))
endif
if percent != p and p <= 100 then
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,-evasionTotal,0)
set percent = p
set msTotal = (70 * p) / 100
set evasionTotal = (96 * p) / 100
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,evasionTotal,0)
call ms.change(0,msTotal)
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set time = 0.00
set timeTotal = 9 - 1.00 * b.level
set evasionTotal = 0
set msTotal = 0
set percent = 0
set ms = Movespeed.create(b.target,0,0)
set itemSW = b.int
call SetItemCharges(itemSW.itemS,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A03F'
set BUFF_DATA.BuffID = 'B059'
set BUFF_DATA.Name = "Sea Walker"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct IcyBlasts extends array
real dmg
group enum
player owner
integer armor
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ReleaseGroup(enum)
set enum = null
set owner = null
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-armor,0,true)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local unit temp
local effect sfx = AddSpecialEffect("war3mapImported\\FreezingRing.mdx",GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectScale(sfx,1.5)
call BlzSetSpecialEffectTimeScale(sfx,1.5)
call DestroyEffect(sfx)
set sfx = null
call GroupClear(enum)
call GroupEnumUnitsInRange(enum,GetUnitX(b.target),GetUnitY(b.target),400.00,null)
loop
set temp = FirstOfGroup(enum)
exitwhen temp == null
call GroupRemoveUnit(enum,temp)
if FILT_UNIT_ENEMY(temp,owner) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(b.owner,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_FROST,temp,1.5,0)
endif
endloop
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 30.00 + 10.00 * b.level
set armor = 4 + 2 * b.level
set enum = NewGroup()
set owner = GetOwningPlayer(b.target)
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A03E'
set BUFF_DATA.BuffID = 'B058'
set BUFF_DATA.Name = "IcyBlasts"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct FrenzyFOB extends array
real hp
integer as
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call AddUnitStatusReduction(STATUS_STUN,b.target,0,false)
call AddUnitStatusReduction(STATUS_DISARM,b.target,0,false)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitRemoveHp(b.target,hp)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = 30 + 10 * b.level
set hp = (BlzGetUnitMaxHP(b.target) * 0.03) / 2
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call AddUnitStatusReduction(STATUS_STUN,b.target,0,true)
call AddUnitStatusReduction(STATUS_DISARM,b.target,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A06L'
set BUFF_DATA.BuffID = 'B04Z'
set BUFF_DATA.Name = "Frenzy"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Purge extends array
Movespeed ms
integer as
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = 10 * b.int
set ms = Movespeed.create(b.target,-( 0.20 + 0.05 * b.int),0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call CreateTextTagForAll(GetUnitX(b.target),GetUnitY(b.target),"|c008080ff"+"x"+I2S(b.int),12)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AR'
set BUFF_DATA.BuffID = 'B03V'
set BUFF_DATA.Name = "Purge"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
function UnstableDarkDamage takes unit source, unit target, integer lvl, real dmg returns nothing
local group g = NewGroup()
local player owner = GetOwningPlayer(source)
local real dmgp = dmg * 0.40 + 0.20 * lvl
local unit temp
local effect sfx
call GroupEnumUnitsInRange(g,GetUnitX(target),GetUnitY(target),250,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,owner) and not IsUnitMagicImmune(temp) and temp != target then
call CodeDamage.Damage(source,temp,dmgp,udg_DamageTypeMagicAoe,"UDDamage",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set owner = null
set sfx = AddSpecialEffect("war3mapImported\\DarkNova.mdx",GetUnitX(target),GetUnitY(target))
call BlzSetSpecialEffectScale(sfx,0.20)
call DestroyEffect(sfx)
set sfx = null
endfunction
struct ShadowWalk extends array
private static method onRemove takes Buff b returns nothing
call Status.Remove(STATUS_INVISIBILITY,b.target)
endmethod
private static method onApply takes Buff b returns nothing
call Status.Add(STATUS_INVISIBILITY,b.target,0,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CX'
set BUFF_DATA.BuffID = 'B05O'
set BUFF_DATA.Name = "ShadowWalk"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct MagicEater extends array
real sl
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,b.target,-sl,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set sl = 0.05 + 0.10 * b.level
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,b.target,sl,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08K'
set BUFF_DATA.BuffID = 'B032'
set BUFF_DATA.Name = "Magic Eater"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Savage extends array
private static method onRemove takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-120,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,25,0,true)
endmethod
private static method onApply takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,120,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-25,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05Q'
set BUFF_DATA.BuffID = 'B022'
set BUFF_DATA.Name = "Savage"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Slam extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call AddUnitNegativeStatusReduction(b.target,0.45,false)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,45,0,true)
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call AddUnitNegativeStatusReduction(b.target,-0.45,false)
set ms = Movespeed.create(b.target,-0.45,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-45,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08Z'
set BUFF_DATA.BuffID = 'B039'
set BUFF_DATA.Name = "Slam"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct UnholyRegeneration extends array
integer lr
integer mr
real hp
real mp
real factor
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,-lr,0)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,-mr,0)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real chp = GetUnitState(b.target,UNIT_STATE_MAX_LIFE)
local real cmp = GetUnitState(b.target,UNIT_STATE_MAX_MANA)
if chp != hp then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,-lr,0)
set lr = R2I(chp * factor)
set hp = chp
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,lr,0)
endif
if cmp != mp then
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,-mr,0)
set mr = R2I(cmp * factor)
set mp = cmp
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,mr,0)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set factor = 0.01 + 0.01 * b.level
set hp = GetUnitState(b.target,UNIT_STATE_MAX_LIFE)
set mp = GetUnitState(b.target,UNIT_STATE_MAX_MANA)
set lr = R2I(hp * factor)
set mr = R2I(mp * factor)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,lr,0)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,mr,0)
set sfx = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\Darksummoning\\DarkSummonTarget.mdl",b.target,"origin")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A090'
set BUFF_DATA.BuffID = 'B03A'
set BUFF_DATA.Name = "Unholy Regeneration"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct DivineWordBuff extends array
real dps
integer hr
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,-hr)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,-hr)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dps,udg_DamageTypeHeal,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dps = 20 * b.level
set hr = 60 * b.level
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,hr)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,hr)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A094'
set BUFF_DATA.BuffID = 'B03B'
set BUFF_DATA.Name = "Divine Word"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.00
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct DivineWordDebuff extends array
real dps
integer hr
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,hr)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,hr)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dps,udg_DamageTypeMagicOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dps = 20 * b.level
set hr = 60 * b.level
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,-hr)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,-hr)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0A5'
set BUFF_DATA.BuffID = 'B03Q'
set BUFF_DATA.Name = "Divine Word Debuff"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.00
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Cripple extends array
real dmgRed
Movespeed ms
integer as
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = 15 + 5 * b.level
set ms = Movespeed.create(b.target,-(0.15 + 0.05 * b.level),0)
set dmgRed = 0.15 + 0.05 * b.level
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A09M'
set BUFF_DATA.BuffID = 'B03L'
set BUFF_DATA.Name = "Cripple"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct VampiricAura extends array
private static method OnEffect takes unit u, Aura a returns nothing
local real r = 0.06 + 0.06 * a.level
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,u,r,0)
endmethod
private static method OnEndEffect takes unit u, Aura a returns nothing
local real r = 0.06 + 0.06 * a.level
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,u,-r,0)
endmethod
implement AuraCore
endstruct
private function InfernalActions takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local group g = NewGroup()
local unit u = tb.unit[0]
local player p = GetOwningPlayer(u)
local unit temp
local real dmg = 60.00 + 70.00 * tb.integer[3]
call GroupEnumUnitsInRange(g,tb.real[1],tb.real[2],200.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_STUN,temp,1.30,Status_EFFECT[STATUS_STUN])
endif
endloop
call ReleaseGroup(g)
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set g = null
set p = null
set u = null
set t = null
endfunction
function InfernalDamage takes unit u, real x, real y, integer lvl returns nothing
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
set tb.unit[0] = u
set tb.real[1] = x
set tb.real[2] = y
set tb.integer[3] = lvl
call TimerStart(t,1.0,false,function InfernalActions)
set t = null
endfunction
function SpiderNetCast takes unit u, integer lvl, real x, real y returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local unit temp
call GroupEnumUnitsInRange(g,x,y,300.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call MissileSpiderNet(u,temp,lvl)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endfunction
private struct SlamChain extends array
implement Alloc
real x
real y
effect sfx
public method destroy takes nothing returns nothing
call BlzSetSpecialEffectAlpha(sfx,0)
call DestroyEffect(sfx)
set sfx = null
call this.deallocate()
endmethod
public static method create takes real x, real y, effect sfx returns thistype
local thistype this = thistype.allocate()
set .x = x
set .y = y
set .sfx = sfx
return this
endmethod
endstruct
private function SlamCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local LinkedList list = tb.integer[4]
local integer c = tb.integer[5]
local real a = tb.real[6]
local SlamChain sc
local effect sfx
local real x
local real y
local Link h
local group g
local player p
local unit temp
if c != 0 then
set h = list.head
if h == 0 then
set x = GetUnitX(u) + 50 * Cos(a)
set y = GetUnitY(u) + 50 * Sin(a)
set sfx = AddSpecialEffect("war3mapImported\\ChainElement.mdx",x,y)
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectScale(sfx,2.0)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 50.00)
call BlzSetSpecialEffectColor(sfx,128,128,128)
set sc = SlamChain.create(x,y,sfx)
else
set sc = h.data
set x = sc.x + 50 * Cos(a)
set y = sc.y + 50 * Sin(a)
set sfx = AddSpecialEffect("war3mapImported\\ChainElement.mdx",x,y)
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectScale(sfx,2.0)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 50.00)
call BlzSetSpecialEffectColor(sfx,128,128,128)
set sc = SlamChain.create(x,y,sfx)
endif
call list.add(sc)
set c = c - 1
set tb.integer[5] = c
else
set h = list.last
set sc = h.data
call SetUnitX(u,sc.x)
call SetUnitY(u,sc.y)
call list.remove(h)
call sc.destroy()
if list.head == 0 then
set x = tb.real[1]
set y = tb.real[2]
call SetUnitX(u,x)
call SetUnitY(u,y)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl",x,y))
set g = NewGroup()
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,x,y,270.00,null)
set a = 100.00 + 50.00 * tb.integer[3]
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,a,udg_DamageTypeMagicAoe,"",0,0)
call UnitAddBuff(temp,u,6.0,Slam.buff,0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
call Status.Remove(STATUS_DISARM,u)
call Status.Remove(STATUS_UNTURN,u)
call Status.Remove(STATUS_UNPATH,u)
call ReleaseTimer(t)
call tb.flush()
call tb.destroy()
call list.destroy()
endif
endif
set t = null
set u = null
set sfx = null
endfunction
function SlamCast takes unit u, real x, real y, integer lvl returns nothing
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
set tb.unit[0] = u
set tb.real[1] = x
set tb.real[2] = y
set tb.integer[3] = lvl
set tb.integer[4] = LinkedList.create()
set tb.integer[5] = R2I(Distance(GetUnitX(u),GetUnitY(u),x,y) / 50)
set tb.real[6] = Angle(GetUnitX(u),GetUnitY(u),x,y)
call Status.Add(STATUS_DISARM,u,0,0)
call Status.Add(STATUS_UNTURN,u,0,0)
call Status.Add(STATUS_UNPATH,u,0,0)
call TimerStart(t,0.03125,true,function SlamCallback)
set t = null
endfunction
private function init takes nothing returns nothing
call MagicBulwark.Initialize()
call Purge.Initialize()
call ShadowWalk.Initialize()
call MagicEater.Initialize()
call Savage.Initialize()
call Slam.Initialize()
call UnholyRegeneration.Initialize()
call DivineWordBuff.Initialize()
call DivineWordDebuff.Initialize()
call Cripple.Initialize()
call VampiricAura.Initialize()
call FrenzyFOB.Initialize()
call IcyBlasts.Initialize()
call SeaWalker.Initialize()
call FelSeal.Initialize()
call BindingChain.Initialize()
set SN_EFFECT = Effect.create("Abilities\\Spells\\Undead\\Web\\Web_AirTarget.mdl","chest")
endfunction
endscope
scope TrinketData
public function Setup takes nothing returns nothing
local ItemData id = ItemData.create('ckng')
set id.goldCost = 1400
set id.abilityName = "Inspiration"
set id.abilityText = "Each second in combat, increases wielder's main attribute by 1 until leaving combat."
set id.tier1Text = "10 Max Bonus"
set id.tier2Text = "15 Max Bonus"
set id.tier3Text = "20 Max Bonus"
call id.AddBonus(BONUS_TYPE_ALL_STATS,"All Stats",5,3)
set id = ItemData.create('modt')
set id.goldCost = 1000
set id.abilityName = "Mana Recover"
set id.abilityText = "Restores an amount of mana to nearby allied units.(45s CD)"
set id.tier1Text = "Restores 90 + 8% of Missing Mana."
set id.tier2Text = "Restores 120 + 10% of Missing Mana."
set id.tier3Text = "Restores 150 + 12% of Missing Mana."
set id.abilityID = 'AImr'
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",100,50)
set id = ItemData.create('ofro')
set id.goldCost = 1200
set id.abilityName = "Ancient Heal"
set id.abilityText = "Heals the target ally every second for 8 seconds also increases all healing done to the target by a %.(25s CD)"
set id.tier1Text = "35 Heal, 20% increased healing"
set id.tier2Text = "45 Heal, 25% increased healing"
set id.tier3Text = "55 Heal, 30% increased healing"
set id.abilityID = 'A065'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",10,5)
set id = ItemData.create('rde4')
set id.goldCost = 1200
set id.abilityName = "Untouchable"
set id.abilityText = "Always miss the first attack received once every 3 seconds and each attack evaded gives a charge that adds bonus evasion. Up to 5 charges."
set id.tier1Text = "20(3.1%) Evasion"
set id.tier2Text = "40(6.2%) Evasion"
set id.tier3Text = "60(9.3%) Evasion"
set id.abilityID = 'A05Z'
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,5)
set id = ItemData.create('tkno')
set id.goldCost = 1200
set id.abilityName = "Hard Skin"
set id.abilityText = "Every time the wielder blocks an attack recovers 5% of his max Hp."
set id.tier1Text = "6s Cooldown"
set id.tier2Text = "5s Cooldown"
set id.tier3Text = "4s Cooldown"
set id.abilityID = 'A060'
call id.AddBonus(BONUS_TYPE_BLOCK,"Block",20,20)
set id = ItemData.create('rde1')
set id.goldCost = 1000
set id.abilityName = "Defibrillator"
set id.abilityText = "Blocks a negative status once per cooldown and makes the wielder immune to any status for 2 seconds."
set id.tier1Text = "20s Cooldown"
set id.tier2Text = "17s Cooldown"
set id.tier3Text = "14s Cooldown"
set id.abilityID = 'A061'
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",100,50)
set id = ItemData.create('rde2')
set id.goldCost = 1000
set id.abilityName = "Area Healing"
set id.abilityText = "Upon activation heals all nearby allies (700 AoE), the amount healed is increased by 40 for each allied hero in range. (50s CD)"
set id.tier1Text = "120 Healing"
set id.tier2Text = "180 Healing"
set id.tier3Text = "240 Healing"
set id.abilityID = 'A062'
call id.AddBonus(BONUS_TYPE_LIFE_REGEN,"Life Regen",2,2)
set id = ItemData.create('rde3')
set id.goldCost = 1200
set id.abilityName = "Spell Boost"
set id.abilityText = "Casting a spell gives 1 charge which adds 3% spell damage amplification for 6 seconds."
set id.tier1Text = "4 Max Charges"
set id.tier2Text = "6 Max Charges"
set id.tier3Text = "8 Max Charges"
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",30,20)
set id = ItemData.create('prvt')
set id.goldCost = 1200
set id.abilityName = "Brave Fight"
set id.abilityText = "Each second in combat, increases the attack damage and spell strength until leaving combat."
set id.tier1Text = "Up to 24 Attack Damage and 48(7.5%) Spell Strength."
set id.tier2Text = "Up to 36 Attack Damage and 60(9.3%) Spell Strength."
set id.tier3Text = "Up to 48 Attack Damage and 72(11.25%) Spell Strength."
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",10,5)
set id = ItemData.create('desc')
set id.goldCost = 1200
set id.abilityName = "Vampiric Blood"
set id.abilityText = "Each attack has 30% chance to increase the damage and lifesteal for 7 seconds."
set id.tier1Text = "+10 Damage, +10% Lifesteal"
set id.tier2Text = "+20 Damage, +20% Lifesteal"
set id.tier3Text = "+30 Damage, +30% Lifesteal"
call id.AddBonus(BONUS_TYPE_ATTACK_STRENGTH,"Attack Strength",30,20)
set id = ItemData.create('I00A')
set id.goldCost = 1200
set id.abilityName = "Portal"
set id.abilityText = "Teleports the wielder to any place in the map, has 4 seconds delay."
set id.tier1Text = "60s Cooldown"
set id.tier2Text = "50s Cooldown"
set id.tier3Text = "40s Cooldown"
set id.abilityID = 'A0A0'
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",10,10)
set id = ItemData.create('I00B')
set id.goldCost = 1000
set id.abilityName = "Moon's Grace"
set id.abilityText = "Reduces the critical damage of all sources of damage (is doubled during night)."
set id.tier1Text = "5% Reduction"
set id.tier2Text = "10% Reduction"
set id.tier3Text = "15% Reduction"
call id.AddBonus(BONUS_TYPE_SIGHT_RANGE,"Sight Range",100,50)
set id = ItemData.create('whwd')
set id.goldCost = 1000
set id.abilityName = "Rocket Jump"
set id.abilityText = "The wielder jumps to the target location and dispels all Status that disrupt movement."
set id.tier1Text = "800 distance, 40 CD"
set id.tier2Text = "900 distance, 35 CD"
set id.tier3Text = "1000 distance, 30 CD"
set id.abilityID = 'A05F'
set id.abilityID2 = 'A08I'
call id.AddBonus(BONUS_TYPE_NOTHING,"Movement Speed",30,5)
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",10,5)
set id = ItemData.create('dust')
set id.goldCost = 1200
set id.abilityName = "Safe Step"
set id.abilityText = "Reduces movement speed but blocks 100% of the enemy attacks. Lasts 4 seconds. (10s CD)"
set id.tier1Text = "-25% Movement Speed"
set id.tier2Text = "-20% Movement Speed"
set id.tier3Text = "-15% Movement Speed"
set id.abilityID = 'A05I'
set id.abilityID2 = 'A08I'
call id.AddBonus(BONUS_TYPE_NOTHING,"Movement Speed",30,10)
set id = ItemData.create('sror')
set id.goldCost = 1200
set id.abilityName = "Blink"
set id.abilityText = "Allows the hero to teleport to the targeted point. The Cooldown and distance is shorted by 50% while in combat."
set id.tier1Text = "18s CD, 1000 Distance"
set id.tier2Text = "14s CD, 1200 Distance"
set id.tier3Text = "10s CD, 1400 Distance"
set id.abilityID = 'AIbk'
set id.abilityID2 = 'A08I'
call id.AddBonus(BONUS_TYPE_NOTHING,"Movement Speed",30,10)
set id = ItemData.create('fgdg')
set id.goldCost = 1200
set id.abilityName = "Impulse"
set id.abilityText = "Enter combat and every 6 seconds increases the Movement Speed and Attack Speed for 3 seconds."
set id.tier1Text = "+10% MS and AS"
set id.tier2Text = "+20% MS and AS"
set id.tier3Text = "+30% MS and AS"
set id.abilityID = 'A08I'
call id.AddBonus(BONUS_TYPE_NOTHING,"Movement Speed",30,10)
set id = ItemData.create('wswd')
set id.goldCost = 1000
set id.abilityName = "Wanderer Steps"
set id.abilityText = "While out of combat increases the Life and Mana regeneration by a %."
set id.tier1Text = "100% Regen"
set id.tier2Text = "150% Regen"
set id.tier3Text = "200% Regen"
set id.abilityID = 'A08I'
call id.AddBonus(BONUS_TYPE_NOTHING,"Movement Speed",30,10)
set id = ItemData.create('I006')
set id.goldCost = 1000
set id.abilityName = "Summon Golem"
set id.abilityText = "Summons a sluggish golem that has 1000 Hp, 10 Armor and 45 Damage, can cast Stomp (8s CD) to stun the enemies around for 1s dealing 75 damage. The Hp of the golem scales with the wielder's Hp.(100s CD)"
set id.tier1Text = "20% of Hero Hp, 40s Duration"
set id.tier2Text = "25% of Hero Hp, 50s Duration"
set id.tier3Text = "30% of Hero Hp, 60s Duration"
set id.abilityID = 'AIfu'
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",50,50)
set id = ItemData.create('I00C')
set id.goldCost = 1400
set id.abilityName = "Restart"
set id.abilityText = "Upon casting restart the cooldown of hero abilities or items."
set id.tier1Text = "220s Cooldown, up to 3 Cooldowns."
set id.tier2Text = "200s Cooldown, up to 4 Cooldowns."
set id.tier3Text = "180s Cooldown, up to 5 Cooldowns."
set id.abilityID = 'A02S'
call id.AddBonus(BONUS_TYPE_HP,"Mana Points",100,50)
set id = ItemData.create('I00A')
set id.goldCost = 1400
set id.abilityName = "Witchcraft"
set id.abilityText = "Each 3rd hero or item spell casted gives to the wielder a shield that absorbs an amount of damage, lasts 4 seconds (the counter is disabled while shielded)."
set id.tier1Text = "150 Absorption"
set id.tier2Text = "190 Absorption"
set id.tier3Text = "230 Absorption"
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,2)
set id = ItemData.create('I00T')
set id.goldCost = 1400
set id.abilityName = "Assimilate"
set id.abilityText = "After receive spell damage that makes the wielder's life drops below 25%, reduces all damage from spells by 90%, stun the wielder and heals Hp periodically lasts 4.5 seconds."
set id.tier1Text = "40 Heal, 70s CD"
set id.tier2Text = "60 Heal, 60s CD"
set id.tier3Text = "80 Heal, 50s CD"
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",30,20)
set id = ItemData.create('pdiv')
set id.goldCost = 1400
set id.abilityName = "Phoenix Fire"
set id.abilityText = "The spell damage inflicted gives 1% bonus spell critical chance for 1.5 seconds."
set id.tier1Text = "Up to 15% Critical Bonus"
set id.tier2Text = "Up to 20% Critical Bonus"
set id.tier3Text = "Up to 25% Critical Bonus"
set id.abilityID = 'A05J'
call id.AddBonus(BONUS_TYPE_SPELL_LIFESTEAL,"Spell Lifesteal",10,5)
endfunction
endscope
scope TrinketBuffs initializer init
struct Defibrillator extends array
private static method onRemove takes Buff b returns nothing
call AddUnitNegativeStatusReduction(b.target,0,false)
endmethod
private static method onApply takes Buff b returns nothing
call AddUnitNegativeStatusReduction(b.target,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CY'
set BUFF_DATA.BuffID = 'B05P'
set BUFF_DATA.Name = "Defibrillator Immunity"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Assimilate extends array
real heal
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_STUN,b.target)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.target,b.target,heal,udg_DamageTypeHealOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set heal = (20 + 20 * b.level) / 9
call Status.Add(STATUS_STUN,b.target,0,Status_EFFECT[STATUS_STUN])
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A048'
set BUFF_DATA.BuffID = 'B05B'
set BUFF_DATA.Name = "Assimilate"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Inspiration extends array
integer statChoosed
integer stat
integer c
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
call BonusStruct.Add(statChoosed,b.target,-c,0,true)
call SetItemCharges(it.itemS,0)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
if c < stat then
set c = c + 1
call BonusStruct.Add(statChoosed,b.target,1,0,true)
call SetItemCharges(it.itemS,c)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Hero h = GetUnitData(b.target,"HeroIndex")
set stat = 5 + 5 * b.level
if h != 0 then
if h.PrimaryAttribute == 1 then
set statChoosed = BONUS_TYPE_AGILITY
elseif h.PrimaryAttribute == 2 then
set statChoosed = BONUS_TYPE_INTELLIGENCE
else
set statChoosed = BONUS_TYPE_STRENGTH
endif
endif
set c = 0
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05T'
set BUFF_DATA.BuffID = 'B025'
set BUFF_DATA.Name = "Inspiration"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct AncientHeal extends array
real heal
real amp
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,heal,udg_DamageTypeHealOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set heal = 25 + 10 * b.level
set amp = 0.15 + 0.05 * b.level
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05U'
set BUFF_DATA.BuffID = 'B026'
set BUFF_DATA.Name = "Ancient Heal"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Untouchable extends array
real eva
private static method onStackRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,-eva,0)
call SetItemCharges(it.itemS,0)
endmethod
private static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
set eva = 20 * b.level
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,eva,0)
call SetItemCharges(it.itemS,b.stacks)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05V'
set BUFF_DATA.BuffID = 'B027'
set BUFF_DATA.Name = "Untouchable"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
/*struct EarthSkin extends array
integer ar
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-ar,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ar = 1 + 1 * b.level
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,ar,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05W'
set BUFF_DATA.BuffID = 'B028'
set BUFF_DATA.Name = "Earth Skin"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct*/
struct SpellBoost extends array
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.level
if b.elapsedTime == b.duration then
call SetItemCharges(it.itemS,0)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05X'
set BUFF_DATA.BuffID = 'B029'
set BUFF_DATA.Name = "Spell Boost"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct BraveFight extends array
integer dmg
integer c
real spstr
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg * c,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,-spstr * c,0)
call SetItemCharges(it.itemS,0)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
if 12 > c then
set c = c + 1
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,spstr,0)
call SetItemCharges(it.itemS,c)
set b.elapsedTime = 0.0
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
set dmg = 1 + 1 * b.level
set spstr = 3 + 1 * b.level
set c = 0
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A06S'
set BUFF_DATA.BuffID = 'B02G'
set BUFF_DATA.Name = "Brave Fight"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct VampiricBlood extends array
integer dmg
real ls
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,-ls,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 10 * b.level
set ls = 0.10 * b.level
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,ls,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08V'
set BUFF_DATA.BuffID = 'B038'
set BUFF_DATA.Name = "Vampiric Blood"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Impulse extends array
integer as
Movespeed ms
private static method Reimpulse takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
if IsUnitInCombat(u) and GetUnitAbilityLevel(u,'A0D7') != 0 then
call UnitAddBuff(u,u,3.0,Impulse.buff,tb.integer[1],0)
endif
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set t = null
set u = null
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Table tb = Table.create()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call ms.destroy()
set tb.unit[0] = b.target
set tb.integer[1] = b.level
call TimerStart(NewTimerEx(tb),3.0,false,function thistype.Reimpulse)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = 8 * b.level
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
set ms = Movespeed.create(b.target,0.05 + 0.05 * b.level,0)
call BlzStartUnitAbilityCooldown(b.target,'A0D7',6.0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05E'
set BUFF_DATA.BuffID = 'B020'
set BUFF_DATA.Name = "Impulse"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct SafeStep extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-(0.30 - 0.05 * b.level),0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05P'
set BUFF_DATA.BuffID = 'B021'
set BUFF_DATA.Name = "Safe Step"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct WandererSteps extends array
integer r
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,-r)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,-r)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set r = 50 + 50 * b.level
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,r)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,r)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0B8'
set BUFF_DATA.BuffID = 'B047'
set BUFF_DATA.Name = "Wanderer Steps"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function DECallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Item it = GetTimerData(t)
call AddStatusNegation(it.wielder)
call SetItemDroppable(it.itemS,true)
call SetItemPawnable(it.itemS,true)
call ReleaseTimer(t)
set t = null
endfunction
public function DefibrillatorCD takes integer st, Item it returns nothing
local timer t = NewTimerEx(it)
local real cd = 23.00 - 3.00 * it.tier
call BlzStartUnitAbilityCooldown(it.wielder,'A061',cd)
call UnitAddBuff(it.wielder,it.wielder,2.0,Defibrillator.buff,0,0)
call SetItemDroppable(it.itemS,false)
call SetItemPawnable(it.itemS,false)
call TimerStart(t,cd,false,function DECallback)
set t = null
endfunction
function RecalibratorWatch takes unit u, Item it returns nothing
local Hero h = GetUnitData(u,"HeroIndex")
local LinkedList inv = GetUnitData(u,"UnitItems")
local integer c = 2 + 1 * it.tier
local integer i = 0
local Ability a
local Link node
local Item it2
if h.traitAbility != 0 and BlzGetUnitAbilityCooldownRemaining(u,h.traitAbility) != 0 then
set c = c - 1
call BlzEndUnitAbilityCooldown(u,h.traitAbility)
endif
loop
set i = i + 1
exitwhen i > 6
set a = h.Abilities.integer[i]
if c != 0 and a != 0 then
if a.isOnCooldown() then
set c = c - 1
call a.resetCooldown()
endif
endif
endloop
if inv != 0 then
set node = inv.head
loop
exitwhen node == 0
set it2 = node.data
if it2.abilityID != 0 and c != 0 and it2 != it then
if BlzGetUnitAbilityCooldownRemaining(u,it2.abilityID) != 0 then
set c = c - 1
call BlzEndUnitAbilityCooldown(u,it2.abilityID)
endif
endif
set node = node.next
endloop
endif
endfunction
function AreaHealing takes unit u, Item it returns nothing
local group g = NewGroup()
local group g2 = NewGroup()
local unit temp
local real heal = 60.00 + 60.00 * it.tier
local integer c = 0
local player p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),700,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if IsUnitAlly(temp,p) and not IsUnitHidden(temp) and not IsUnitType(temp,UNIT_TYPE_STRUCTURE) then
if IsUnitType(temp,UNIT_TYPE_HERO) then
set c = c + 1
endif
call GroupAddUnit(g2,temp)
endif
endloop
call ReleaseGroup(g)
set g = null
set heal = heal + 40 * c
loop
set temp = FirstOfGroup(g2)
exitwhen temp == null
call GroupRemoveUnit(g2,temp)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl",temp,"chest"))
call CodeDamage.Damage(u,temp,heal,udg_DamageTypeHeal,"",0,0)
endloop
call ReleaseGroup(g2)
set g2 = null
set p = null
endfunction
function ManaRecover takes unit u, Item it returns nothing
local group g = NewGroup()
local unit temp
local real mana = 60.00 + 30.00 * it.tier
local real mt
local player p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),700,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if IsUnitAlly(temp,p) and BlzGetUnitMaxMana(temp) != 0 then
set mt = GetUnitMissingMana(temp) * (0.06 + 0.02 * it.tier) + mana
call UnitAddMp(temp,mt)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl",temp,"overhead"))
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endfunction
struct ResistanceAura extends array
private static method OnEffect takes unit u, Aura a returns nothing
local integer r = 20 + 20 * a.level
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,r,0)
endmethod
private static method OnEndEffect takes unit u, Aura a returns nothing
local integer r = 20 + 20 * a.level
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,-r,0)
endmethod
implement AuraCore
endstruct
private function PhoenixFireCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Item it = GetTimerData(t)
local Table tb = it.int
local integer i = tb.integer[1]
set i = i - 1
call SetItemCharges(it.itemS,i)
if i == 0 then
call PauseTimer(t)
else
set tb.integer[1] = i
endif
set t = null
endfunction
public function PhoenixFireEnd takes Item it returns nothing
local Table tb = it.int
call ReleaseTimer(tb.timer[0])
call SetItemCharges(it.itemS,0)
call tb.flush()
call tb.destroy()
endfunction
public function PhoenixFireInit takes Item it returns nothing
local Table tb = Table.create()
set it.int = tb
set tb.timer[0] = NewTimerEx(it)
set tb.integer[1] = 0
endfunction
public function PhoenixFireBonus takes Item it returns nothing
local Table tb = it.int
local integer i = tb.integer[1]
if i == 1 then
call TimerStart(tb.timer[0],1.5,true,function PhoenixFireCallback)
endif
if i != 10 + 5 * it.tier then
set i = i + 1
call SetItemCharges(it.itemS,i)
set tb.integer[1] = i
endif
endfunction
private function init takes nothing returns nothing
call Inspiration.Initialize()
call Defibrillator.Initialize()
call AncientHeal.Initialize()
call Untouchable.Initialize()
//call EarthSkin.Initialize()
call SpellBoost.Initialize()
call BraveFight.Initialize()
call VampiricBlood.Initialize()
call Impulse.Initialize()
call SafeStep.Initialize()
call WandererSteps.Initialize()
call Assimilate.Initialize()
call ResistanceAura.Initialize()
endfunction
endscope
scope ArmorData
public function Setup takes nothing returns nothing
local ItemData id = ItemData.create('kybl')
set id.goldCost = 1400
set id.abilityName = "Reactive Armor"
set id.abilityText = "If the wielder is attacked and has less than 35% of his Hp, increasing his Armor, Block and Resistance rating for 10 seconds."
set id.tier1Text = "50(7.8%) Block and Resistance, +2 Armor"
set id.tier2Text = "80(12.5%) Block and Resistance, +4 Armor"
set id.tier3Text = "110(17.1%) Block and Resistance, +6 Armor"
call id.AddBonus(BONUS_TYPE_BLOCK,"Block",30,30)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",30,30)
set id = ItemData.create('ches')
set id.goldCost = 1000
set id.abilityName = "Armor Aura"
set id.abilityText = "Gives an additional armor to nearby friendly units. (900 AoE)"
set id.tier1Text = "+2 Armor"
set id.tier2Text = "+4 Armor"
set id.tier3Text = "+6 Armor"
set id.abilityID = 'A053'
call id.AddBonus(BONUS_TYPE_LIFE_REGEN,"Life Regen",2,2)
call id.AddBonus(BONUS_TYPE_MANA_REGEN,"Mana Regen",2,2)
set id = ItemData.create('bzbe')
set id.goldCost = 1500
set id.abilityName = "King's Blessing"
set id.abilityText = "Gives a shield that absorbs 100 damage + a % of the wielder's hp, if the shield is broken, heals the wielder 50% of the damage absorbed. Lasts 15s (60s CD)"
set id.tier1Text = "12% of Max Hp"
set id.tier2Text = "16% of Max Hp"
set id.tier3Text = "20% of Max Hp"
set id.abilityID = 'A07A'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",3,1)
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",100,100)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",50,50)
set id = ItemData.create('engs')
set id.goldCost = 1500
set id.abilityName = "Consume"
set id.abilityText = "Sacrifices a unit or an amount of Hp from an allied Hero to get bonus Damage and Lifesteal for 20 seconds. (65s CD)"
set id.tier1Text = "250 Hp 20 Dmg 40 Lifesteal"
set id.tier2Text = "350 Hp 30 Dmg 60 Lifesteal"
set id.tier3Text = "450 Hp 40 Dmg 80 Lifesteal"
set id.abilityID = 'A054'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",15,10)
call id.AddBonus(BONUS_TYPE_LIFESTEAL,"Lifesteal",10,10)
set id = ItemData.create('bzbf')
set id.goldCost = 1600
set id.abilityName = "Anti Mage"
set id.abilityText = "Negates the next enemy hero spell."
set id.tier1Text = "35s Cooldown"
set id.tier2Text = "30s Cooldown"
set id.tier3Text = "25s Cooldown"
set id.abilityID = 'A068'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",3,1)
call id.AddBonus(BONUS_TYPE_ALL_STATS,"All Stats",4,4)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",30,30)
set id = ItemData.create('gmfr')
set id.goldCost = 1000
set id.abilityName = "Providence"
set id.abilityText = "Heals an amount of Hp every 1.5s while in combat."
set id.tier1Text = "16 Healing"
set id.tier2Text = "24 Healing"
set id.tier3Text = "32 Healing"
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",10,5)
set id = ItemData.create('ledg')
set id.goldCost = 1000
set id.abilityName = "Forest Blessing"
set id.abilityText = "Every 10 attacks of enemy heroes received heals a % of the missing life for 4 seconds."
set id.tier1Text = "Heal 12% of Missing Life"
set id.tier2Text = "Heal 18% of Missing Life"
set id.tier3Text = "Heal 24% of Missing Life"
set id.abilityID = 'A056'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,2)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",10,5)
set id = ItemData.create('kygh')
set id.goldCost = 1300
set id.abilityName = "Howl of Terror"
set id.abilityText = "Upon activation reduces nearby enemies attack damage and damage they do through spells (500 AoE), lasts 7 seconds.(15s CD)"
set id.tier1Text = "20% Reduction, -10% Spell Damage"
set id.tier2Text = "30% Reduction, -15% Spell Damage"
set id.tier3Text = "40% Reduction, -20% Spell Damage"
set id.abilityID = 'A057'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",75,75)
set id = ItemData.create('gopr')
set id.goldCost = 1200
set id.abilityName = "Energy Barrier"
set id.abilityText = "Upon activation gives a shield that absorbs an amount of spell damage for 15 seconds. (30s CD)"
set id.tier1Text = "275 Shield Life"
set id.tier2Text = "350 Shield Life"
set id.tier3Text = "425 Shield Life"
set id.abilityID = 'A058'
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",50,50)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",30,30)
set id = ItemData.create('azhr')
set id.goldCost = 1000
set id.abilityName = "Snakeskin"
set id.abilityText = "The attacks dodged increases the attack speed for 12 seconds, stackable 6 times"
set id.tier1Text = "5 AS per stack"
set id.tier2Text = "6 AS per stack"
set id.tier3Text = "7 AS per stack"
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_EVASION,"Evasion",30,30)
set id = ItemData.create('cnhn')
set id.goldCost = 1500
set id.abilityName = "Audacity"
set id.abilityText = "When activated increases the mana cost of the hero abilities by 30% but heals the wielder equal to the mana cost of the spells casted, lasts 15s. (80s CD)"
set id.tier1Text = "50% of the mana cost as heal"
set id.tier2Text = "70% of the mana cost as heal"
set id.tier3Text = "90% of the mana cost as heal"
set id.abilityID = 'A0AX'
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",100,50)
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",10,10)
call id.AddBonus(BONUS_TYPE_CD_REDUCTION,"Cooldown Reduction",3,3)
set id = ItemData.create('dkfw')
set id.goldCost = 1400
set id.abilityName = "Void"
set id.abilityText = "Upon taking a total of 600 damage in combat the wielder falls to the void making him invulnerable but disabling the battle capabilities for 2.5 seconds."
set id.tier1Text = "80s CD"
set id.tier2Text = "60s CD"
set id.tier3Text = "40s CD"
set id.abilityID = 'A05C'
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",75,75)
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",10,10)
set id = ItemData.create('k3m1')
set id.goldCost = 1500
set id.abilityName = "Liberty Hand"
set id.abilityText = "Removes all movement impairing effects and heals the target twice with 3 seconds delay. (30s CD)"
set id.tier1Text = "140 Heal"
set id.tier2Text = "200 Heal"
set id.tier3Text = "260 Heal"
set id.abilityID = 'A08N'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",100,50)
call id.AddBonus(BONUS_TYPE_ALL_STATS,"All Stats",5,5)
set id = ItemData.create('mort')
set id.goldCost = 1400
set id.abilityName = "Shining Blast"
set id.abilityText = "The first attack of an enemy hero releases a blast of energy that knockback and blind all nearby enemies within 400 radius, dealing magical damage. Once every 15 seconds."
set id.tier1Text = "120 Damage, Lasts 1.75 seconds"
set id.tier2Text = "160 Damage, Lasts 2.25 seconds"
set id.tier3Text = "200 Damage, Lasts 2.75 seconds"
set id.abilityID = 'A08O'
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",100,50)
call id.AddBonus(BONUS_TYPE_LIFE_REGEN,"Life Regen",2,2)
set id = ItemData.create('k3m3')
set id.goldCost = 1000
set id.abilityName = "Throw Shield"
set id.abilityText = "Throws the shield to the target enemy, dealing Physical Damage and stun for 1.6s. The cooldown is reduced when the wielder blocks an attack and is doubled if is an hero attack.(15s CD)"
set id.tier1Text = "100 Damage, -0.5s cooldown per attack"
set id.tier2Text = "150 Damage, -0.75s cooldown per attack"
set id.tier3Text = "200 Damage, -1s cooldown per attack"
set id.abilityID = 'A05H'
call id.AddBonus(BONUS_TYPE_ALL_STATS,"All Stats",3,3)
call id.AddBonus(BONUS_TYPE_BLOCK,"Block",30,30)
set id = ItemData.create('mgtk')
set id.goldCost = 1000
set id.abilityName = "Nature Aura"
set id.abilityText = "Increases nearby allies mana and life regeneration (900 aoe)."
set id.tier1Text = "+2 Regen"
set id.tier2Text = "+4 Regen"
set id.tier3Text = "+6 Regen"
set id.abilityID = 'A08Q'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",30,30)
set id = ItemData.create('kymn')
set id.goldCost = 1600
set id.abilityName = "Titanic Bless"
set id.abilityText = "Gives magic immunity for 5 seconds."
set id.tier1Text = "50s Cooldown"
set id.tier2Text = "40s Cooldown"
set id.tier3Text = "30s Cooldown"
set id.abilityID = 'A08R'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,2)
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",10,10)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",30,30)
set id = ItemData.create('k3m2')
set id.goldCost = 1600
set id.abilityName = "Molten Spikes"
set id.abilityText = "Upon activation reflects 75% of incoming damage back to the enemy heroes, dealing Pure Damage. Lasts until all instances are used and stuns enemies around for 2s (20s CD)"
set id.tier1Text = "3 instances of damage"
set id.tier2Text = "5 instances of damage"
set id.tier3Text = "7 instances of damage"
set id.abilityID = 'A09J'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,1)
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",100,50)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",30,30)
set id = ItemData.create('jpnt')
set id.goldCost = 1200
set id.abilityName = "Ethereal"
set id.abilityText = "Makes the target unit ethereal for 6s (3s on enemies), deals 2.1x the Main Attribute as Magical Damage. Ethereal units receive 30% more damage from magic spells and heals but are immune to physical damage and attacks."
set id.tier1Text = "35s Cooldown"
set id.tier2Text = "25s Cooldown"
set id.tier3Text = "15s Cooldown"
set id.abilityID = 'A09K'
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",30,30)
call id.AddBonus(BONUS_TYPE_RESISTANCE,"Resistance",30,30)
set id = ItemData.create('phlt')
set id.goldCost = 1200
set id.abilityName = "Healing Stream"
set id.abilityText = "When the wielder suffers a disabling effect, halfs the duration of that effect and heals the wielder over 3 seconds."
set id.tier1Text = "200 Heal, 16s Cooldown"
set id.tier2Text = "250 Heal, 12s Cooldown"
set id.tier3Text = "300 Heal, 8s Cooldown"
set id.abilityID = 'A0CU'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",1,1)
call id.AddBonus(BONUS_TYPE_STATUS_RED,"Status Reduction",5,5)
set id = ItemData.create('sclp')
set id.goldCost = 1400
set id.abilityName = "Stone Skin"
set id.abilityText = "The attackers have 15% chance to get stunned for 0.2s, receiving physical damage based on the armor, each attack against the wielder increases the chance by 1% up to 45%. Resets upon leaving combat."
set id.tier1Text = "25 + 2x Armor to Damage."
set id.tier2Text = "25 + 4x Armor to Damage."
set id.tier3Text = "25 + 6x Armor to Damage."
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",3,2)
call id.AddBonus(BONUS_TYPE_BLOCK,"Block",30,30)
set id = ItemData.create('sorf')
set id.goldCost = 1200
set id.abilityName = "Diamond Spears"
set id.abilityText = "Every time the wielder suffers a critical strike will spread up to 3 diamond spears to enemies in 600 AoE wich deal magical damage. (5s CD) Can be activated manually with 100% increased damage and cooldown."
set id.tier1Text = "80 Damage"
set id.tier2Text = "100 Damage"
set id.tier3Text = "120 Damage"
set id.abilityID = 'A08U'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,2)
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,10)
set id = ItemData.create('vpur')
set id.goldCost = 1400
set id.abilityName = "Viper Counter"
set id.abilityText = "Every time the wielder dodge a hero attack, strike the attacker slowing the movement and attack speed by 35% for 2 seconds and deals your attack damage as physical damage."
set id.tier1Text = "4s Cooldown"
set id.tier2Text = "3s Cooldown"
set id.tier3Text = "2s Cooldown"
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,10)
call id.AddBonus(BONUS_TYPE_EVASION,"Evasion",30,30)
set id = ItemData.create('sxpl')
set id.goldCost = 1600
set id.abilityName = "Reflect"
set id.abilityText = "Upon activation reflects the next enemy spell back to him, lasts 1.5 seconds."
set id.tier1Text = "14s CD"
set id.tier2Text = "12s CD"
set id.tier3Text = "10s CD"
set id.abilityID = 'A03Z'
call id.AddBonus(BONUS_TYPE_HP,"Health Points",75,75)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",75,75)
call id.AddBonus(BONUS_TYPE_STATUS_RED,"Status Reduction",5,5)
endfunction
endscope
scope ArmorBuffs initializer init
struct ViperCounter extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,35,0,true)
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-35,0,true)
set ms = Movespeed.create(b.target,-0.35,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CW'
set BUFF_DATA.BuffID = 'B05N'
set BUFF_DATA.Name = "Viper Counter"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct ForestBlessing extends array
real heal
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.target,b.target,heal,udg_DamageTypeHealOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set heal = GetUnitMissingLife(b.target) * (0.06 + 0.06 * b.level)
set heal = heal / 8
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08G'
set BUFF_DATA.BuffID = 'B030'
set BUFF_DATA.Name = "Forest Blessing"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Reflect extends array
private static method onRemove takes Buff b returns nothing
if b.int == 0 then
call RemoveSpellReflection(b.target)
endif
endmethod
private static method onApply takes Buff b returns nothing
call AddSpellReflection(b.target)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Reflect"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct KingsBlessing extends array
real d
real life
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if life <= 0 then
call CodeDamage.Damage(b.target,b.target,d,udg_DamageTypeHeal,"",0,0)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set life = GetUnitState(b.target,UNIT_STATE_MAX_LIFE) * (0.08 + 0.04 * b.level) + 100
set d = life / 2
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08H'
set BUFF_DATA.BuffID = 'B02L'
set BUFF_DATA.Name = "KingsBlessing"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct ReactiveArmor extends array
real r
integer armor
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-r,0)
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,b.target,-r,0)
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-armor,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set r = 20 + 30 * b.level
set armor = 2 * b.level
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,b.target,r,0)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,r,0)
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A055'
set BUFF_DATA.BuffID = 'B01V'
set BUFF_DATA.Name = "Reactive Armor"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Consume extends array
integer dmg
real ls
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,-ls,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 10 + 10 * b.level
set ls = 0.20 + 0.20 * b.level
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,ls,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A059'
set BUFF_DATA.BuffID = 'B01X'
set BUFF_DATA.Name = "Consume"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Providence extends array
real h
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.target,b.target,h,udg_DamageTypeHealOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set h = 8 + 8 * b.level
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A06P'
set BUFF_DATA.BuffID = 'B02E'
set BUFF_DATA.Name = "Providence"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct HowlOfTerror extends array
public static method ApplyBuff takes unit u, integer lvl returns nothing
local group g = NewGroup()
local unit temp
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),700,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if GetUnitAbilityLevel(u,'BNht') != 0 then
call UnitAddBuff(temp,u,15.00,thistype.buff,lvl,0)
endif
endloop
call ReleaseGroup(g)
set g = null
endmethod
private static method onRemove takes Buff b returns nothing
call UnitRemoveAbility(b.target,'BNht')
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Howl of Terror"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct EnergyBarrier extends array
real life
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set life = 200 + 75 * b.level
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05A'
set BUFF_DATA.BuffID = 'B01W'
set BUFF_DATA.Name = "Energy Bracers"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Snakeskin extends array
integer as
private static method onStackRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call SetItemCharges(it.itemS,0)
endmethod
private static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
set as = 4 + 1 * b.level
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call SetItemCharges(it.itemS,b.stacks)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05B'
set BUFF_DATA.BuffID = 'B01Y'
set BUFF_DATA.Name = "Snakeskin"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 6
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Void extends array
effect sfx
unit dummy
real selec
real size
integer skid
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_DISABLE,b.target)
call Status.Remove(STATUS_INVULNERABLE,b.target)
call BlzSetUnitRealField(b.target,UNIT_RF_SELECTION_SCALE,selec)
call BlzSetUnitSkin(b.target,skid)
call BlzSetUnitRealField(b.target,UNIT_RF_SCALING_VALUE,size)
call RemoveUnit(dummy)
set dummy = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Add(STATUS_DISABLE,b.target,0,0)
call Status.Add(STATUS_INVULNERABLE,b.target,0,0)
set skid = BlzGetUnitSkin(b.target)
set dummy = CreateUnit(GetOwningPlayer(b.target),'nvdl',0,0,0)
call ShowUnit(dummy,false)
call PauseUnit(dummy,true)
set selec = BlzGetUnitRealField(b.target,UNIT_RF_SELECTION_SCALE)
set size = BlzGetUnitRealField(b.target,UNIT_RF_SCALING_VALUE)
call BlzSetUnitSkin(b.target,BlzGetUnitSkin(dummy))
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\BlackHoleSpell.mdx",b.target,"origin"))
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Void"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct LibertyHand extends array
private static method onFinish takes Buff b returns nothing
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Mjolnir.mdx",b.target,"origin"))
call DispelMovilityStatus(b.target)
call UnitDispelAllBuffsType(b.target,EFFECT_TYPE_SLOW)
call CodeDamage.Damage(b.target,b.target,80.00 + 60.00 * b.level,udg_DamageTypeHeal,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Mjolnir.mdx",b.target,"origin"))
call CodeDamage.Damage(b.target,b.target,80.00 + 60.00 * b.level,udg_DamageTypeHeal,"",0,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08S'
set BUFF_DATA.BuffID = 'B035'
set BUFF_DATA.Name = "Liberty Hand"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct ShiningBlast extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08T'
set BUFF_DATA.BuffID = 'B036'
set BUFF_DATA.Name = "Shining Blast"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct MoltenSpikes extends array
effect sfx1
effect sfx2
Item it
integer instances
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g = NewGroup()
local player p = GetOwningPlayer(b.target)
local unit temp
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),250,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call Status.Add(STATUS_STUN,temp,2.0,Status_EFFECT[STATUS_STUN])
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Demon\\ReviveDemon\\ReviveDemon.mdl",temp,"origin"))
endif
endloop
call ReleaseGroup(g)
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
call SetItemCharges(it.itemS,0)
set sfx1 = null
set sfx2 = null
set g = null
set p = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set it = b.int
set instances = 1 + 2 * it.tier
call SetItemCharges(it.itemS,instances + 1)
set sfx1 = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\ThornyShield\\ThornyShieldTargetChestMountLeft.mdl",b.target,"chest")
set sfx2 = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\ThornyShield\\ThornyShieldTargetChestMountRight.mdl",b.target,"chest")
call BlzSetSpecialEffectColor(sfx1,255,0,0)
call BlzSetSpecialEffectColor(sfx2,255,0,0)
call BlzSetSpecialEffectScale(sfx1,1.5)
call BlzSetSpecialEffectScale(sfx2,1.5)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Molten Spikes"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct NatureAura extends array
private static method OnEffect takes unit u, Aura a returns nothing
local integer r = 2 * a.level
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,u,r,0)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,u,r,0)
endmethod
private static method OnEndEffect takes unit u, Aura a returns nothing
local integer r = 2 * a.level
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,u,-r,0)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,u,-r,0)
endmethod
implement AuraCore
endstruct
function ApplyShiningBlast takes unit u, integer lvl returns nothing
local player p = GetOwningPlayer(u)
local group g = NewGroup()
local real d = 3 + 1 * lvl
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local effect sfx = AddSpecialEffect("war3mapImported\\Holy Nova.mdx",x,y)
local real dmg = 80 + 40 * lvl
local unit temp
call BlzSetSpecialEffectScale(sfx,1.0)
call DestroyEffect(sfx)
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),400,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call UnitAddBuff(temp,u,d,ShiningBlast.buff,0,0)
call KPJUnit.create(temp,200,Angle(x,y,GetUnitX(temp),GetUnitY(temp)),0.60,0,KPJDefaultConfig,KPJ_TYPE_KNOCKBACK)
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set sfx = null
endfunction
struct HealingStream extends array
real h
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.target,b.target,h,udg_DamageTypeHealOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set h = (150 + 50 * b.level)/6
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08P'
set BUFF_DATA.BuffID = 'B037'
set BUFF_DATA.Name = "HealingStream"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Audacity extends array
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Ability.HeroAbilitiesAddManaCostPercent(b.target,-30)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Ability.HeroAbilitiesAddManaCostPercent(b.target,30)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AY'
set BUFF_DATA.BuffID = 'B040'
set BUFF_DATA.Name = "Audacity"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function AMCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Item it = GetTimerData(t)
call AddSpellNegation(it.wielder)
call SetItemDroppable(it.itemS,true)
call SetItemPawnable(it.itemS,true)
call ReleaseTimer(t)
set t = null
endfunction
public function AntiMageCD takes Item it returns nothing
local timer t = NewTimerEx(it)
local real cd = 40.00 - 5.00 * it.tier
call BlzStartUnitAbilityCooldown(it.wielder,'A068',cd)
call SetItemDroppable(it.itemS,false)
call SetItemPawnable(it.itemS,false)
call TimerStart(t,cd,false,function AMCallback)
set t = null
endfunction
function DiamondSpears takes Item it, integer op returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(it.wielder)
local real dmg = 60.00 + 20.00 * it.tier
local integer count = 3
local unit temp
if op == 2 then
set dmg = dmg * 2
set count = 6
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl",it.wielder,"chest"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl",it.wielder,"right hand"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl",it.wielder,"left hand"))
call GroupEnumUnitsInRange(g,GetUnitX(it.wielder),GetUnitY(it.wielder),600,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null or count == 0
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
set count = count - 1
call MissileDiamondSpear(it.wielder,temp,dmg)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endfunction
private function init takes nothing returns nothing
call ReactiveArmor.Initialize()
call KingsBlessing.Initialize()
call Consume.Initialize()
call Providence.Initialize()
call HowlOfTerror.Initialize()
call EnergyBarrier.Initialize()
call Snakeskin.Initialize()
call Void.Initialize()
call LibertyHand.Initialize()
call ShiningBlast.Initialize()
call HealingStream.Initialize()
call NatureAura.Initialize()
call MoltenSpikes.Initialize()
call Audacity.Initialize()
call Reflect.Initialize()
call ForestBlessing.Initialize()
call ViperCounter.Initialize()
endfunction
endscope
scope WeaponData
public function Setup takes nothing returns nothing
local ItemData id = ItemData.create('rag1')
set id.goldCost = 1200
set id.abilityName = "Forked Lightning"
set id.abilityText = "Strike up to 3 enemies with lightning dealing Magical Damage (x2 Damage to units). The damage is increased by 2 for each unit killed. (30s CD)"
set id.tier1Text = "125 Damage"
set id.tier2Text = "200 Damage"
set id.tier3Text = "275 Damage"
set id.abilityID = 'A04T'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,10)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",10,5)
set id = ItemData.create('tmsc')
set id.goldCost = 1000
set id.abilityName = "Arcane Essence"
set id.abilityText = "Recovers mana upon casting an ability once every 12 seconds."
set id.tier1Text = "20 + 5% of Max Mana"
set id.tier2Text = "20 + 7% of Max Mana"
set id.tier3Text = "20 + 9% of Max Mana"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",10,5)
set id = ItemData.create('rwiz')
set id.goldCost = 1000
set id.abilityName = "Obliterate"
set id.abilityText = "35% chance to increase the damage of normal attacks."
set id.tier1Text = "20 Damage"
set id.tier2Text = "30 Damage"
set id.tier3Text = "40 Damage"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",10,5)
set id = ItemData.create('ssil')
set id.goldCost = 1400
set id.abilityName = "Crusader Shout"
set id.abilityText = "When the wielder enters combat, increases the attack damage and attack speed of nearby allies, lasts 10 seconds."
set id.tier1Text = "25 Damage and Attack Speed"
set id.tier2Text = "35 Damage and Attack Speed"
set id.tier3Text = "45 Damage and Attack Speed"
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",10,5)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,5)
set id = ItemData.create('sbch')
set id.goldCost = 1400
set id.abilityName = "Long Sight"
set id.abilityText = "Upon enter combat increases the wielder's attack range for 10 seconds.|n(Only Works on Ranged heroes)"
set id.tier1Text = "100 Attack Range"
set id.tier2Text = "150 Attack Range"
set id.tier3Text = "200 Attack Range"
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,10)
call id.AddBonus(BONUS_TYPE_ATTACK_STRENGTH,"Attack Strength",30,30)
set id = ItemData.create('bgst')
set id.goldCost = 1500
set id.abilityName = "Execute"
set id.abilityText = "Damage dealt to enemy heroes with less than 20% of their hp is increased by a %."
set id.tier1Text = "+10% damage"
set id.tier2Text = "+12% damage"
set id.tier3Text = "+14% damage"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,10)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,10)
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",10,10)
set id = ItemData.create('brac')
set id.goldCost = 1600
set id.abilityName = "Rage"
set id.abilityText = "Increases damage taken/dealt for all type of damage, including healings. Lasts 15 seconds.(45s CD)"
set id.tier1Text = "15% increase"
set id.tier2Text = "20% increase"
set id.tier3Text = "25% increase"
set id.abilityID = 'A04X'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",20,10)
call id.AddBonus(BONUS_TYPE_ATTACK_STRENGTH,"Attack Strength",20,20)
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",20,20)
set id = ItemData.create('evtl')
set id.goldCost = 1200
set id.abilityName = "Pierce Armor"
set id.abilityText = "The attacks ignore a certain amount of armor."
set id.tier1Text = "2 Armor"
set id.tier2Text = "4 Armor"
set id.tier3Text = "6 Armor"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
call id.AddBonus(BONUS_TYPE_ATTACK_STRENGTH,"Attack Strength",30,30)
set id = ItemData.create('lhst')
set id.goldCost = 1400
set id.abilityName = "Soul Swap"
set id.abilityText = "Absorbs the Hp of the target if is an enemy or transfers Hp if is an allied. Each hero kill increases the value by 25.(60s CD)"
set id.tier1Text = "150 Hp base"
set id.tier2Text = "250 Hp base"
set id.tier3Text = "350 Hp base"
set id.abilityID = 'A04Y'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",10,10)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",10,10)
set id = ItemData.create('belv')
set id.goldCost = 1500
set id.abilityName = "Sinister Mark"
set id.abilityText = "A successful attack, reduces the healing the target receive and the life/mana regeneration for 6 seconds."
set id.tier1Text = "30% reduction"
set id.tier2Text = "35% reduction"
set id.tier3Text = "40% reduction"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",20,10)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,5)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",10,5)
set id = ItemData.create('ward')
set id.goldCost = 1500
set id.abilityName = "Judgement Crown"
set id.abilityText = "Increases/decreases the target's Armor and a % of his Resistance for 8 seconds.(15s CD)"
set id.tier1Text = "4 Armor, 25% Resistance"
set id.tier2Text = "6 Armor, 35% Resistance"
set id.tier3Text = "8 Armor, 45% Resistance"
set id.abilityID = 'A04Z'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,5)
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",10,5)
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",30,30)
set id = ItemData.create('stel')
set id.goldCost = 1300
set id.abilityName = "Swiftness"
set id.abilityText = "Every attack has 20% chance to increase Attack Speed for 7 seconds."
set id.tier1Text = "15% AS"
set id.tier2Text = "30% AS"
set id.tier3Text = "45% AS"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,10)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,5)
set id = ItemData.create('ciri')
set id.goldCost = 1200
set id.abilityName = "Meditation"
set id.abilityText = "The next hero spell casted will have its cooldown reduced, once every 12s."
set id.tier1Text = "-3.5 seconds CD"
set id.tier2Text = "-5 seconds CD"
set id.tier3Text = "-6.5 seconds CD"
set id.abilityID = 'A0D0'
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",75,75)
call id.AddBonus(BONUS_TYPE_MANA_REGEN,"Mana Regen",2,1)
set id = ItemData.create('rlif')
set id.goldCost = 1000
set id.abilityName = "Attack Speed Aura"
set id.abilityText = "Increases nearby friendly units attack speed.(900 AoE)"
set id.tier1Text = "15% AS"
set id.tier2Text = "20% AS"
set id.tier3Text = "25% AS"
set id.abilityID = 'A04U'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,5)
set id = ItemData.create('afac')
set id.goldCost = 1200
set id.abilityName = "Sacrifice"
set id.abilityText = "Sacrifices 25% of your max Hp to gain damage, the Hp is consumed over the duration. Lasts 10 seconds (25s CD)"
set id.tier1Text = "50 Damage"
set id.tier2Text = "70 Damage"
set id.tier3Text = "90 Damage"
set id.abilityID = 'A04S'
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,2)
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",75,75)
set id = ItemData.create('spsh')
set id.goldCost = 1500
set id.abilityName = "Crushing Wave"
set id.abilityText = "The next successful attack sends out a crushing wave towards the enemy, dealing Magic Damage to enemies in a line."
set id.tier1Text = "6s CD, 75 Damage"
set id.tier2Text = "5s CD, 100 Damage"
set id.tier3Text = "4s CD, 125 Damage"
set id.useDummy = true
set id.abilityID = 'A01I'
set id.abilityID2 = 'A02F'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",15,10)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,10)
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",30,30)
set id = ItemData.create('ajen')
set id.goldCost = 1300
set id.abilityName = "Tempest Attack"
set id.abilityText = "Each 3.5s your next attack will release a thunder that deals a % of the damage dealt to the enemy stunning him for 0.75s."
set id.tier1Text = "30% Damage"
set id.tier2Text = "40% Damage"
set id.tier3Text = "50% Damage"
set id.abilityID = 'A04D'
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",10,5)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,5)
set id = ItemData.create('bspd')
set id.goldCost = 1200
set id.abilityName = "Envenomed Shots"
set id.abilityText = "Every 6th ranged attack the wielder will poison the enemy slowing him and dealing damage over time, lasts 3 seconds."
set id.tier1Text = "30% Slow, 25 Dps"
set id.tier2Text = "35% Slow, 50 Dps"
set id.tier3Text = "40% Slow, 75 Dps"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,5)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,10)
set id = ItemData.create('cnob')
set id.goldCost = 1500
set id.abilityName = "Chop"
set id.abilityText = "Chops the target enemy, silencing him for the duration, if the target is attacked will be slowed by 45% for 1.5 seconds (200 cast range). (20s CD)"
set id.tier1Text = "4s Duration"
set id.tier2Text = "6s Duration"
set id.tier3Text = "8s Duration"
set id.abilityID = 'A0A4'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,10)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",10,5)
call id.AddBonus(BONUS_TYPE_ATTACK_STRENGTH,"Attack Strength",30,30)
set id = ItemData.create('ratc')
set id.goldCost = 1400
set id.abilityName = "Skull Bash"
set id.abilityText = "Every certain amount of melee attacks, the wielder will knockback the enemy for 1.5 seconds, dealing physical damage based on the strength."
set id.tier1Text = "7 attacks, 90 Damage + 25% of STR"
set id.tier2Text = "6 attacks, 120 Damage + 35% of STR"
set id.tier3Text = "5 attacks, 150 Damage + 45% of STR"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,10)
call id.AddBonus(BONUS_TYPE_STRENGTH,"Strength",10,10)
set id = ItemData.create('penr')
set id.goldCost = 1500
set id.abilityName = "Windwalk"
set id.abilityText = "Turns the wielder invisible increasing his Movement Speed by 20%, The attack that breaks the invisibility will be increased and will be a Critical Strike.(25s CD)"
set id.tier1Text = "+75 Damage, 6s Duration"
set id.tier2Text = "+125 Damage, 7s Duration"
set id.tier3Text = "+175 Damage, 8s Duration"
set id.abilityID = 'A078'
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",15,10)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,10)
call id.AddBonus(BONUS_TYPE_ATTACK_STRENGTH,"Attack Strength",20,10)
set id = ItemData.create('odef')
set id.goldCost = 1300
set id.abilityName = "Magnetic Push"
set id.abilityText = "Push the target unit 600 distance towards his facing angle if is an ally, otherwise will be pushed in the opposite angle."
set id.tier1Text = "20s Cooldown"
set id.tier2Text = "15s Cooldown"
set id.tier3Text = "10s Cooldown"
set id.abilityID = 'A05D'
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",5,5)
call id.AddBonus(BONUS_TYPE_STATUS_RED,"Status Reduction",5,5)
set id = ItemData.create('rat6')
set id.goldCost = 1600
set id.abilityName = "Arcane Strike"
set id.abilityText = "Upon activation the next attack upon a hero in the next 3 seconds will steal a positive buff from him, while dealing bonus magic damage if success. (18s CD)"
set id.tier1Text = "60 Damage"
set id.tier2Text = "120 Damage"
set id.tier3Text = "180 Damage"
set id.abilityID = 'A0B5'
call id.AddBonus(BONUS_TYPE_INTELLIGENCE,"Intelligence",15,10)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,5)
call id.AddBonus(BONUS_TYPE_SPELL_STRENGTH,"Spell Strength",30,30)
set id = ItemData.create('rat9')
set id.goldCost = 1600
set id.abilityName = "Sparkling Current"
set id.abilityText = "When the wielder makes a critical strike with attacks, increases the critical chance with attacks and movement speed for 8s, stack up to 5 times."
set id.tier1Text = "4% Critical, 4% Ms"
set id.tier2Text = "6% Critical, 5% Ms"
set id.tier3Text = "8% Critical, 6% Ms"
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",20,10)
call id.AddBonus(BONUS_TYPE_AGILITY,"Agility",10,5)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,10)
endfunction
endscope
scope WeaponBuffs initializer init
struct CrusaderShout extends array
integer dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-dmg,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 15 + 10 * b.level
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,dmg,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A050'
set BUFF_DATA.BuffID = 'B01R'
set BUFF_DATA.Name = "Crusader Shout"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct LongSight extends array
integer ar
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call AddHeroAttackRange(b.target,-ar)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ar = (50 + 50 * b.level)/25
call AddHeroAttackRange(b.target,ar)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08B'
set BUFF_DATA.BuffID = 'B02X'
set BUFF_DATA.Name = "Long Sight"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct RageItem extends array
real inc
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set inc = 0.10 + 0.05 * b.level
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08E'
set BUFF_DATA.BuffID = 'B02Y'
set BUFF_DATA.Name = "Rage"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct SinisterMark extends array
real red
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,R2I(red*100))
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,R2I(red*100))
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set red = 0.25 + 0.05 * b.level
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,0,R2I(-red*100))
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,0,R2I(-red*100))
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A06Q'
set BUFF_DATA.BuffID = 'B02F'
set BUFF_DATA.Name = "SinisterMark"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct JudgementCrown extends array
integer res
integer ar
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-ar,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,0,-res)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local player p = GetOwningPlayer(b.owner)
set res = 15 + 10 * b.level
set ar = 2 + 2 * b.level
if IsUnitAlly(b.target,p) then
set sfx = AddSpecialEffectTarget("Abilities\\Spells\\Human\\InnerFire\\InnerFireTarget.mdl",b.target,"overhead")
else
set res = res * -1
set ar = ar * -1
set sfx = AddSpecialEffectTarget("war3mapImported\\InnerFireRed.mdx",b.target,"overhead")
endif
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,ar,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,0,res)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08F'
set BUFF_DATA.BuffID = 'B02Z'
set BUFF_DATA.Name = "JudgementCrown"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Swiftness extends array
integer as
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = 15 * b.level
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A051'
set BUFF_DATA.BuffID = 'B01S'
set BUFF_DATA.Name = "Swiftness"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct Sacrifice extends array
integer dmg
real life
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitRemoveHp(b.target,life)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 30 + 20 * b.level
set life = (BlzGetUnitMaxHP(b.target) * 0.25) / 20
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A052'
set BUFF_DATA.BuffID = 'B01T'
set BUFF_DATA.Name = "Sacrifice"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct EnvenomedShots extends array
Movespeed ms
real dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypeMagicOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-(0.25 + 0.05 * b.level),0)
set dmg = 25 * b.level
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0A2'
set BUFF_DATA.BuffID = 'B03O'
set BUFF_DATA.Name = "Envenomed Shots"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct ChopSlow extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,45,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-0.45,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-45,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Chop Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Chop extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0A3'
set BUFF_DATA.BuffID = 'B03P'
set BUFF_DATA.Name = "Chop"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct WindWalk extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call Status.Remove(STATUS_GHOST,b.target)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,0.20,0)
call Status.Add(STATUS_GHOST,b.target,0,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AJ'
set BUFF_DATA.BuffID = 'B01J'
set BUFF_DATA.Name = "Wind Walk"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct ArcaneStrike extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0B6'
set BUFF_DATA.BuffID = 'B045'
set BUFF_DATA.Name = "Arcane Strike"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct SparklingCurrent extends array
real crit
Movespeed ms
private static method onStackRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
call ms.destroy()
set crit = 0
call SetItemCharges(it.itemS,GetUnitBuff(b.target,SparklingCurrent.buff).stacks - 1)
endmethod
private static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Item it = b.int
set ms = Movespeed.create(b.target,0.03 + 0.01 * b.level,0)
set crit = 2 + 2 * b.level
call SetItemCharges(it.itemS,b.stacks)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CL'
set BUFF_DATA.BuffID = 'B04X'
set BUFF_DATA.Name = "Sparkling Attacks"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_INDEPENDENT
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function init takes nothing returns nothing
call CrusaderShout.Initialize()
call LongSight.Initialize()
call RageItem.Initialize()
call SinisterMark.Initialize()
call JudgementCrown.Initialize()
call Swiftness.Initialize()
call Sacrifice.Initialize()
call EnvenomedShots.Initialize()
call Chop.Initialize()
call ChopSlow.Initialize()
call WindWalk.Initialize()
call ArcaneStrike.Initialize()
call SparklingCurrent.Initialize()
endfunction
endscope
scope ConsumableData
public function Setup takes nothing returns nothing
local ItemData id = ItemData.create('hslv')
set id.goldCost = 50
set id.dummyID = 'I001'
set id.charges = 2
set id.abilityID = 'AIrl'
call AddItemDummyData(id)
set id = ItemData.create('tsct')
set id.goldCost = 100
set id.dummyID = 'I008'
set id.charges = 2
set id.abilityID = 'A00C'
call AddItemDummyData(id)
set id = ItemData.create('pman')
set id.goldCost = 150
set id.dummyID = 'I004'
set id.charges = 1
set id.abilityID = 'AIhb'
call AddItemDummyData(id)
set id = ItemData.create('rej3')
set id.goldCost = 100
set id.dummyID = 'I005'
set id.charges = 1
set id.abilityID = 'AIre'
call AddItemDummyData(id)
set id = ItemData.create('stwp')
set id.goldCost = 100
set id.dummyID = 'I012'
set id.charges = 3
set id.abilityID = 'Aste'
call AddItemDummyData(id)
set id = ItemData.create('mcri')
set id.goldCost = 150
set id.dummyID = 'I009'
set id.charges = 3
call AddItemDummyData(id)
set id = ItemData.create('pclr')
set id.goldCost = 250
set id.dummyID = 'I000'
set id.charges = 1
set id.abilityID = 'A04Q'
call AddItemDummyData(id)
set id = ItemData.create('plcl')
set id.goldCost = 200
set id.dummyID = 'I002'
set id.charges = 1
set id.abilityID = 'A005'
call AddItemDummyData(id)
set id = ItemData.create('pinv')
set id.goldCost = 200
set id.dummyID = 'I007'
set id.charges = 1
set id.abilityID = 'A09N'
call AddItemDummyData(id)
set id = ItemData.create('rnec')
set id.goldCost = 300
set id.dummyID = 'I00R'
set id.charges = 1
set id.abilityID = 'A0A0'
call AddItemDummyData(id)
set id = ItemData.create('phea')
set id.goldCost = 150
set id.dummyID = 'I00U'
set id.charges = 4
set id.abilityID = 'A07D'
call AddItemDummyData(id)
set id = ItemData.create('pnvl')
set id.goldCost = 200
set id.dummyID = 'I00V'
set id.charges = 1
set id.abilityID = 'AIpm'
call AddItemDummyData(id)
endfunction
endscope
scope ConsumableBuffs initializer init
struct ManaSteal extends array
real mana
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitRemoveMp(b.target,mana)
call UnitAddMp(b.owner,mana)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl",b.target,"overhead"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl",b.owner,"overhead"))
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set mana = (80.0 + GetUnitState(b.target,UNIT_STATE_MAX_MANA) * 0.05)
if GetUnitItemOfType(b.owner,'bfhr') != 0 then
set mana = mana + mana * 0.25
endif
set mana = mana / 6
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Mana steal"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Cheers extends array
real hp
real mp
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitAddHp(b.target,hp)
call UnitAddMp(b.target,mp)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-0.30,0)
set hp = GetUnitState(b.target,UNIT_STATE_MAX_LIFE) * 0.20 / 8
set mp = GetUnitState(b.target,UNIT_STATE_MAX_MANA) * 0.20 / 8
if GetUnitItemOfType(b.target,'bfhr') != 0 then
set hp = hp + hp * 0.25
set mp = mp + mp * 0.25
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A09Y'
set BUFF_DATA.BuffID = 'B03N'
set BUFF_DATA.Name = "Cheers"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Regen extends array
real value
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if IsUnitInCombat(b.target) then
call UnitAddHp(b.target,value / 2)
call UnitAddMp(b.target,value / 2)
else
call UnitAddHp(b.target,value)
call UnitAddMp(b.target,value)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitRemoveAbility(b.target,'BIrg')
call UnitRemoveAbility(b.target,'BIrl')
call UnitRemoveAbility(b.target,'BIrm')
set value = 120
if GetUnitItemOfType(b.target,'bfhr') != 0 then
set value = value + value * 0.25
endif
set value = value / 20.00
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05S'
set BUFF_DATA.BuffID = 'B024'
set BUFF_DATA.Name = "Regen"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct BitterDrink extends array
integer bt
integer value
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(bt,b.target,-value,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local string s
local integer att = GetHeroMainAttribute(b.target)
set value = GetRandomInt(1,15)
if att == 1 then
set s = "|c00ffff00+"+I2S(value)+" Agility|r"
call BonusStruct.Add(BONUS_TYPE_AGILITY,b.target,value,0,true)
set bt = BONUS_TYPE_AGILITY
elseif att == 2 then
set s = "|c00ffff00+"+I2S(value)+" Intelligence|r"
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,b.target,value,0,true)
set bt = BONUS_TYPE_INTELLIGENCE
else
set s = "|c00ffff00+"+I2S(value)+" Strength|r"
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,value,0,true)
set bt = BONUS_TYPE_STRENGTH
endif
call CreateTextTagBounty(GetOwningPlayer(b.target),GetUnitX(b.target),GetUnitY(b.target),s,10)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A003'
set BUFF_DATA.BuffID = 'B033'
set BUFF_DATA.Name = "Bitter Drink"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function init takes nothing returns nothing
call ManaSteal.Initialize()
call Regen.Initialize()
call BitterDrink.Initialize()
call Cheers.Initialize()
endfunction
endscope
scope MiscData
public function Setup takes nothing returns nothing
local ItemData id = ItemData.create('brag')
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",3,0)
call id.AddBonus(BONUS_TYPE_ALL_STATS,"All Stats",3,0)
set id = ItemData.create('bfhr')
call id.AddBonus(BONUS_TYPE_LIFE_REGEN,"Life Regen",2,0)
call id.AddBonus(BONUS_TYPE_ALL_STATS,"All Stats",4,0)
set id = ItemData.create('arsh')
set id.goldCost = 0
set id = ItemData.create('vddl')
set id.goldCost = 0
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,0)
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",100,0)
set id = ItemData.create('frhg')
set id.goldCost = 0
call id.AddBonus(BONUS_TYPE_MANA_REGEN,"Mana Regen",2,0)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",100,0)
set id = ItemData.create('blba')
set id.goldCost = 300
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,0)
call id.AddBonus(BONUS_TYPE_ATTACK_SPEED,"Attack Speed",10,0)
set id = ItemData.create('amrc')
set id.goldCost = 0
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",10,0)
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",100,0)
set id = ItemData.create('stwa')
set id.goldCost = 0
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",10,0)
call id.AddBonus(BONUS_TYPE_ARMOR,"Armor",2,0)
set id = ItemData.create('will')
set id.goldCost = 0
call id.AddBonus(BONUS_TYPE_MAIN_ATTRIBUTE,"Main Attribute",6,0)
set id.abilityID = 'A0BC'
set id = ItemData.create('ratf')
set id.goldCost = 0
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",100,0)
call id.AddBonus(BONUS_TYPE_MP,"Mana Points",100,0)
set id = ItemData.create('anfg')
set id.goldCost = 0
call id.AddBonus(BONUS_TYPE_DAMAGE,"Damage",5,0)
set id = ItemData.create('axas')
set id.goldCost = 0
call id.AddBonus(BONUS_TYPE_HP,"Hit Points",75,0)
call id.AddBonus(BONUS_TYPE_ALL_STATS,"All Stats",2,0)
call Poison.Initialize()
endfunction
struct Poison extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,10,udg_DamageTypePhysicalOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-0.10,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0A7'
set BUFF_DATA.BuffID = 'B05Y'
set BUFF_DATA.Name = "Poison"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
endscope
scope ItemEvents initializer init
globals
private constant string CHANCE_SFX = "Abilities\\Spells\\Items\\AIlm\\AIlmTarget.mdl"
private constant string HEAL_SFX = "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl"
private constant string MANA_SFX = "Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl"
private constant string ATTACK_SFX = "Abilities\\Weapons\\BlackKeeperMissile\\BlackKeeperMissile.mdl"
endglobals
private function ForkedLightningCast takes unit u, unit t, real d returns nothing
local group g = NewGroup()
local real x = GetUnitX(t)
local real y = GetUnitY(t)
local player p = GetOwningPlayer(u)
local unit temp
local integer c = 2
call CodeDamage.Damage(u,t,d,udg_DamageTypeMagicAoe,"",0,0)
call GroupEnumUnitsInRange(g,x,y,300.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null or c == 0
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and c != 0 and temp != t then
set c = c - 1
if IsUnitType(temp,UNIT_TYPE_HERO) then
call CodeDamage.Damage(u,temp,d,udg_DamageTypeMagicAoe,"",0,0)
else
call CodeDamage.Damage(u,temp,d * 2,udg_DamageTypeMagicAoe,"",0,0)
endif
call Lightning.create("FORK",u,temp,0.75,0.25,100,100).setLightColor(255,255,255,255)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endfunction
private function MeteoricAttack takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local group g = NewGroup()
local unit u = tb.unit[0]
local real x = tb.real[1]
local real y = tb.real[2]
local player p = GetOwningPlayer(u)
local unit temp
local real dmg = 140.00
call GroupEnumUnitsInRange(g,x,y,280.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_STUN,temp,0.30,Status_EFFECT[STATUS_STUN])
endif
endloop
call ReleaseTimer(t)
call ReleaseGroup(g)
set g = null
set p = null
set u = null
set t = null
endfunction
public function CastMeteoricAttack takes unit caster, real x, real y returns nothing
local effect sfx = AddSpecialEffect("war3mapImported\\AlloveOrangemeteor.mdx",x,y)
local Table tb = Table.create()
call BlzSetSpecialEffectTimeScale(sfx,1.2)
call BlzSetSpecialEffectScale(sfx,1.2)
call DestroyEffect(sfx)
set tb.unit[0] = caster
set tb.real[1] = x
set tb.real[2] = y
call TimerStart(NewTimerEx(tb),0.75,false,function MeteoricAttack)
set sfx = null
endfunction
private function SlamGolem takes unit u returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local unit temp
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),300,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call Status.Add(STATUS_STUN,temp,1.0,Status_EFFECT[STATUS_STUN])
call CodeDamage.Damage(u,temp,75.00,udg_DamageTypeMagicAoe,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endfunction
private function OnLeaveCombat takes nothing returns nothing
local unit u = GetEventCombatLeaveUnit()
local Buff b
local Item it
local real r
local integer i
if IsUnitType(u,UNIT_TYPE_HERO) then
set b = GetUnitBuff(u,Untouchable.buff)
if b != 0 then
call UnitRemoveBuff(u,Untouchable.buff)
endif
set it = GetUnitItemOfType(u,'sclp')
if it != 0 then
call SetItemCharges(it.itemS,0)
endif
set it = GetUnitItemOfType(u,'wswd')
if it != 0 then
call UnitAddBuff(u,u,9000,WandererSteps.buff,it.tier,0)
endif
set it = GetUnitItemOfType(u,'sror')
if it != 0 then
call SetUnitAbilityLevel(u,'AIbk',it.tier)
endif
set it = GetUnitItemOfType(u,'prvt')
if it != 0 then
call SetItemCharges(it.itemS,0)
endif
set it = GetUnitItemOfType(u,'dkfw')
if it != 0 then
call SetItemCharges(it.itemS,0)
endif
set it = GetUnitItemOfType(u,'prvt')
if it != 0 then
call UnitRemoveBuff(u,BraveFight.buff)
endif
set it = GetUnitItemOfType(u,'ckng')
if it != 0 then
call UnitRemoveBuff(u,Inspiration.buff)
endif
set it = GetUnitItemOfType(u,'gmfr')
if it != 0 then
call UnitRemoveBuff(u,Providence.buff)
endif
set it = GetUnitItemOfType(u,'will')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(u,'A0BC') == 0 then
set i = GetItemCharges(it.itemS)
call UnitAddHp(u,5 * i)
call UnitAddMp(u,5 * i)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl",u,"origin"))
endif
call SetItemCharges(it.itemS,0)
endif
endif
set u = null
endfunction
private function OnEnterCombat takes nothing returns nothing
local unit u = GetEventCombatEnterUnit()
local Item it
if IsUnitType(u,UNIT_TYPE_HERO) then
set it = GetUnitItemOfType(u,'sror')
if it != 0 then
call SetUnitAbilityLevel(u,'AIbk',3 + it.tier)
endif
set it = GetUnitItemOfType(u,'gmfr')
if it != 0 then
call UnitAddBuff(u,u,999999,Providence.buff,it.tier,0)
endif
set it = GetUnitItemOfType(u,'ssil')
if it != 0 then
call DestroyEffect(AddSpecialEffect("war3mapImported\\LionSong.mdx",GetUnitX(u),GetUnitY(u)))
call ApplyBuffArea(u,700.00,10.00,CrusaderShout.buff,true,false,it.tier)
endif
set it = GetUnitItemOfType(u,'ckng')
if it != 0 then
call UnitAddBuff(u,u,9999,Inspiration.buff,it.tier,it)
endif
set it = GetUnitItemOfType(u,'fgdg')
if it != 0 then
call UnitAddBuff(u,u,3.0,Impulse.buff,it.tier,0)
endif
set it = GetUnitItemOfType(u,'wswd')
if it != 0 then
call UnitRemoveBuff(u,WandererSteps.buff)
endif
set it = GetUnitItemOfType(u,'fgsk')
if it != 0 then
if not UnitHasBuff(u,SeaWalker.buff) then
call UnitAddBuff(u,u,15.0,SeaWalker.buff,it.tier,it)
endif
endif
set it = GetUnitItemOfType(u,'sbch')
if it != 0 then
call UnitAddBuff(u,u,10.0,LongSight.buff,it.tier,0)
endif
set it = GetUnitItemOfType(u,'prvt')
if it != 0 then
call UnitAddBuff(u,u,9999.0,BraveFight.buff,it.tier,it)
endif
endif
set u = null
endfunction
public function HeroSpellEvent takes unit u, integer id returns nothing
local real r
local integer i
local Ability a
local PresenceOfMind p
local SorceryRuneBuff sr
local Buff b
local Item it
set it = GetUnitItemOfType(u,'ciri')
if it != 0 then
set r = BlzGetAbilityManaCost(id,GetUnitAbilityLevel(u,id) - 1)
if r != 0 then
set a = Ability.GetUnitAbilityByID(id,u)
if a != 0 and BlzGetUnitAbilityCooldownRemaining(u,it.abilityID) == 0 then
call a.addTempFlatCooldown(-(2 + 1.5 * it.tier))
call DestroyEffect(AddSpecialEffectTarget(CHANCE_SFX,u,"origin"))
call BlzStartUnitAbilityCooldown(u,it.abilityID,12.00)
endif
endif
endif
set p = GetUnitBuff(u,PresenceOfMind.buff).buffAllocIndex
if p != 0 then
set a = Ability.GetUnitAbilityByID(id,u)
if a != 0 and not a.isCharged then
if not p.done then
set p.done = true
call a.addTempFlatCooldown(-6)
endif
endif
endif
set b = GetUnitBuff(u,Audacity.buff)
if b != 0 then
set a = Ability.GetUnitAbilityByID(id,u)
if a != 0 then
set r = a.calcManaCost
set r = r * (0.30 + 0.20 * b.level)
call CodeDamage.Damage(u,u,r,udg_DamageTypeHeal,"",0,0)
endif
endif
set it = GetUnitItemOfType(u,'rde3')
if it != 0 then
set i = GetItemCharges(it.itemS)
if i != 2 + 2 * it.tier then
set i = i + 1
call SetItemCharges(it.itemS,i)
endif
call UnitAddBuff(u,u,6.0,SpellBoost.buff,it,i)
call DestroyEffect(AddSpecialEffectTarget(CHANCE_SFX,u,"origin"))
endif
set it = GetUnitItemOfType(u,'I00A')
if it != 0 then
set i = GetItemCharges(it.itemS)
set i = i + 1
if i >= 3 then
call AddUnitShield(u,110 + 40 * it.tier,4.00,it.itemID)
call SetItemCharges(it.itemS,0)
else
if not UnitHasBuff(u,Shield.buff) then
call SetItemCharges(it.itemS,i)
endif
endif
endif
endfunction
private function ItemCastAll takes unit u, unit t, integer id returns nothing
local Item it = GetUnitItemOfType(u,'tmsc')
local Buff b
local integer i
local real evalue
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(u,'A0CT') == 0 then
call BlzStartUnitAbilityCooldown(u,'A0CT',12)
set evalue = 20 + (BlzGetUnitMaxMana(u) * (0.03 + 0.02 * it.tier))
call UnitAddMp(u,evalue)
call DestroyEffect(AddSpecialEffectTarget(MANA_SFX,u,"overhead"))
endif
endif
if id != 'A078' then
set b = GetUnitBuff(u,WindWalk.buff)
if b != 0 then
call b.remove()
endif
endif
set it = GetUnitItemOfType(u,'frhg')
if it != 0 then
set i = BlzGetAbilityManaCost(id,GetUnitAbilityLevel(u,id))
if BlzGetUnitAbilityCooldownRemaining(u,'A0CQ') == 0 and i != 0 then
call UnitAddHp(u,i)
call BlzStartUnitAbilityCooldown(u,'A0CQ',12.0)
call DestroyEffect(AddSpecialEffectTarget(HEAL_SFX,u,"overhead"))
endif
endif
endfunction
public function ItemCast takes unit u, integer id, real x, real y returns nothing
local Item it = GetUnitItemOfTypeAbility(u,id)
local Buff b
local real r
local real a
local integer i
local unit s
if it == 0 then
return
endif
if it.abilityID == 'A0BC' then
set i = GetItemCharges(it.itemS)
set r = 5 * i
call UnitAddHp(u,r * 2)
call UnitAddMp(u,r * 2)
return
endif
if it.abilityID == 'A05M' then
call SpiderNetCast(u,it.tier,x,y)
return
endif
if id == 'A07D' then
call MissileThrowGrenade(u,x,y)
endif
if id == 'A08Y' then
call SlamCast(u,x,y,it.tier)
endif
if id == 'A0A0' then
call Teleport.create(u,null,x,y,false,4,TP_TO_POINT)
endif
if id == 'A078' then
call UnitAddBuff(u,u,5.0 + 1.0 * it.tier,WindWalk.buff,it.tier,0)
return
endif
if id == 'A04X' then
call UnitAddBuff(u,u,15.0,RageItem.buff,it.tier,0)
return
endif
if id == 'A04S' then
call UnitAddBuff(u,u,10.0,Sacrifice.buff,it.tier,0)
return
endif
if id == 'AIrl' then
call UnitAddBuff(u,u,10.0,Regen.buff,0,0)
return
endif
if id == 'AIhb' then
if GetRandomInt(1,100) <= 25 then
call UnitDispelBuffs(u,2,BUFF_TYPE_NEGATIVE)
else
call UnitDispelBuffs(u,1,BUFF_TYPE_NEGATIVE)
endif
return
endif
if id == 'AIre' then
set r = 200 + 10 * GetHeroLevel(u)
if GetUnitItemOfType(u,'bfhr') != 0 then
set r = r + r * 0.25
endif
call UnitAddHp(u,r)
call UnitAddMp(u,r)
return
endif
if id == 'A07A' then
call UnitAddBuff(u,u,15.0,KingsBlessing.buff,it.tier,0)
return
endif
if id == 'A057' then
call HowlOfTerror.ApplyBuff(u,it.tier)
return
endif
if id == 'A058' then
call UnitAddBuff(u,u,15.0,EnergyBarrier.buff,it.tier,0)
return
endif
if id == 'AImr' then
call ManaRecover(u,it)
return
endif
if id == 'A062' then
call AreaHealing(u,it)
return
endif
if id == 'A06H' then
call UnitAddBuff(u,u,15.00,MagicEater.buff,it.tier,0)
return
endif
if id == 'A05R' then
call UnitDispelAllBuffs(u,BUFF_TYPE_NEGATIVE)
return
endif
if id == 'A05I' then
call UnitAddBuff(u,u,4.0,SafeStep.buff,it.tier,0)
return
endif
if id == 'A05N' then
call UnitAddBuff(u,u,4.0 + 3.0 * it.tier,Savage.buff,it.tier,0)
return
endif
if id == 'A04Q' then
call UnitAddBuff(u,u,120.0,BitterDrink.buff,0,0)
return
endif
if id == 'A005' then
call UnitAddBuff(u,u,4.0,Cheers.buff,0,0)
return
endif
if id == 'A08R' then
call Status.Add(STATUS_SPELL_IMMUNITY,u,5.0,Status_EFFECT[STATUS_SPELL_IMMUNITY])
return
endif
if id == 'A091' then
call UnitAddBuff(u,u,7.0,UnholyRegeneration.buff,it.tier,0)
return
endif
if id == 'A09J' then
call UnitAddBuff(u,u,9999999,MoltenSpikes.buff,it.tier,it)
return
endif
if id == 'A09N' then
call Status.Add(STATUS_INVISIBILITY,u,7.0,0)
return
endif
if id == 'A08U' then
call DiamondSpears(it,2)
return
endif
if id == 'A0AX' then
call UnitAddBuff(u,u,15.00,Audacity.buff,it.tier,0)
return
endif
if id == 'A0B5' then
call UnitAddBuff(u,u,3.00,ArcaneStrike.buff,it.tier,0)
return
endif
if id == 'AUin' then
call InfernalDamage(u,x,y,it.tier)
return
endif
if id == 'A02S' then
call RecalibratorWatch(u,it)
return
endif
if id == 'A03D' then
call UnitAddBuff(u,u,6,IcyBlasts.buff,it.tier,0)
return
endif
if id == 'A03Z' then
call UnitAddBuff(u,u,1.5,Reflect.buff,0,0)
return
endif
endfunction
private function ItemCastTarget takes unit u, unit t, Item it returns nothing
local Buff b
local real r
local real x
local real y
local integer i
//---------------------------------------------------------------------
//------Not Reflected / not negated (Allies target)
if it.abilityID == 'A0DB' then
if u == t then
call UnitAddBuff(u,u,6.0,MagicBulwark.buff,it.tier,0)
else
call UnitAddBuff(t,u,6.0,MagicBulwark.buff,it.tier,0)
call UnitAddBuff(u,u,6.0,MagicBulwark.buff,it.tier,0)
endif
return
endif
if it.abilityID == 'A054' then
if not IsUnitType(t,UNIT_TYPE_HERO) then
call CodeDamage.Damage(u,t,1,udg_DamageTypeMagic,"KillBlow",0,0)
else
call UnitRemoveHp(t,150 + 100 * it.tier)
endif
call UnitAddBuff(u,u,20.0,Consume.buff,it.tier,0)
return
endif
if it.abilityID == 'A065' then
call UnitAddBuff(t,u,8.0,AncientHeal.buff,it.tier,0)
return
endif
if it.abilityID == 'A08N' then
call DispelMovilityStatus(t)
call UnitDispelAllBuffsType(t,EFFECT_TYPE_SLOW)
call UnitAddBuff(t,t,3.0,LibertyHand.buff,it.tier,0)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\Mjolnir.mdx",t,"origin"))
return
endif
if it.abilityID == 'A04Z' then
call UnitAddBuff(t,u,8.0,JudgementCrown.buff,it.tier,0)
return
endif
if it.abilityID == 'A05G' then
call UnitAddBuff(t,u,6.0,ShadowWalk.buff,it.tier,0)
return
endif
//-------Not Reflected (enemies target)
if it.abilityID == 'A04Y' then
set i = GetItemCharges(it.itemS)
if i == 0 then
call SetItemCharges(it.itemS,0)
else
call SetItemCharges(it.itemS,i + 1)
endif
set r = (50 + 100 * it.tier) + i * 25
call MissileSoulStrike(u,t,r,1)
call MissileSoulStrike(t,u,r,2)
return
endif
//-------Normal
if it.abilityID == 'Aste' then
call UnitAddBuff(t,u,3.0,ManaSteal.buff,0,0)
endif
if it.abilityID == 'A05D' then
if IsUnitAlly(u,GetOwningPlayer(t)) then
set r = GetUnitFacing(t) * bj_DEGTORAD
else
set r = (GetUnitFacing(t) + 180) * bj_DEGTORAD
endif
call KPJUnit.create(t,600,r,0.50,0,KPJDefaultConfig,KPJ_TYPE_KNOCKBACK)
return
endif
if it.abilityID == 'A0A4' then
set r = 2 + 2 * it.tier
call UnitAddBuff(t,u,r,Chop.buff,0,0)
call Status.Add(STATUS_SILENCE,t,r,Status_EFFECT[STATUS_SILENCE])
return
endif
if it.abilityID == 'A05K' then
if IsUnitEnemy(t,GetOwningPlayer(u)) then
set i = UnitDispelAllBuffs(t,BUFF_TYPE_POSITIVE)
call UnitAddBuff(t,u,4.0,Purge.buff,0,i)
else
call UnitDispelAllBuffs(t,BUFF_TYPE_NEGATIVE)
endif
call BlzSetUnitAbilityCooldown(u,it.abilityID,it.tier - 1,40 - 5 * it.tier)
return
endif
if it.abilityID == 'A05O' then
call Status.Add(STATUS_HEX,t,1.0 + 1.0 * it.tier,0)
return
endif
if it.abilityID == 'A08X' then
set r = Status.Add(STATUS_SILENCE,t,2.0,Status_EFFECT[STATUS_SILENCE])
if r != 0 then
call UnitAddBuff(t,u,r,FelSeal.buff,it.tier,0)
endif
return
endif
if it.abilityID == 'A04T' then //-
set i = GetItemCharges(it.itemS)
if i == 0 then
call SetItemCharges(it.itemS,0)
else
call SetItemCharges(it.itemS,i + 1)
endif
set r = 50.00 + 75.00 * it.tier
set r = r + (2 * i)
call ForkedLightningCast(u,t,r)
return
endif
if it.abilityID == 'A092' then
set r = Status.Add(STATUS_DISARM,t,2.0 + 1.0 * it.tier,Status_EFFECT[STATUS_DISARM])
if r != 0 then
call UnitAddBuff(t,u,r,BindingChain.buff,it.tier,0)
endif
return
endif
if it.abilityID == 'A093' then
if IsUnitEnemy(t,GetOwningPlayer(u)) then
call UnitAddBuff(t,u,6.0,DivineWordDebuff.buff,it.tier,0)
else
call UnitAddBuff(t,u,6.0,DivineWordBuff.buff,it.tier,0)
endif
return
endif
if it.abilityID == 'A09L' then
call UnitAddBuff(t,u,6.0,Cripple.buff,it.tier,0)
return
endif
if it.abilityID == 'A07E' then
call UnitAddBuff(t,u,3.0 + 1.0 * it.tier,FrenzyFOB.buff,it.tier,0)
return
endif
if it.abilityID == 'A09K' then
if IsUnitEnemy(t,GetOwningPlayer(u)) then
call Status.Add(STATUS_BANISH,t,3.0,0)
set r = I2R(BlzGetUnitIntegerField(u,UNIT_IF_PRIMARY_ATTRIBUTE))
if r == 1 then
set i = GetHeroStr(u,true)
elseif r == 2 then
set i = GetHeroInt(u,true)
elseif r == 3 then
set i = GetHeroAgi(u,true)
endif
if i != 0 then
call CodeDamage.Damage(u,t,i * 2.1,udg_DamageTypeMagic,"",0,0)
endif
else
call Status.Add(STATUS_BANISH,t,6.0,0)
endif
call Lightning.create("SPLK",u,t,0.75,0.25,100,100).setLightColor(255,255,255,255)
return
endif
//-------Missiles
if it.abilityID == 'A095' then
call MissileWindFlute(u,t)
return
endif
if it.abilityID == 'A05H' then
call MissileThrowShield(u,t,it.tier)
return
endif
endfunction
private function ItemSpellEvent takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer id = GetSpellAbilityId()
local boolean b1
local boolean b2
local boolean b3 = id != 'A056' and id != 'A065' and id != 'A08N' and id != 'A04Z' and id != 'A05G' and id != 'A05C' and id != 'A05K' and id != 'A05D' and id != 'A095' and id != 'A07E' and id != 'A09K' and id != 'A093' and id != 'A0DB'
local Buff b
local real r
//b3 = Items que pueden targetear alliados y enemigos
//b1 = Items con missiles
local Item it
if (u == t and b3) or t == null then
call ItemCast(u,id,GetSpellTargetX(),GetSpellTargetY())
else
set it = GetUnitItemOfTypeAbility(u,id)
if it != 0 then
set b1 = id == 'A095' or id == 'A05H' or id == 'A09K'
set b2 = IsUnitAlly(t,GetTriggerPlayer())
if b1 or b2 then
call ItemCastTarget(u,t,it)
else
if not TriggerSpellNegation(t) then
call ItemCastTarget(u,t,it)
endif
if id != 'A04Y' then
if TriggerSpellReflection(t) then
call ItemCastTarget(t,u,it)
endif
endif
endif
endif
endif
if IsUnitType(u,UNIT_TYPE_HERO) then
call ItemCastAll(u,t,id)
else
if id == 'A00N' then
call SlamGolem(u)
endif
set b = GetUnitBuff(u,FelSeal.buff)
if b != 0 then
call Status.Add(STATUS_SILENCE,u,3.0,Status_EFFECT[STATUS_SILENCE])
set r = BlzGetAbilityManaCost(id,GetUnitAbilityLevel(u,id) - 1) * (0.50 + 0.25 * b.level)
call UnitRemoveMp(u,r)
call CodeDamage.Damage(b.owner,u,r,udg_DamageTypeMagic,"",0,0)
call UnitRemoveBuff(u,FelSeal.buff)
endif
endif
set u = null
set t = null
endfunction
private function ItemDeathEvent takes nothing returns nothing
local unit t = GetTriggerUnit()
local unit u = GetKillingUnit()
local Hero h
local Item it
local integer i = 0
local real r = 0
local group g
local unit temp
local player p
local boolean isHero = IsUnitType(t,UNIT_TYPE_HERO)
local Buff b
if GetUnitTypeId(u) == 'ddot' then
set u = GetPlayerHero(GetOwningPlayer(GetKillingUnit())).hero
endif
if isHero then
set it = GetUnitItemOfType(u,'lhst')
if it != null then
set i = GetItemCharges(it.itemS)
call SetItemCharges(it.itemS,i + 1)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\AncestralSpiritMod.mdx",u,"overhead"))
endif
set g = NewGroup()
set p = GetOwningPlayer(t)
call GroupEnumUnitsInRange(g,GetUnitX(t),GetUnitY(t),1000,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if IsUnitType(temp,UNIT_TYPE_HERO) and temp != t then
set it = GetUnitItemOfType(temp,'totw')
if it != 0 then
set i = GetItemCharges(it.itemS)
call SetItemCharges(it.itemS,i + 1)
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set b = GetUnitBuff(u,Immolation.buff)
if b != 0 then
call Immolation[b.buffAllocIndex].disable()
endif
else
set it = GetUnitItemOfType(u,'brag')
if it != 0 then
if GetRandomInt(1,2) == 1 then
call UnitAddHp(u,35 + BlzGetUnitMaxHP(u) * 0.02)
call DestroyEffect(AddSpecialEffectTarget(HEAL_SFX,u,"overhead"))
else
call UnitAddMp(u,35 + BlzGetUnitMaxMana(u) * 0.02)
call DestroyEffect(AddSpecialEffectTarget(MANA_SFX,u,"overhead"))
endif
endif
set it = GetUnitItemOfType(u,'rag1')
if it != null then
set i = GetItemCharges(it.itemS)
call SetItemCharges(it.itemS,i + 1)
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\AncestralSpiritMod.mdx",u,"overhead"))
endif
endif
set u = null
set t = null
endfunction
private function onPostDamageEvent takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Item it
local real r
local integer lvl
local KingsBlessing b
local EnergyBarrier eb
local Buff bff
if not data.isAbsorbed then
if data.isCritical and data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set it = GetUnitItemOfType(data.target,'I00B')
if it != 0 then
set r = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
if r >= 18 or r < 6 then
//noche
set data.damageMod = data.damageMod - data.damageMod * (0.10 * it.tier)
else
set data.damageMod = data.damageMod - data.damageMod * (0.05 * it.tier)
endif
endif
set it = GetUnitItemOfType(data.target,'mcri')
if it != 0 then
set data.damageMod = data.damageMod * 0.40
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\DragonHawkMissile\\DragonHawkMissile.mdl",data.target,"overhead"))
call SetItemCharges(it.itemS,GetItemCharges(it.itemS) - 1)
if GetItemCharges(it.itemS) == 0 then
call it.destroy()
endif
endif
endif
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,KingsBlessing.buff).buffAllocIndex
if b != 0 then
set b.life = b.life - data.damageMod
if b.life < 0 then
if b.life <= -1 then
set data.damageMod = b.life * -1
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
set b.life = 0
call UnitRemoveBuff(data.target,KingsBlessing.buff)
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
endif
endif
if data.dmgType <= 6 or data.dmgType == 8 then
set eb = GetUnitBuff(data.target,EnergyBarrier.buff).buffAllocIndex
if eb != 0 then
set eb.life = eb.life - data.damageMod
if eb.life < 0 then
if eb.life <= -1 then
set data.damageMod = eb.life * -1
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
set eb.life = 0
call UnitRemoveBuff(data.target,EnergyBarrier.buff)
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
endif
endif
endif
endfunction
private function onPreDamageEvent takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer id
local real r = 0
local Item it
local integer lvl
local boolean st = IsUnitType(data.target,UNIT_TYPE_STRUCTURE)
local Buff b
//-------Events for all type of damage
set b = GetUnitBuff(data.target,RageItem.buff)
if b != 0 then
set data.mult = data.mult + RageItem[b.buffAllocIndex].inc
endif
set b = GetUnitBuff(data.source,RageItem.buff)
if b != 0 then
set data.mult = data.mult + RageItem[b.buffAllocIndex].inc
endif
//-----------Events for all damage but no heal
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if data.dmgType != udg_DamageTypeAttack then
set b = GetUnitBuff(data.source,HowlOfTerror.buff)
if b != 0 then
set data.mult = data.mult - (0.05 + 0.05 * b.level)
endif
set b = GetUnitBuff(data.target,MagicBulwark.buff)
if b != 0 then
if GetRandomInt(1,100) <= (10 * b.level + UnitStat.GetStat(STAT_BLOCK_CHANCE,b.target)) then
set data.mult = data.mult - 0.30
call DestroyEffect(AddSpecialEffectTarget(BLOCK_SFX,b.target,"chest"))
endif
endif
set it = GetUnitItemOfType(data.target,'axas')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(data.target,'A0DE') == 0 and data.damageMod != 0 then
call BlzStartUnitAbilityCooldown(data.target,'A0DE',6.0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl",data.target,"chest"))
set data.add = data.add - 40
endif
endif
endif
set it = GetUnitItemOfType(data.source,'amrc')
if it != 0 then
if not st and not IsUnitType(data.target,UNIT_TYPE_HERO) then
set data.mult = data.mult + 0.10
endif
endif
set b = GetUnitBuff(data.source,Cripple.buff)
if b != 0 then
set data.mult = data.mult - Cripple[b.buffAllocIndex].dmgRed
endif
set b = GetUnitBuff(data.target,Assimilate.buff)
if b != 0 and data.dmgType != udg_DamageTypeAttack then
set data.mult = data.mult - 0.90
endif
set b = GetUnitBuff(data.target,ShadowWalk.buff)
if b != 0 then
set data.mult = data.mult - (0.20 + 0.20 * b.level)
endif
set b = GetUnitBuff(data.source,ShadowWalk.buff)
if b != 0 then
set data.mult = data.mult - (0.20 + 0.20 * b.level)
endif
set it = GetUnitItemOfType(data.source,'bgst')
if it != 0 and not st then
if GetUnitLifePercent(data.target) <= 20 then
set data.mult = data.mult + 0.08 + 0.02 * it.tier
call DestroyEffect(AddSpecialEffectTarget(ATTACK_SFX,data.target,"overhead"))
endif
endif
endif
//-----------Events for healing or hot
if data.dmgType == udg_DamageTypeHeal or data.dmgType == udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,SinisterMark.buff)
if b != 0 then
set data.mult = data.mult - SinisterMark[b.buffAllocIndex].red
endif
set b = GetUnitBuff(data.target,AncientHeal.buff)
if b != 0 then
set data.mult = data.mult + AncientHeal[b.buffAllocIndex].amp
endif
endif
//-------Events for attack damage
if data.dmgType == udg_DamageTypeAttack then
set it = GetUnitItemOfType(data.target,'rde4')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(data.target,'A05Z') == 0 then
call BlzStartUnitAbilityCooldown(data.target,'A05Z',3.0)
set data.trueEvasion = true
call DestroyEffect(AddSpecialEffectTarget(CHANCE_SFX,data.target,"origin"))
endif
endif
set it = GetUnitItemOfType(data.target,'vddl')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(data.target,'A0CR') == 0 then
call BlzStartUnitAbilityCooldown(data.target,'A0CR',5.0)
set data.mult = data.mult - 0.50
endif
endif
set it = GetUnitItemOfType(data.source,'blba')
if it != 0 then
if not st and IsUnitType(data.target,UNIT_TYPE_HERO) then
if GetUnitLifePercent(data.target) <= 50 then
set data.add = data.add + 10
endif
endif
endif
set it = GetUnitItemOfType(data.source,'stwa')
if it != 0 then
if GetUnitAbilityLevel(data.target,'A0CP') != 0 then
set data.mult = data.mult + 0.25
endif
endif
set it = GetUnitItemOfType(data.source,'rwiz')
if it != 0 then
if GetRandomInt(1,100) <= 35 and not st then
set data.add = data.add + (10.00 + 10 * it.tier)
call DestroyEffect(AddSpecialEffectTarget(ATTACK_SFX,data.target,"overhead"))
endif
endif
set it = GetUnitItemOfType(data.source,'evtl')
if it != 0 then
set data.ignoreArmor = data.ignoreArmor + (2 * it.tier)
call DestroyEffect(AddSpecialEffectTarget(ATTACK_SFX,data.target,"overhead"))
endif
set b = GetUnitBuff(data.source,ShiningBlast.buff)
if b != 0 then
set data.trueEvasion = true
endif
set b = GetUnitBuff(data.target,SafeStep.buff)
if b != 0 then
set data.trueBlock = true
endif
set b = GetUnitBuff(data.source,WindWalk.buff)
if b != 0 then
set data.add = data.add + (25 + 50 * b.level)
set data.trueCritical = true
call b.remove()
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl",data.target,"overhead"))
endif
set b = GetUnitBuff(data.source,SparklingCurrent.buff)
if b != 0 then
set data.criticalChanceAdd = data.criticalChanceAdd + SparklingCurrent[b.buffAllocIndex].crit
endif
endif
//-----Event for all damage but no attack damage
if data.dmgType != udg_DamageTypeAttack then
set b = GetUnitBuff(data.source,SpellBoost.buff)
if b != 0 then
set data.mult = data.mult + 0.03 * b.int
endif
set it = GetUnitItemOfType(data.source,'pdiv')
if it != 0 then
set data.criticalChanceAdd = data.criticalChanceAdd + GetItemCharges(it.itemS)
endif
endif
//-----Event for area damage
endfunction
private function onDamageEvent takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local real r1 = 0
local real r2 = 0
local integer i = 0
local integer i2 = 0
local Item it
local Buff b
local DamageOptions op
local boolean s = IsUnitType(data.target,UNIT_TYPE_STRUCTURE)
local boolean ss = IsUnitType(data.source,UNIT_TYPE_STRUCTURE)
local boolean hs = IsUnitType(data.source,UNIT_TYPE_HERO)
local boolean ht = IsUnitType(data.target,UNIT_TYPE_HERO)
//----Events for all damage except heals
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,FelSeal.buff)
if b != 0 and data.damageMod >= 50 then
call Status.AddTime(STATUS_SILENCE,data.target,0.25)
call AddUnitBuffDuration(data.target,FelSeal.buff,0.25)
set FelSeal[b.buffAllocIndex].time = FelSeal[b.buffAllocIndex].time + 0.25
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\GargoyleMissile\\GargoyleMissile.mdl",b.target,"overhead"))
endif
set b = GetUnitBuff(data.target,MoltenSpikes.buff)
if b != 0 and not data.isAbsorbed then
if hs and data.codeDmg.codeName != "Returned" then
if MoltenSpikes[b.buffAllocIndex].instances != 0 then
set MoltenSpikes[b.buffAllocIndex].instances = MoltenSpikes[b.buffAllocIndex].instances - 1
call SetItemCharges(MoltenSpikes[b.buffAllocIndex].it.itemS,MoltenSpikes[b.buffAllocIndex].instances)
call MissileMoltenSpike(data.target,data.source,data.damageMod)
if MoltenSpikes[b.buffAllocIndex].instances == 0 then
call UnitRemoveBuff(data.target,MoltenSpikes.buff)
endif
endif
endif
endif
if not data.isAbsorbed and data.isCritical then
set it = GetUnitItemOfType(data.target,'sorf')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(data.target,it.abilityID) == 0 then
call BlzStartUnitAbilityCooldown(data.target,it.abilityID,5.0)
call DiamondSpears(it,1)
endif
endif
endif
if data.damageMod > 0 and data.dmgType != udg_DamageTypeAttack then
set it = GetUnitItemOfType(data.source,'woms')
if it != 0 then
if GetRandomInt(1,100) <= 40 and data.damageMod >= 75 and data.codeDmg.codeName != "UDDamage" then
call UnstableDarkDamage(data.source,data.target,it.tier,data.damageMod)
endif
endif
set it = GetUnitItemOfType(data.target,'I00S')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(data.target,'A060') == 0 then
set i = GetItemCharges(it.itemS)
set it.realD = it.realD + data.damageMod
if it.realD >= 50 then
set i2 = R2I(it.realD / 50.00)
set it.realD = it.realD - i2 * 50.00
set i = i + i2
if i >= 14 - 2 * it.tier then
call BlzStartUnitAbilityCooldown(data.target,'A060',4.0)
call SetItemCharges(it.itemS,0)
call DamageArea(data.target,400,100 + 50 * it.tier,udg_DamageTypeHeal,true,false,"Abilities\\Spells\\Items\\RitualDagger\\RitualDaggerTarget.mdl","overhead")
else
call SetItemCharges(it.itemS,i)
endif
endif
endif
endif
set it = GetUnitItemOfType(data.source,'pdiv')
if it != 0 then
call TrinketBuffs_PhoenixFireBonus.evaluate(it)
endif
endif
if data.damageMod > 0 and not data.isAbsorbed and data.dmgType != udg_DamageTypeAttack then
set it = GetUnitItemOfType(data.target,'I00T')
if it != 0 then
if GetUnitLifePercent(data.target) < 25 and BlzGetUnitAbilityCooldownRemaining(data.target,'A04B') == 0 then
call UnitAddBuff(data.target,data.target,4.5,Assimilate.buff,it.tier,0)
call BlzStartUnitAbilityCooldown(data.target,'A04B',80 - 10 * it.tier)
endif
endif
endif
if data.damageMod > 0 and not data.isAbsorbed and hs then
set it = GetUnitItemOfType(data.target,'dkfw')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(data.target,'A05C') == 0 then
set i = GetItemCharges(it.itemS)
set i = i + R2I(data.damageMod)
if i >= 600 then
set i = 0
call UnitAddBuff(data.target,data.target,2.5,Void.buff,0,0)
call BlzStartUnitAbilityCooldown(data.target,'A05C',100 - 20 * it.tier)
endif
call SetItemCharges(it.itemS,i)
endif
endif
endif
endif
if data.dmgType == udg_DamageTypeMagicOverTime or data.dmgType == udg_DamageTypePhysicalOverTime then
set it = GetUnitItemOfType(data.source,'sand')
if it != 0 then
if GetRandomInt(1,100) <= 15 then
set r2 = -10 + 20 * it.tier
set r1 = GetRandomReal(r2,r2 + 20)
call CodeDamage.Damage(data.source,data.target,r1,udg_DamageTypeMagic,"",0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl",data.target,"chest"))
endif
endif
endif
//---Events for attack damage
if data.dmgType == udg_DamageTypeAttack and not data.isMiss then
set it = GetUnitItemOfType(data.source,'anfg')
if it != 0 then
call UnitAddBuff(data.target,data.source,3.0,Poison.buff,0,0)
endif
set it = GetUnitItemOfType(data.target,'ledg')
if it != 0 then
if hs then
set i = GetItemCharges(it.itemS)
set i = i + 1
if i == 10 then
//call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\snapMissile\\snapMissile.mdl",data.target,"overhead"))
call UnitAddBuff(data.target,data.target,4.0,ForestBlessing.buff,it.tier,0)
set i = 0
endif
call SetItemCharges(it.itemS,i)
endif
endif
set it = GetUnitItemOfType(data.source,'rat9')
if it != 0 and data.isCritical then
call UnitAddBuff(data.source,data.source,8.0,SparklingCurrent.buff,it.tier,it)
endif
set it = GetUnitItemOfType(data.target,'sclp')
if it != 0 and not ss then
set i = GetItemCharges(it.itemS)
if GetRandomInt(1,100) <= 15 + i then
set r1 = BlzGetUnitArmor(data.target) * (2 * it.tier)
call CodeDamage.Damage(data.target,data.source,25 + r1,udg_DamageTypePhysical,"",0,0)
call Status.Add(STATUS_STUN,data.source,0.20,Status_EFFECT[STATUS_STUN])
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\RockBoltMissile\\RockBoltMissile.mdl",data.source,"overhead"))
endif
set i = i + 1
if i <= 30 then
call SetItemCharges(it.itemS,i)
endif
endif
set it = GetUnitItemOfType(data.source,'bspd')
if it != 0 then
if not s and data.allowOrbs and IsUnitType(data.source,UNIT_TYPE_RANGED_ATTACKER) then
set i = GetItemCharges(it.itemS)
set i = i + 1
if i >= 6 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\snapMissile\\snapMissile.mdl",data.target,"overhead"))
call UnitAddBuff(data.target,data.source,3.0,EnvenomedShots.buff,it.tier,0)
set i = 0
endif
call SetItemCharges(it.itemS,i)
endif
endif
set it = GetUnitItemOfType(data.source,'ratc')
if it != 0 then
if not s and data.allowOrbs and IsUnitType(data.source,UNIT_TYPE_MELEE_ATTACKER) then
set i = GetItemCharges(it.itemS)
set i = i + 1
if i >= 8 - 1 * it.tier then
call KPJUnit.create(data.target,120,AngleBetweenUnits(data.source,data.target),1.5,0,KPJDefaultConfig3,KPJ_TYPE_KNOCKBACK)
set r1 = GetHeroStr(data.source,true) * (15 + 10 * it.tier) / 100
call CodeDamage.Damage(data.source,data.target,(60 + 30 * it.tier) + r1,udg_DamageTypePhysical,"",0,0)
set i = 0
endif
call SetItemCharges(it.itemS,i)
endif
endif
set b = GetUnitBuff(data.target,Chop.buff)
if b != 0 and data.allowOrbs then
call UnitAddBuff(data.target,data.source,1.5,ChopSlow.buff,0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\MeatwagonMissile\\MeatwagonMissile.mdl",b.target,"overhead"))
endif
set b = GetUnitBuff(data.source,ArcaneStrike.buff)
if b != 0 then
call b.remove()
set b = UnitStealBuff(data.target,data.source)
if b != 0 then
call CreateTextTagForPlayer(GetOwningPlayer(data.source),GetUnitX(data.source),GetUnitY(data.source),"|c008080ff"+b.Name,12)
call CodeDamage.Damage(data.source,data.target,60.00 * b.level,udg_DamageTypeMagic,"",0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl",data.target,"origin"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl",data.source,"origin"))
endif
endif
set it = GetUnitItemOfType(data.source,'belv')
if it != 0 and not s then
call UnitAddBuff(data.target,data.source,6.0,SinisterMark.buff,it.tier,0)
endif
set it = GetUnitItemOfType(data.source,'stel')
if it != 0 and not s then
if GetRandomInt(1,100) <= 20 and not UnitHasBuff(data.source,Swiftness.buff) then
call UnitAddBuff(data.source,data.source,7.0,Swiftness.buff,it.tier,0)
call DestroyEffect(AddSpecialEffectTarget(CHANCE_SFX,data.source,"origin"))
endif
endif
set it = GetUnitItemOfType(data.target,'kybl')
if it != 0 then
if GetUnitLifePercent(data.target) <= 35 and not UnitHasBuff(data.target,ReactiveArmor.buff) then
call UnitAddBuff(data.target,data.target,10.0,ReactiveArmor.buff,it.tier,0)
call DestroyEffect(AddSpecialEffectTarget(CHANCE_SFX,data.target,"origin"))
endif
endif
set it = GetUnitItemOfType(data.source,'spsh')
if it != 0 and data.mainAttack then
if BlzGetUnitAbilityCooldownRemaining(data.source,it.abilityID) == 0 then
call BlzStartUnitAbilityCooldown(data.source,it.abilityID,7.0 - 1.0 * it.tier)
set r1 = GetUnitX(data.source)
set r2 = GetUnitY(data.source)
call SetUnitX(it.dummy,r1)
call SetUnitY(it.dummy,r2)
call CastDummyWave(it.dummy,ORDER_carrionswarm,GetUnitX(data.target),GetUnitY(data.target))
endif
endif
set it = GetUnitItemOfType(data.source,'ajen')
if it != 0 and not data.isAbsorbed and data.codeDmg.codeName != "ThunderAttack" and not s then
if BlzGetUnitAbilityCooldownRemaining(data.source,'A04D') == 0 then
set op = DamageOptions.create()
set op.allowOrbs = true
call CodeDamage.Damage(data.source,data.target,data.damageMod * (0.20 + 0.10 * it.tier),udg_DamageTypeAttack,"ThunderAttack",0,op)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl",data.target,"origin"))
call Status.Add(STATUS_STUN,data.target,0.75,Status_EFFECT[STATUS_STUN])
call BlzStartUnitAbilityCooldown(data.source,'A04D',3.50)
endif
endif
set it = GetUnitItemOfType(data.source,'desc')
if it != 0 then
if GetRandomInt(1,100) <= 30 and not UnitHasBuff(data.source,VampiricBlood.buff) then
call UnitAddBuff(data.source,data.source,7.0,VampiricBlood.buff,it.tier,0)
call DestroyEffect(AddSpecialEffectTarget(CHANCE_SFX,data.source,"origin"))
endif
endif
endif
if data.dmgType == udg_DamageTypeAttack then
set it = GetUnitItemOfType(data.target,'mort')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(data.target,'A08O') == 0 and hs then
call ApplyShiningBlast(data.target,it.tier)
call BlzStartUnitAbilityCooldown(data.target,'A08O',15.00)
endif
endif
endif
if data.isMiss then
set it = GetUnitItemOfType(data.target,'rde4')
if it != 0 then
call UnitAddBuff(data.target,data.target,999.0,Untouchable.buff,it.tier,it)
endif
set it = GetUnitItemOfType(data.target,'azhr')
if it != 0 then
call UnitAddBuff(data.target,data.target,12.0,Snakeskin.buff,it.tier,it)
endif
set it = GetUnitItemOfType(data.target,'vpur')
if it != 0 then
set r2 = BlzGetUnitAbilityCooldownRemaining(data.target,'A0CV')
if r2 == 0 and hs then
call BlzStartUnitAbilityCooldown(data.target,'A0CV',5 - 1 * it.tier)
call MissileViperCounter(data.target,data.source)
endif
endif
endif
if data.isBlock then
if ht then
set it = GetUnitItemOfType(data.target,'k3m3')
if it != 0 then
set r2 = BlzGetUnitAbilityCooldownRemaining(data.target,'A05H')
if r2 != 0 then
set r1 = 0.25 + 0.25 * it.tier
if hs then
set r1 = r1 * 2
endif
call BlzStartUnitAbilityCooldown(data.target,'A05H',r2 - r1)
endif
endif
set it = GetUnitItemOfType(data.target,'tkno')
if it != 0 then
set r2 = BlzGetUnitAbilityCooldownRemaining(data.target,'A0DA')
if r2 == 0 then
call UnitAddHp(data.target,BlzGetUnitMaxHP(data.target) * 0.05)
call DestroyEffect(AddSpecialEffectTarget(HEAL_SFX,data.target,"overhead"))
call BlzStartUnitAbilityCooldown(data.target,'A0DA',7 - 1 * it.tier)
endif
endif
endif
endif
endfunction
private function onDummyDamageEvent takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local DamageOptions op
local Item it
local unit u
local Hero h
//Crushing Wave
if GetUnitAbilityLevel(data.source,'A02F') != 0 then
set it = GetUnitUserData(data.source)
call CodeDamage.Damage(it.wielder,data.target,50 + 25 * it.tier,udg_DamageTypeMagicAoe,"",0,0)
endif
//Meteoric Attack
if GetUnitAbilityLevel(data.source,'A03G') != 0 then
set u = GetUnitByIndex(GetUnitUserData(data.source))
call CodeDamage.Damage(u,data.target,75.00,udg_DamageTypeMagicAoe,"",0,0)
set u = null
endif
if GetUnitAbilityLevel(data.source,'Amnx') != 0 then
set h = GetPlayerHero(GetOwningPlayer(data.source))
set u = h.hero
if IsUnitType(data.target,UNIT_TYPE_HERO) then
call CodeDamage.Damage(u,data.target,100.00,udg_DamageTypePure,"",0,0)
call Status.Add(STATUS_ENSNARE,data.target,4.00,Status_EFFECT[STATUS_ENSNARE])
else
if GetUnitLevel(data.target) <= 3 then
call CodeDamage.Damage(u,data.target,0.00,udg_DamageTypePure,"KillBlow",0,0)
else
call CodeDamage.Damage(u,data.target,200.00,udg_DamageTypePure,"",0,0)
endif
endif
set u = null
endif
endfunction
private function ItemSummonEvent takes nothing returns nothing
local unit u = GetSummoningUnit()
local unit s = GetSummonedUnit()
local integer id = GetUnitTypeId(s)
local Item it
local integer r
local integer i
if id == 'n00R' then
set it = GetUnitItemOfType(u,'I006')
if it != 0 then
set r = R2I(BlzGetUnitMaxHP(u) * (0.15 + 0.05 * it.tier))
call BonusStruct.Add(BONUS_TYPE_HP,s,r,0,false)
endif
endif
if id == 'nglm' then
call UnitApplyTimedLife(s,'BTLF',120.00)
endif
if id == 'ninf' then
set r = BlzGetUnitIntegerField(u,UNIT_IF_PRIMARY_ATTRIBUTE)
if r == 1 then
set i = GetHeroStr(u,true)
elseif r == 2 then
set i = GetHeroInt(u,true)
elseif r == 3 then
set i = GetHeroAgi(u,true)
endif
call BlzSetUnitMaxHP(s,500 + 20 * i)
call BlzSetUnitBaseDamage(s, 25 + i,0)
call SetUnitState(s,UNIT_STATE_LIFE,999999)
endif
set u = null
set s = null
endfunction
private function OnStatus takes nothing returns nothing
local StatusObject s = EVENT_STATUS
local Item it
if IsUnitType(s.target,UNIT_TYPE_HERO) then
set it = GetUnitItemOfType(s.target,'phlt')
if it != 0 then
if BlzGetUnitAbilityCooldownRemaining(s.target,'A0CU') == 0 and not s.permanent and s.status <= 12 then
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl",s.target,"origin"))
set s.duration = s.duration / 2
call UnitAddBuff(s.target,s.target,3.0,HealingStream.buff,it.tier,0)
call BlzStartUnitAbilityCooldown(s.target,'A0CU',20 - 4 * it.tier)
endif
endif
endif
endfunction
private function OnTeleport takes nothing returns nothing
local unit u = TELEPORT_UNIT
local Item it
if TELEPORT_SUCCESS == 1 then
set it = GetUnitItemOfType(u,'arsh')
if it != 0 then
call UnitAddBuff(u,u,3.00,HasteRuneBuff.buff,0,0)
endif
endif
set u = null
endfunction
private function OnHeroRespawnEnd takes nothing returns boolean
local unit u = RespawnedHero
local Buff b = GetUnitBuff(u,Immolation.buff)
if b != 0 then
call Immolation[b.buffAllocIndex].enable()
endif
set u = null
return false
endfunction
private function OnHeroRespawn takes nothing returns boolean
local unit u = RespawnedHero
local Respawn rs = Respawn[GetUnitUserData(u)]
local Item it
set it = GetUnitItemOfType(u,'ratf')
if it != 0 then
set rs.timeLeft = rs.timeLeft - rs.timeLeft * 0.25
endif
set u = null
return false
endfunction
private function init takes nothing returns nothing
call RegisterHeroRespawnEvent(Filter(function OnHeroRespawn),EVENT_PLAYER_HERO_RESPAWN_START)
call RegisterHeroRespawnEvent(Filter(function OnHeroRespawnEnd),EVENT_PLAYER_HERO_RESPAWN_END)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function ItemSpellEvent)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function ItemDeathEvent)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SUMMON, function ItemSummonEvent)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamageEvent))
call DamageEvent.RegisterPostCalculation(Filter(function onPostDamageEvent))
call DamageEvent.RegisterDamage(Filter(function onDamageEvent))
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDamageEvent))
call RegisterCombatEvent(function OnLeaveCombat,EVENT_UNIT_LEAVE_COMBAT)
call RegisterCombatEvent(function OnEnterCombat,EVENT_UNIT_ENTER_COMBAT)
call RegisterUnitStatusEvent(function OnStatus)
call RegisterTeleportEvent(function OnTeleport)
endfunction
endscope
library ItemMissiles uses Missile, MiscLibrary
struct DiamondSpearMissile extends array
private static method onFinish takes Missile missile returns boolean
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeMagicAoe,"",0,0)
return true
endmethod
implement MissileStruct
endstruct
struct ViperCounterMissile extends array
private static method onFinish takes Missile missile returns boolean
call CodeDamage.Damage(missile.source,missile.target,GetUnitAttackDamage(missile.source),udg_DamageTypePhysical,"",0,0)
call UnitAddBuff(missile.target,missile.source,2.0,ViperCounter.buff,0,0)
return true
endmethod
implement MissileStruct
endstruct
struct SpiderNet extends array
private static method onFinish takes Missile missile returns boolean
local real d = 1.2 + ((GetUnitMoveSpeed(missile.target) / 50) * 0.20)
call Status.Add(STATUS_ENSNARE,missile.target,d,SN_EFFECT)
call CodeDamage.Damage(missile.source,missile.target,80.00 + 40.00 * missile.level,udg_DamageTypeMagic,"",0,0)
return true
endmethod
implement MissileStruct
endstruct
struct FireGuardMissile extends array
private static method onFinish takes Missile missile returns boolean
local group g
local unit temp
if not TriggerSpellNegation(missile.target) then
set g = NewGroup()
call DestroyEffect(AddSpecialEffect(missile.model,missile.x,missile.y))
call GroupEnumUnitsInRange(g,missile.x,missile.y,200,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) then
call CodeDamage.Damage(missile.source,temp,150.00,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_STUN,temp,1.5,Status_EFFECT[STATUS_STUN])
endif
endloop
call ReleaseGroup(g)
set g = null
endif
if TriggerSpellReflection(missile.target) then
call MissileFireGuard.evaluate(missile.target,missile.source)
endif
return true
endmethod
implement MissileStruct
endstruct
struct SoulStrikeMissile extends array
private static method onFinish takes Missile missile returns boolean
if missile.data == 1 then
if IsUnitAlly(missile.target,missile.owner) then
call UnitAddHp(missile.target,missile.damage)
else
call UnitRemoveHp(missile.target,missile.damage)
endif
elseif missile.data == 2 then
if IsUnitAlly(missile.source,missile.owner) then
call UnitRemoveHp(missile.target,missile.damage)
else
call UnitAddHp(missile.target,missile.damage)
endif
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl",missile.target,"chest"))
return true
endmethod
implement MissileStruct
endstruct
struct MoltenSpikeMissile extends array
private static method onFinish takes Missile missile returns boolean
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypePure,"Returned",0,0)
return true
endmethod
implement MissileStruct
endstruct
struct DisruptiveShotMissile extends array
private static method onFinish takes Missile missile returns boolean
local real x1 = GetUnitX(missile.target)
local real y1 = GetUnitY(missile.target)
local real x2 = GetUnitX(missile.source)
local real y2 = GetUnitY(missile.source)
if UnitAlive(missile.target) and UnitAlive(missile.source) then
call SetUnitX(missile.source,x1)
call SetUnitY(missile.source,y1)
call SetUnitX(missile.target,x2)
call SetUnitY(missile.target,y2)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl",missile.target,"overhead"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl",missile.source,"overhead"))
call UnitDispelAllBuffs(missile.target,BUFF_TYPE_NEGATIVE)
call UnitDispelAllBuffs(missile.target,BUFF_TYPE_POSITIVE)
call UnitDispelAllBuffs(missile.source,BUFF_TYPE_NEGATIVE)
call UnitDispelAllBuffs(missile.source,BUFF_TYPE_POSITIVE)
endif
return true
endmethod
implement MissileStruct
endstruct
private function CycloneEnd takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetUnitByIndex(GetTimerData(t))
call UnitRestartBuffs(u,BUFF_TYPE_POSITIVE)
call ReleaseTimer(t)
set t = null
set u = null
endfunction
struct WindFluteMissile extends array
private static method onFinish takes Missile missile returns boolean
call Status.Add(STATUS_CYCLONE,missile.target,1.4,Status_EFFECT[STATUS_CYCLONE])
call TimerStart(NewTimerEx(GetUnitUserData(missile.target)),1.4,false,function CycloneEnd)
return true
endmethod
implement MissileStruct
endstruct
struct ThrowShieldMissile extends array
private static method onFinish takes Missile missile returns boolean
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl",missile.x,missile.y))
if UnitAlive(missile.target) then
if not TriggerSpellNegation(missile.target) then
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypePhysical,"",0,0)
call Status.Add(STATUS_STUN,missile.target,1.6,Status_EFFECT[STATUS_STUN])
endif
if TriggerSpellReflection(missile.target) then
call MissileThrowShield.evaluate(missile.target,missile.source,missile.level)
endif
return true
endif
return false
endmethod
implement MissileStruct
endstruct
struct ThrowGrenadeMissile extends array
private static method onFinish takes Missile missile returns boolean
local group g = NewGroup()
local unit temp
call DestroyEffect(AddSpecialEffect(missile.model,missile.x,missile.y))
call GroupEnumUnitsInRange(g,missile.x,missile.y,160,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_VALID_UNIT(temp) and IsUnitEnemy(temp,missile.owner) then
if IsUnitType(temp,UNIT_TYPE_STRUCTURE) then
call CodeDamage.Damage(missile.source,temp,300,udg_DamageTypeMagicAoe,"",0,0)
else
if IsUnitType(temp,UNIT_TYPE_HERO) then
call CodeDamage.Damage(missile.source,temp,100,udg_DamageTypeMagicAoe,"",0,0)
else
call CodeDamage.Damage(missile.source,temp,200,udg_DamageTypeMagicAoe,"",0,0)
endif
call Status.Add(STATUS_STUN,temp,0.6,Status_EFFECT[STATUS_STUN])
call KPJUnit.create(temp,180,Angle(missile.x,missile.y,GetUnitX(temp),GetUnitY(temp)),0.6,0,KPJDefaultConfig3,KPJ_TYPE_KNOCKBACK)
endif
endif
endloop
call ReleaseGroup(g)
set g = null
return true
endmethod
implement MissileStruct
endstruct
function MissileSoulStrike takes unit source, unit target, real dmg, integer op returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
if op == 2 then
set missile.owner = GetOwningPlayer(target)
else
set missile.owner = GetOwningPlayer(source)
endif
set missile.damage = dmg
set missile.data = op
set missile.speed = 35
set missile.model = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilMissile.mdl"
set missile.scale = 1.5
call SoulStrikeMissile.launch(missile)
return missile
endfunction
function MissileSpiderNet takes unit source, unit target, integer lvl returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.level = lvl
set missile.owner = GetOwningPlayer(source)
set missile.speed = 45
set missile.model = "Abilities\\Spells\\Undead\\Web\\WebTarget.mdl"
set missile.scale = 0.40
call SpiderNet.launch(missile)
return missile
endfunction
function MissileFireGuard takes unit source, unit target returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 20
set missile.model = "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
set missile.scale = 1.50
call FireGuardMissile.launch(missile)
return missile
endfunction
function MissileMoltenSpike takes unit source, unit target, real dmg returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 33
set missile.damage = dmg * 0.75
set missile.model = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
set missile.scale = 1.50
call MoltenSpikeMissile.launch(missile)
return missile
endfunction
function MissileDisruptiveShot takes unit source, unit target returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 30
set missile.model = "Abilities\\Spells\\NightElf\\shadowstrike\\ShadowStrikeMissile.mdl"
set missile.scale = 1.20
call DisruptiveShotMissile.launch(missile)
return missile
endfunction
function MissileWindFlute takes unit source, unit target returns Missile
local Missile missile
if source == target then
call Status.Add(STATUS_CYCLONE,target,1.8,Status_EFFECT[STATUS_CYCLONE])
call TimerStart(NewTimerEx(GetUnitUserData(target)),1.8,false,function CycloneEnd)
return 0
endif
set missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 30
set missile.model = "Abilities\\Spells\\NightElf\\Cyclone\\CycloneTarget.mdl"
set missile.scale = 1.0
call WindFluteMissile.launch(missile)
return missile
endfunction
function MissileThrowShield takes unit source, unit target, integer lvl returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 40
set missile.damage = 50.00 + 50.00 * lvl
set missile.model = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltMissile.mdl"
set missile.scale = 2.0
call ThrowShieldMissile.launch(missile)
return missile
endfunction
function MissileThrowGrenade takes unit source, real x, real y returns Missile
local real xu = GetUnitX(source)
local real yu = GetUnitY(source)
local Missile missile = Missile.createXYZ(xu,yu,25.00,x,y,25.00)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.speed = 30
set missile.arc = 45 * bj_DEGTORAD
set missile.model = "war3mapImported\\PotatoMasher.mdx"
set missile.scale = 2
call ThrowGrenadeMissile.launch(missile)
return missile
endfunction
function MissileViperCounter takes unit source, unit target returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 40
set missile.model = "Abilities\\Spells\\NightElf\\shadowstrike\\ShadowStrikeMissile.mdl"
set missile.scale = 1.0
call ViperCounterMissile.launch(missile)
return missile
endfunction
function MissileDiamondSpear takes unit source, unit target, real dmg returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),65.00,AngleBetweenUnits(source,target),0,65.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 40
set missile.damage = dmg
set missile.model = "Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl"
set missile.scale = 0.75
call DiamondSpearMissile.launch(missile)
return missile
endfunction
endlibrary
library OnAttackEffects initializer init uses Bonus
globals
private constant string SFX_LIFESTEAL = "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl"
private constant string SFX_FEED = "Abilities\\Spells\\Human\\Feedback\\ArcaneTowerAttack.mdl"
private constant string SFX_CORRUPTION = "Abilities\\Spells\\Items\\OrbCorruption\\OrbCorruptionSpecialArt.mdl"
private constant string SFX_MANAS = "Abilities\\Spells\\Undead\\ReplenishMana\\ReplenishManaCasterOverhead.mdl"
private constant string SFX_MANA = "Abilities\\Spells\\Undead\\ReplenishMana\\SpiritTouchTarget.mdl"
public constant integer FROST_ID = 'A06U'
public constant integer CORRUPTION_ID = 'A06T'
public constant integer FEEDBACK_ID = 'A06V'
public constant integer BRUTE_ID = 'A06W'
public constant integer CLEAVE_ID = 'A06Y'
public constant integer BLEED_ID = 'A06X'
public constant integer ARCANE_ID = 'A06Z'
public constant integer COLD_STEEL_ID = 'A073'
public constant integer M_THORNS_ID = 'A076'
public constant integer I_THORNS_ID = 'A09H'
public constant integer PERSEVERANCE_ID = 'A074'
public constant integer MANA_ID = 'A075'
public constant integer ENDURANCE_ID = 'A09I'
public constant integer IMMOLATION_ID = 'AIcf'
endglobals
private function DiamondRevestimentStrike takes unit hero, unit source, real damage, integer dmgtype returns nothing
call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\RainOfCrystalTarget.mdx",source,"origin"))
call CodeDamage.Damage(hero,source,damage * 1.2,dmgtype,"",0,0)
endfunction
private function onDummyDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local unit h
local DamageOptions op
local Immolation b
if GetUnitAbilityLevel(data.source,IMMOLATION_ID) != 0 then
set h = Index[GetUnitUserData(data.source)].u
set b = GetUnitBuff(h,Immolation.buff).buffAllocIndex
if UnitAlive(h) and IsUnitInCombat(h) and b != 0 then
set op = DamageOptions.create()
set op.notCritical = true
call CodeDamage.Damage(h,data.target,b.dmg,udg_DamageTypeMagicOverTime,"",0,op)
endif
set h = null
endif
endfunction
private function onPostDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local real evalue
local real r
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if not data.isAbsorbed and data.damageMod > 0 then
set lvl = GetUnitAbilityLevel(data.target,MANA_ID)
if lvl != 0 then
set evalue = EnchantEffect.Get(EFFECT_MANA_SHIELD,data.target)
if GetRandomInt(1,100) <= R2I(evalue) then
set r = (data.damageMod * 0.50)
if GetUnitState(data.target,UNIT_STATE_MANA) >= r then
call DestroyEffect(AddSpecialEffectTarget(SFX_MANAS,data.target,"overhead"))
call UnitRemoveMp(data.target,r * 2)
set data.damageMod = data.damageMod * 0.50
endif
endif
endif
endif
if data.isCritical then
set lvl = GetUnitAbilityLevel(data.target,'B05S')
if lvl != 0 then
set data.damageMod = data.damageMod - data.damageMod * 0.12
endif
set lvl = GetUnitAbilityLevel(data.target,'B05T')
if lvl != 0 then
set data.damageMod = data.damageMod - data.damageMod * 0.16
endif
if GetUnitAbilityLevel(data.target,'A040') != 0 and data.damageMod != 0 then
set evalue = EnchantEffect.Get(EFFECT_DIAMOND,data.target)
if BlzGetUnitAbilityCooldownRemaining(data.target,'A040') == 0 then
if IsUnitEnemy(data.source,GetOwningPlayer(data.target)) then
call BlzStartUnitAbilityCooldown(data.target,'A040',evalue)
call AddUnitShield(data.target,data.damageMod * 1.5,5.00,0)
endif
endif
endif
endif
endif
endfunction
private function onPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local real evalue
local Buff b
local real r
if data.dmgType == udg_DamageTypeAttack and not data.isMiss then
set b = GetUnitBuff(data.target,Bleed.buff)
if b != 0 then
set evalue = EnchantEffect.Get(EFFECT_BLEED,b.owner)
set data.mult = data.mult + (evalue * b.stacks)
endif
if GetUnitAbilityLevel(data.source,'A06Y') != 0 then
set evalue = EnchantEffect.Get(EFFECT_CLEAVE,data.source)
if data.codeDmg == 0 and not data.mainAttack and evalue > 0.0 then
set data.trueAttack = true
set data.notCritical = true
set data.mult = evalue
endif
endif
if GetUnitAbilityLevel(data.source,FEEDBACK_ID) != 0 then
if GetUnitState(data.target,UNIT_STATE_MANA) != 0 then
set evalue = EnchantEffect.Get(EFFECT_FEEDBACK,data.source)
call DestroyEffect(AddSpecialEffectTarget(SFX_FEED,data.target,"origin"))
set r = evalue + GetUnitState(data.target,UNIT_STATE_MANA) * 0.01
call UnitRemoveMp(data.target,r)
set data.add = data.add + r / 2
endif
endif
endif
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if GetUnitAbilityLevel(data.target,'B05Q') != 0 then
set data.mult = data.mult - 0.20
endif
endif
endfunction
private function onDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local DamageOptions opd
local Buff b
local real evalue
local real r = 0
local real r2 = 0
local integer lvl
local boolean isHero = IsUnitType(data.source,UNIT_TYPE_HERO)
if isHero and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) then
if data.dmgType == udg_DamageTypeMagic or data.dmgType == udg_DamageTypePhysical or data.dmgType == udg_DamageTypeMagicAoe or data.dmgType == udg_DamageTypePhysicalAoe or data.dmgType == udg_DamageTypePure then
set lvl = GetUnitAbilityLevel(data.target,M_THORNS_ID)
if lvl != 0 and data.codeDmg.codeName != "Returned" then
set evalue = EnchantEffect.Get(EFFECT_MAGIC_THORNS,data.target)
set opd = DamageOptions.create()
set opd.notCritical = true
call CodeDamage.Damage(data.target,data.source,30 + (data.damageMod * evalue),udg_DamageTypePure,"Returned",0,opd)
endif
set lvl = GetUnitAbilityLevel(data.source,'A03W')
if lvl != 0 then
set evalue = EnchantEffect.Get(EFFECT_HUNTER,data.source)
if GetRandomInt(1,100) <= R2I(evalue) then
call UnitAddBuff(data.target,data.source,7.0,Distortion.buff,0,0)
endif
endif
endif
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime and data.dmgType != udg_DamageTypeAttack then
if data.source != data.target then
set r = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_SPELL_LIFESTEAL,data.source) + data.slifestealAdd
if r != 0 then
if not IsUnitType(data.target,UNIT_TYPE_HERO) then
set r = r * 0.50
endif
set r2 = data.damageMod * r
set opd = DamageOptions.create()
set opd.notCritical = true
call CodeDamage.Damage(data.source,data.source,r2,udg_DamageTypeHeal,"Lifesteal",0,opd)
call DestroyEffect(AddSpecialEffectTarget(SFX_LIFESTEAL,data.source,"overhead"))
endif
endif
endif
if data.dmgType != udg_DamageTypeAttack then
if GetUnitAbilityLevel(data.source,ARCANE_ID) != 0 then
set evalue = EnchantEffect.Get(EFFECT_ARCANE,data.source)
if GetRandomInt(1,100) <= R2I(evalue) then
set r = GetUnitState(data.source,UNIT_STATE_MAX_MANA)
call UnitAddMp(data.source,20 + r*0.01)
call DestroyEffect(AddSpecialEffectTarget(SFX_MANA,data.source,"overhead"))
endif
endif
endif
if data.dmgType == udg_DamageTypeAttack then
if data.damageMod > 0 then
set lvl = GetUnitAbilityLevel(data.target,I_THORNS_ID)
if lvl != 0 and data.codeDmg.codeName != "Returned" then
set opd = DamageOptions.create()
set opd.notCritical = true
set evalue = EnchantEffect.Get(EFFECT_IRON_THORNS,data.target)
call CodeDamage.Damage(data.target,data.source,30 + (data.damageMod * evalue),udg_DamageTypePure,"Returned",0,opd)
endif
set lvl = GetUnitAbilityLevel(data.target,COLD_STEEL_ID)
if lvl != 0 then
set evalue = EnchantEffect.Get(EFFECT_FROST,data.target)
call Status.Add(STATUS_FROST,data.source,evalue,0)
endif
set lvl = GetUnitAbilityLevel(data.target,'A044')
if lvl != 0 then
set evalue = EnchantEffect.Get(EFFECT_CREST,data.target)
if GetRandomInt(1,100) <= R2I(evalue) and not data.isMiss then
if IsUnitType(data.source,UNIT_TYPE_MELEE_ATTACKER) then
call KPJUnit.create(data.source,300,AngleBetweenUnits(data.target,data.source),0.75,0,KPJDefaultConfig4,KPJ_TYPE_KNOCKBACK)
else
call Status.Add(STATUS_DISARM,data.source,1.4,Status_EFFECT[STATUS_DISARM])
endif
endif
endif
endif
if not data.isMiss and data.allowOrbs then
set lvl = GetUnitAbilityLevel(data.source,FROST_ID)
if lvl != 0 then
set evalue = EnchantEffect.Get(EFFECT_FROST,data.source)
call Status.Add(STATUS_FROST,data.target,evalue,0)
endif
set lvl = GetUnitAbilityLevel(data.source,CORRUPTION_ID)
if lvl != 0 then
call DestroyEffect(AddSpecialEffectTarget(SFX_CORRUPTION,data.target,"chest"))
call UnitAddBuff(data.target,data.source,7.0,Corruption.buff,0,0)
endif
set lvl = GetUnitAbilityLevel(data.source,'A03P')
if lvl != 0 then
set r = EnchantEffect.Get(EFFECT_BASH,data.source) + data.bashChanceAdd
if r != 0 then
if GetRandomInt(1,100) <= R2I(r) then
call Status.Add(STATUS_STUN,data.target,1.0,Status_EFFECT[STATUS_STUN])
endif
endif
endif
set lvl = GetUnitAbilityLevel(data.source,BRUTE_ID)
if lvl != 0 then
set evalue = EnchantEffect.Get(EFFECT_BRUTE,data.source)
if GetRandomInt(1,100) <= R2I(evalue) then
call UnitAddBuff(data.target,data.source,7.0,Maim.buff,0,0)
endif
endif
set lvl = GetUnitAbilityLevel(data.source,BLEED_ID)
if lvl != 0 then
call UnitAddBuff(data.target,data.source,4.0,Bleed.buff,0,0)
endif
set r = BonusStruct.GetTotalBonusSpecial(BONUS_TYPE_LIFESTEAL,data.source) + data.lifestealAdd
if r != 0 then
set r2 = data.damageMod * r
set opd = DamageOptions.create()
set opd.notCritical = true
call CodeDamage.Damage(data.source,data.source,r2,udg_DamageTypeHeal,"Lifesteal",0,opd)
call DestroyEffect(AddSpecialEffectTarget(SFX_LIFESTEAL,data.source,"overhead"))
endif
endif
endif
endif
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if Status.UnitHasStatus(STATUS_SLEEP,data.target) then
set b = GetUnitBuff(data.target,SleepB.buff)
if b != 0 then
if data.dmgType == udg_DamageTypeAttack and data.source != b.owner then
call Status.Remove(STATUS_SLEEP,data.target)
elseif data.codeDmg.codeName != "PhaseShift" and data.codeDmg != 0 then
call Status.Remove(STATUS_SLEEP,data.target)
endif
else
call Status.Remove(STATUS_SLEEP,data.target)
endif
endif
set lvl = GetUnitAbilityLevel(data.target,PERSEVERANCE_ID)
if lvl != 0 and isHero then
set evalue = EnchantEffect.Get(EFFECT_PERSEVERANCE,data.target)
if GetRandomInt(1,100) <= R2I(evalue) then
call DestroyEffect(AddSpecialEffectTarget(SFX_LIFESTEAL,data.target,"overhead"))
call CodeDamage.Damage(data.target,data.target,GetUnitState(data.target,UNIT_STATE_MAX_LIFE) * 0.01,udg_DamageTypeHeal,"",0,0)
endif
endif
endif
endfunction
private function init takes nothing returns nothing
call DamageEvent.RegisterDamage(Filter(function onDamage))
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
call DamageEvent.RegisterPostCalculation(Filter(function onPostDamage))
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDamage))
endfunction
endlibrary
library Enchant uses MiscLibrary, PlayerLib, Item
globals
private constant string SFX_DONE = "Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl"
private constant string DEFAULT_TOOLTIP = "Shows the enchantment purchased ready to be used on an item."
constant integer ENCHANT_TYPE_WEAPON = 2
constant integer ENCHANT_TYPE_ARMOR = 3
constant integer ENCHANT_TYPE_ANY = 0
constant integer ENCHANT_COST_EFFECT = 1000
constant integer ENCHANT_COST_NORMAL = 400
private constant integer ENCHANT_ITEM_ID = 'A02X'
Event ENCHANT_EVENT
Enchant ENCHANT_ID
unit ENCHANT_HERO
boolean ENCHANT_REMOVE
Item ENCHANT_ITEM
endglobals
public function ResetEnchantAbility takes player p returns nothing
if Game.LocalPlayer == p then
call BlzSetAbilityIcon(ENCHANT_ITEM_ID,"ReplaceableTextures\\CommandButtons\\BTNINV_Enchant_FormulaEpic_01.blp")
call BlzSetAbilityExtendedTooltip(ENCHANT_ITEM_ID,DEFAULT_TOOLTIP,0)
endif
endfunction
struct Enchant
integer enchantType
integer enchantID
integer enchantAbility
string name
string iconPath
private static thistype array Enchants
private static integer Count = 0
public static method GetEnchantByID takes integer id returns thistype
local integer i = 0
loop
if Enchants[i].enchantID == id then
return Enchants[i]
endif
set i = i + 1
exitwhen i == Count
endloop
return 0
endmethod
public method add takes unit u, Item it returns nothing
set ENCHANT_HERO = u
set ENCHANT_ID = this
set ENCHANT_REMOVE = false
set ENCHANT_ITEM = it
call ENCHANT_EVENT.fire()
endmethod
public method remove takes unit u, Item it returns nothing
set ENCHANT_HERO = u
set ENCHANT_ID = this
set ENCHANT_REMOVE = true
set ENCHANT_ITEM = it
call ENCHANT_EVENT.fire()
endmethod
public static method create takes integer t, integer id, string n, integer ab returns thistype
local thistype this = thistype.allocate()
set enchantType = t
set enchantID = id
set enchantAbility = ab
set name = n
set Enchants[Count] = this
set Count = Count + 1
return this
endmethod
endstruct
function EnchantPurchase takes integer id, player p, item i returns nothing
local Hero h = GetPlayerHero(p)
local Enchant e
local Enchant ce = GetUnitData(h.hero,"CURRENT_ENCHANT")
set e = Enchant.GetEnchantByID(id)
if e != 0 then
if ce != 0 then
if ce.enchantType == ENCHANT_TYPE_ANY then
call AddPlayerGold(p,ENCHANT_COST_NORMAL)
else
call AddPlayerGold(p,ENCHANT_COST_EFFECT)
endif
endif
call SetUnitData(h.hero,"CURRENT_ENCHANT",e)
set e.iconPath = BlzGetItemIconPath(i)
if Game.LocalPlayer == p then
call BlzSetAbilityIcon(ENCHANT_ITEM_ID,e.iconPath)
call BlzSetAbilityExtendedTooltip(ENCHANT_ITEM_ID,BlzGetItemTooltip(i)+"|n"+BlzGetItemExtendedTooltip(i)+"|n|nClick to sell this enchantment.",0)
call StartSound(gg_snd_RuneTaken)
endif
//call Message.ShowToPlayer(p,"Enchantment purchased",MESSAGE_STYLE_ERROR)
endif
endfunction
private function SelectEnchantBonusesByName takes unit u, boolean b, string name, Item it returns nothing
local Hero h
local Movespeed ms
if name == "+10 Main Attribute" then
set h = GetUnitData(u,"HeroIndex")
if b then
if h.PrimaryAttribute == 1 then
call BonusStruct.Add(BONUS_TYPE_AGILITY,u,-10,0,false)
elseif h.PrimaryAttribute == 2 then
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,u,-10,0,false)
elseif h.PrimaryAttribute == 3 then
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,-10,0,false)
endif
else
if h.PrimaryAttribute == 1 then
call BonusStruct.Add(BONUS_TYPE_AGILITY,u,10,0,false)
elseif h.PrimaryAttribute == 2 then
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,u,10,0,false)
elseif h.PrimaryAttribute == 3 then
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,10,0,false)
endif
endif
return
endif
if name == "+4 Armor" then
if b then
call BonusStruct.Add(BONUS_TYPE_ARMOR,u,-4,0,false)
else
call BonusStruct.Add(BONUS_TYPE_ARMOR,u,4,0,false)
endif
return
endif
if name == "+15 Damage" then
if b then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,u,-15,0,false)
else
call BonusStruct.Add(BONUS_TYPE_DAMAGE,u,15,0,false)
endif
return
endif
if name == "+15 Attack Speed" then
if b then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,u,-15,0,false)
else
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,u,15,0,false)
endif
return
endif
if name == "+30(4.6%) Block" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,u,-30,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,u,30,0)
endif
return
endif
if name == "+30(4.6%) Evasion" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,u,-30,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,u,30,0)
endif
return
endif
if name == "+30(4.6%) Resistance" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,-30,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,30,0)
endif
return
endif
if name == "+4 Life Regen" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,u,-4,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,u,4,0)
endif
return
endif
if name == "+4 Mana Regen" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,u,-4,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,u,4,0)
endif
return
endif
if name == "30(+4.6%) Attack Strength" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,u,-30,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,u,30,0)
endif
return
endif
if name == "+30(4.6%) Spell Strength" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,u,-30,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,u,30,0)
endif
return
endif
if name == "+5% Cooldown Reduction" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_CD_REDUCTION,u,0.05,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_CD_REDUCTION,u,-0.05,0)
endif
return
endif
if name == "+7% Lifesteal" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,u,-0.07,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,u,0.07,0)
endif
return
endif
if name == "+7% Spell Lifesteal" then
if b then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,u,-0.07,0)
else
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,u,0.07,0)
endif
return
endif
if name == "+150 Hit Points" then
if b then
call BonusStruct.Add(BONUS_TYPE_HP,u,-150,0,false)
else
call BonusStruct.Add(BONUS_TYPE_HP,u,150,0,false)
endif
return
endif
if name == "+150 Mana Points" then
if b then
call BonusStruct.Add(BONUS_TYPE_MP,u,-150,0,false)
else
call BonusStruct.Add(BONUS_TYPE_MP,u,150,0,false)
endif
return
endif
if name == "+5% Status Reduction" then
if b then
call AddUnitNegativeStatusReduction(u,-0.05,false)
else
call AddUnitNegativeStatusReduction(u,0.05,false)
endif
return
endif
if name == "+20 Movement Speed" then
if b then
set ms = GetUnitData(u,"EMS"+I2S(it))
call ms.destroy()
else
set ms = Movespeed.create(u,0,20)
call SetUnitData(u,"EMS"+I2S(it),ms)
endif
return
endif
if name == "+4 All Stats" then
if b then
call BonusStruct.Add(BONUS_TYPE_AGILITY,u,-4,0,false)
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,u,-4,0,false)
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,-4,0,false)
else
call BonusStruct.Add(BONUS_TYPE_AGILITY,u,4,0,false)
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,u,4,0,false)
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,4,0,false)
endif
return
endif
endfunction
private function EnchantBonuses takes nothing returns nothing
local unit u = ENCHANT_HERO
local boolean b = ENCHANT_REMOVE
local Enchant e = ENCHANT_ID
local Item it = ENCHANT_ITEM
local integer lvl
if e.enchantAbility != 0 then
set lvl = GetUnitData(u,"E"+e.name)
if b then
set lvl = lvl - 1
else
set lvl = lvl + 1
endif
if GetUnitAbilityLevel(u,e.enchantAbility) == 0 then
call UnitAddAbility(u,e.enchantAbility)
call UnitMakeAbilityPermanent(u,true,e.enchantAbility)
if e.enchantType == ENCHANT_TYPE_ARMOR then
if e.name == "Cold Steel" then
call EnchantEffect.Add(EFFECT_FROST,u,1.5)
endif
if e.name == "Immolation" then
call EnchantEffect.Add(EFFECT_IMMOLATION,u,1.0)
call UnitAddBuff(u,u,9999,Immolation.buff,R2I(EnchantEffect.Get(EFFECT_IMMOLATION,u)),0)
endif
if e.name == "Magic Thorns" then
call EnchantEffect.Add(EFFECT_MAGIC_THORNS,u,0.25)
endif
if e.name == "Iron Thorns" then
call EnchantEffect.Add(EFFECT_IRON_THORNS,u,0.25)
endif
if e.name == "Fire Guard" then
call EnchantEffect.Add(EFFECT_FIRE_GUARD,u,10.0)
endif
if e.name == "Perseverance" then
call EnchantEffect.Add(EFFECT_PERSEVERANCE,u,25.0)
endif
if e.name == "Mana Shield" then
call EnchantEffect.Add(EFFECT_MANA_SHIELD,u,25.0)
endif
if e.name == "Resilience Aura" then
call EnchantEffect.Add(EFFECT_RESILIENCE,u,1)
call SetUnitAbilityLevel(u,e.enchantAbility,R2I(EnchantEffect.Get(EFFECT_RESILIENCE,u)))
endif
if e.name == "Arctic Aura" then
call EnchantEffect.Add(EFFECT_ARCTIC,u,1)
call SetUnitAbilityLevel(u,e.enchantAbility,R2I(EnchantEffect.Get(EFFECT_ARCTIC,u)))
endif
if e.name == "Diamond Guard" then
call EnchantEffect.Add(EFFECT_DIAMOND,u,7.0)
endif
if e.name == "Wind Crest" then
call EnchantEffect.Add(EFFECT_CREST,u,15.0)
endif
if e.name == "Magic Break" then
call EnchantEffect.Add(EFFECT_MAGIC_BREAK,u,1)
call MagicBreak.Create(u,e.enchantAbility,'B05Z',900,R2I(EnchantEffect.Get(EFFECT_MAGIC_BREAK,u)))
endif
elseif e.enchantType == ENCHANT_TYPE_WEAPON then
if e.name == "Corruption" then
call EnchantEffect.Add(EFFECT_CORRUPTION,u,7.0)
endif
if e.name == "Frost Attack" then
call EnchantEffect.Add(EFFECT_FROST,u,1.5)
endif
if e.name == "Feedback" then
call EnchantEffect.Add(EFFECT_FEEDBACK,u,25.0)
endif
if e.name == "Cleave Attack" then
call EnchantEffect.Add(EFFECT_CLEAVE,u,0.30)
endif
if e.name == "Bash" then
call EnchantEffect.Add(EFFECT_BASH,u,15.0)
endif
if e.name == "Brute Attack" then
call EnchantEffect.Add(EFFECT_BRUTE,u,20.0)
endif
if e.name == "Bleed" then
call EnchantEffect.Add(EFFECT_BLEED,u,0.02)
endif
if e.name == "Arcane Surge" then
call EnchantEffect.Add(EFFECT_ARCANE,u,30.0)
endif
if e.name == "Defiler Aura" then
call EnchantEffect.Add(EFFECT_DEFILER,u,1)
call SetUnitAbilityLevel(u,e.enchantAbility,R2I(EnchantEffect.Get(EFFECT_DEFILER,u)))
endif
if e.name == "Sorcerer Focus" then
call EnchantEffect.Add(EFFECT_FOCUS,u,15.0)
call Ability.HeroAbilitiesAddManaCostPercent(u,-15)
endif
if e.name == "Meteoric Attacks" then
call EnchantEffect.Add(EFFECT_METEOR,u,25.0)
endif
if e.name == "Arcane Hunter" then
call EnchantEffect.Add(EFFECT_HUNTER,u,20.0)
endif
endif
else
if lvl == 0 then
call UnitRemoveAbility(u,e.enchantAbility)
if e.enchantType == ENCHANT_TYPE_ARMOR then
if e.name == "Cold Steel" then
call EnchantEffect.Remove(EFFECT_FROST,u,1.5)
endif
if e.name == "Immolation" then
call EnchantEffect.Remove(EFFECT_IMMOLATION,u,1.0)
call UnitRemoveBuff(u,Immolation.buff)
endif
if e.name == "Magic Thorns" then
call EnchantEffect.Remove(EFFECT_MAGIC_THORNS,u,0.25)
endif
if e.name == "Iron Thorns" then
call EnchantEffect.Remove(EFFECT_IRON_THORNS,u,0.25)
endif
if e.name == "Fire Guard" then
call EnchantEffect.Remove(EFFECT_FIRE_GUARD,u,12.0)
endif
if e.name == "Perseverance" then
call EnchantEffect.Remove(EFFECT_PERSEVERANCE,u,25.0)
endif
if e.name == "Mana Shield" then
call EnchantEffect.Remove(EFFECT_MANA_SHIELD,u,25.0)
endif
if e.name == "Resilience Aura" then
call EnchantEffect.Remove(EFFECT_RESILIENCE,u,1)
call SetUnitAbilityLevel(u,e.enchantAbility,R2I(EnchantEffect.Get(EFFECT_RESILIENCE,u)))
endif
if e.name == "Arctic Aura" then
call EnchantEffect.Remove(EFFECT_ARCTIC,u,1)
call SetUnitAbilityLevel(u,e.enchantAbility,R2I(EnchantEffect.Get(EFFECT_ARCTIC,u)))
endif
if e.name == "Diamond Guard" then
call EnchantEffect.Remove(EFFECT_DIAMOND,u,7.0)
endif
if e.name == "Wind Crest" then
call EnchantEffect.Remove(EFFECT_CREST,u,15.0)
endif
if e.name == "Magic Break" then
call EnchantEffect.Remove(EFFECT_MAGIC_BREAK,u,1)
call MagicBreak.Destroy(u,e.enchantAbility)
call SetUnitAbilityLevel(u,e.enchantAbility,R2I(EnchantEffect.Get(EFFECT_MAGIC_BREAK,u)))
endif
elseif e.enchantType == ENCHANT_TYPE_WEAPON then
if e.name == "Corruption" then
call EnchantEffect.Remove(EFFECT_CORRUPTION,u,7.0)
endif
if e.name == "Frost Attack" then
call EnchantEffect.Remove(EFFECT_FROST,u,1.5)
endif
if e.name == "Feedback" then
call EnchantEffect.Remove(EFFECT_FEEDBACK,u,25.0)
endif
if e.name == "Cleave Attack" then
call EnchantEffect.Remove(EFFECT_CLEAVE,u,0.30)
endif
if e.name == "Bash" then
call EnchantEffect.Remove(EFFECT_BASH,u,15.0)
endif
if e.name == "Brute Attack" then
call EnchantEffect.Remove(EFFECT_BRUTE,u,20.0)
endif
if e.name == "Bleed" then
call EnchantEffect.Remove(EFFECT_BLEED,u,0.02)
endif
if e.name == "Arcane Surge" then
call EnchantEffect.Remove(EFFECT_ARCANE,u,30.0)
endif
if e.name == "Defiler Aura" then
call EnchantEffect.Remove(EFFECT_DEFILER,u,1)
call SetUnitAbilityLevel(u,e.enchantAbility,R2I(EnchantEffect.Get(EFFECT_DEFILER,u)))
endif
if e.name == "Sorcerer Focus" then
call EnchantEffect.Remove(EFFECT_FOCUS,u,15.0)
call Ability.HeroAbilitiesAddManaCostPercent(u,15)
endif
if e.name == "Meteoric Attacks" then
call EnchantEffect.Remove(EFFECT_METEOR,u,25.0)
endif
if e.name == "Arcane Hunter" then
call EnchantEffect.Remove(EFFECT_HUNTER,u,20.0)
endif
endif
endif
endif
call SetUnitData(u,"E"+e.name,lvl)
else
call SelectEnchantBonusesByName(u,b,e.name,it)
endif
set u = null
endfunction
private function SellEnchantment takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local Enchant e = GetUnitData(u,"CURRENT_ENCHANT")
if e != 0 then
if e.enchantType == ENCHANT_TYPE_ANY then
call AddPlayerGold(p,ENCHANT_COST_NORMAL)
else
call AddPlayerGold(p,ENCHANT_COST_EFFECT)
endif
call SetUnitData(u,"CURRENT_ENCHANT",0)
call ResetEnchantAbility(p)
call Message.ShowToPlayer(p,"Enchantment "+e.name+" sold",MESSAGE_STYLE_KILL_HERO)
endif
set u = null
set p = null
endfunction
private function EnchantSetup takes nothing returns nothing
call Enchant.create(ENCHANT_TYPE_WEAPON,'I034',"Bash",'A03P')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I035',"Corruption",'A06T')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I036',"Frost Attack",'A06U')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I037',"Feedback",'A06V')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I038',"Brute Attack",'A06W')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I039',"Cleave Attack",'A06Y')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I03A',"Bleed",'A06X')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I04Y',"Arcane Surge",'A06Z')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I00J',"Defiler Aura",'A0BT')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I00L',"Sorcerer Focus",'A03Q')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I00M',"Meteoric Attacks",'A03V')
call Enchant.create(ENCHANT_TYPE_WEAPON,'I00O',"Arcane Hunter",'A03W')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I02T',"Cold Steel",'A073')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I02U',"Immolation",'A03Y')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I02V',"Magic Thorns",'A076')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I003',"Iron Thorns",'A09H')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I02X',"Resilience Aura",'A09I')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I02Y',"Fire Guard",'A077')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I02Z',"Perseverance",'A074')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I030',"Mana Shield",'A075')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I00I',"Arctic Aura",'A0BS')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I00N',"Diamond Guard",'A040')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I00P',"Wind Crest",'A044')
call Enchant.create(ENCHANT_TYPE_ARMOR,'I00Q',"Magic Break",'A045')
call Enchant.create(ENCHANT_TYPE_ANY,'I031',"+10 Main Attribute",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I032',"+4 Armor",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I03D',"+16 Damage",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I03E',"+16 Attack Speed",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I03F',"+30(4.6%) Block",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I04T',"+30(4.6%) Evasion",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I04U',"+30(4.6%) Resistance",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I04V',"+4 Life Regen",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I033',"+4 Mana Regen",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I04P',"+30(4.6%) Attack Strength",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I04Q',"+30(4.6%) Spell Strength",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I04S',"+5% Cooldown Reduction",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I00D',"+7% Lifesteal",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I00E',"+7% Spell Lifesteal",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I00F',"+150 Hit Points",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I00G',"+150 Mana Points",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I00H',"+5% Status Reduction",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I00K',"+20 Movement Speed",0)
call Enchant.create(ENCHANT_TYPE_ANY,'I00W',"+4 All Stats",0)
endfunction
public function Setup takes nothing returns nothing
set ENCHANT_EVENT = Event.create()
call ENCHANT_EVENT.register(Filter(function EnchantBonuses))
call EnchantSetup()
call RegisterSpellEffectEvent(ENCHANT_ITEM_ID,function SellEnchantment)
endfunction
endlibrary
scope EnchantBuffs initializer init
struct Immolation extends array
unit dummy
effect sfx
real dmg
public method disable takes nothing returns nothing
call BlzUnitDisableAbility(dummy,'AIcf',true,true)
call BlzSetSpecialEffectScale(sfx,0.0)
endmethod
public method enable takes nothing returns nothing
call BlzSetSpecialEffectScale(sfx,1.0)
call BlzUnitDisableAbility(dummy,'AIcf',false,true)
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitRemoveAbility(dummy,'AIcf')
call SetUnitUserData(dummy,0)
call Dummy.Recycle(dummy)
call DestroyEffect(sfx)
set sfx = null
set dummy = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call SetUnitX(dummy,GetUnitX(b.target))
call SetUnitY(dummy,GetUnitY(b.target))
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set sfx = AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Immolation\\ImmolationTarget.mdl",b.target,"origin")
set dummy = CreateUnit(GetOwningPlayer(b.target),'u001',GetUnitX(b.target),GetUnitY(b.target),0)
call UnitAddAbility(dummy,'AIcf')
call UnitMakeAbilityPermanent(dummy,true,'AIcf')
call SetUnitUserData(dummy,GetUnitUserData(b.target))
if b.level == 1 then
set dmg = 40
elseif b.level == 2 then
set dmg = 60
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Immolation"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.10
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Distortion extends array
private static method onRemove takes Buff b returns nothing
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,80,0)
call AddUnitNegativeStatusReduction(b.target,0.20,false)
endmethod
private static method onApply takes Buff b returns nothing
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-80,0)
call AddUnitNegativeStatusReduction(b.target,-0.20,false)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A03G'
set BUFF_DATA.BuffID = 'B05A'
set BUFF_DATA.Name = "Distortion"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.PierceImmune = false
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Corruption extends array
integer armor
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set armor = R2I(EnchantEffect.Get(EFFECT_CORRUPTION,b.owner))
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-armor,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A070'
set BUFF_DATA.BuffID = 'B02H'
set BUFF_DATA.Name = "Corruption"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Maim extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,35,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-0.35,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-35,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A071'
set BUFF_DATA.BuffID = 'B02I'
set BUFF_DATA.Name = "Maim"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Bleed extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A072'
set BUFF_DATA.BuffID = 'B02J'
set BUFF_DATA.Name = "Bleed"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 10
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct MagicBreak extends array
private static method OnEffect takes unit u, Aura a returns nothing
local integer r
if a.level == 1 then
set r = 50
elseif a.level == 2 then
set r = 70
endif
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,-r,0)
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,u,-r,0)
endmethod
private static method OnEndEffect takes unit u, Aura a returns nothing
local integer r
if a.level == 1 then
set r = 50
elseif a.level == 2 then
set r = 70
endif
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,u,r,0)
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,u,r,0)
endmethod
implement AuraCore
endstruct
private function init takes nothing returns nothing
call Immolation.Initialize()
call Corruption.Initialize()
call Maim.Initialize()
call Bleed.Initialize()
call Distortion.Initialize()
call MagicBreak.Initialize()
endfunction
endscope
library EnchantEffects
globals
constant integer EFFECT_CORRUPTION = 1
constant integer EFFECT_FROST = 2
constant integer EFFECT_FEEDBACK = 3
constant integer EFFECT_CLEAVE = 4
constant integer EFFECT_BASH = 5
constant integer EFFECT_BRUTE = 6
constant integer EFFECT_BLEED = 7
constant integer EFFECT_ARCANE = 8
constant integer EFFECT_DEFILER = 9
constant integer EFFECT_FOCUS = 10
constant integer EFFECT_METEOR = 11
constant integer EFFECT_HUNTER = 12
constant integer EFFECT_IMMOLATION = 13
constant integer EFFECT_MAGIC_THORNS = 14
constant integer EFFECT_IRON_THORNS = 15
constant integer EFFECT_FIRE_GUARD = 16
constant integer EFFECT_PERSEVERANCE = 17
constant integer EFFECT_MANA_SHIELD = 18
constant integer EFFECT_RESILIENCE = 19
constant integer EFFECT_ARCTIC = 20
constant integer EFFECT_DIAMOND = 21
constant integer EFFECT_CREST = 22
constant integer EFFECT_MAGIC_BREAK = 23
private hashtable T = InitHashtable()
endglobals
struct EnchantEffect extends array
public static method Add takes integer et, unit u, real x returns nothing
local integer id = GetUnitUserData(u)
local real a
if id != 0 then
set a = LoadReal(T,et,id)
set a = a + x
call SaveReal(T,et,id,a)
endif
endmethod
public static method Remove takes integer et, unit u, real x returns nothing
local integer id = GetUnitUserData(u)
local real a
if id != 0 then
set a = LoadReal(T,et,id)
set a = a - x
call SaveReal(T,et,id,a)
endif
endmethod
public static method Get takes integer et, unit u returns real
local integer id = GetUnitUserData(u)
if id != 0 then
return LoadReal(T,et,id)
endif
return 0.0
endmethod
endstruct
endlibrary
library Runes
globals
constant real DEFAULT_RUNES_DELAY = 120//90.00
private integer array RUNE_ID
Rune RUNE_MAJOR_HORDE = 0
Rune RUNE_MINOR_HORDE = 0
Rune RUNE_RIVER_HORDE = 0
Rune RUNE_JUMP_HORDE = 0
Rune RUNE_MAJOR_ALLIANCE = 0
Rune RUNE_MINOR_ALLIANCE = 0
Rune RUNE_RIVER_ALLIANCE = 0
Rune RUNE_JUMP_ALLIANCE = 0
unit HORDE_MAJOR_RUNE_SPOT
unit HORDE_MINOR_RUNE_SPOT
unit HORDE_RIVER_RUNE_SPOT
unit HORDE_JUMP_RUNE_SPOT
unit ALLIANCE_MAJOR_RUNE_SPOT
unit ALLIANCE_MINOR_RUNE_SPOT
unit ALLIANCE_RIVER_RUNE_SPOT
unit ALLIANCE_JUMP_RUNE_SPOT
endglobals
private function SetRuneDescriptionById takes item r returns nothing
local integer id = GetItemTypeId(r)
local integer v
if id == RUNE_ID[0] then
call BlzSetItemDescription(r,"Heals "+I2S(R2I(150 + 4 * GameLoop.Minutes))+" Hp and recovers "+I2S(R2I(100 + 4 * GameLoop.Minutes))+" Mp.")
endif
if id == RUNE_ID[1] then
call BlzSetItemDescription(r,"Gives "+I2S(R2I(60 + 2 * GameLoop.Minutes))+" bonus gold and "+I2S(R2I(100 + 10 * GameLoop.Minutes))+" bonus experience.")
endif
if id == RUNE_ID[2] then
call BlzSetItemDescription(r,"Increases all damage/heal done by "+I2S(R2I(10 + 0.5 * GameLoop.Minutes))+"% but increases all damage taken by the same amount, lasts 120 seconds.")
endif
if id == RUNE_ID[3] then
call BlzSetItemDescription(r,"Increases the attack damage by "+I2S(R2I(20 + 1 * GameLoop.Minutes))+" and attack speed by "+I2S(R2I(10 + 1 * GameLoop.Minutes))+"%, lasts 120 seconds.")
endif
if id == RUNE_ID[4] then
call BlzSetItemDescription(r,"Adds "+I2S(R2I(5 + 1 * GameLoop.Minutes/2))+"% cooldown reduction and "+I2S(R2I(5 + 1 * GameLoop.Minutes/2))+" mana cost reduction, lasts 120 seconds.")
endif
if id == RUNE_ID[5] then
call BlzSetItemDescription(r,"Increases the armor by "+I2S(8 + 1 * GameLoop.Minutes)+" and the resistance, block and evasion"+R2S(20 + 2 * GameLoop.Minutes)+", lasts 120 seconds.")
endif
if id == RUNE_ID[7] then
call BlzSetItemDescription(r,"Creates 1 Illusion that deals "+I2S(R2I(25 + 0.5 * GameLoop.Minutes))+"% damage and takes 100% of the damage, lasts 40 seconds.")
endif
if id == RUNE_ID[9] then
set v = R2I(20 + 4 * GameLoop.Minutes)
call BlzSetItemDescription(r,"Increases the sight range by "+I2S(50 + 10 * GameLoop.Minutes / 5)+" and gives true sight, lasts 40 seconds.")
endif
endfunction
public function UpdateRunesDescription takes nothing returns nothing
if RUNE_MAJOR_HORDE != 0 then
call SetRuneDescriptionById(RUNE_MAJOR_HORDE.rune)
endif
if RUNE_MINOR_HORDE != 0 then
call SetRuneDescriptionById(RUNE_MINOR_HORDE.rune)
endif
if RUNE_RIVER_HORDE != 0 then
call SetRuneDescriptionById(RUNE_RIVER_HORDE.rune)
endif
if RUNE_MAJOR_ALLIANCE != 0 then
call SetRuneDescriptionById(RUNE_MAJOR_ALLIANCE.rune)
endif
if RUNE_MINOR_ALLIANCE != 0 then
call SetRuneDescriptionById(RUNE_MINOR_ALLIANCE.rune)
endif
if RUNE_RIVER_ALLIANCE != 0 then
call SetRuneDescriptionById(RUNE_RIVER_ALLIANCE.rune)
endif
endfunction
struct Rune extends array
implement Alloc
real xc
real yc
item rune
boolean taked
integer data
unit spot
public static method create takes integer id, real x, real y, unit s returns thistype
local thistype this = thistype.allocate()
set rune = CreateItem(id,x,y)
call SetItemUserData(rune,this)
set taked = false
set spot = s
set xc = x
set yc = y
call SetUnitUserData(spot,this)
call SetRuneDescriptionById(rune)
return this
endmethod
public method destroy takes nothing returns nothing
call SetItemUserData(rune,0)
call RemoveItem(rune)
call SetUnitUserData(spot,0)
set spot = null
set rune = null
set data = 0
call deallocate()
endmethod
endstruct
private function CreateMajorRunes takes nothing returns nothing
local integer r
local real xh1 = GetUnitX(HORDE_MAJOR_RUNE_SPOT)
local real yh1 = GetUnitY(HORDE_MAJOR_RUNE_SPOT)
local real xa1 = GetUnitX(ALLIANCE_MAJOR_RUNE_SPOT)
local real ya1 = GetUnitY(ALLIANCE_MAJOR_RUNE_SPOT)
call RUNE_MAJOR_HORDE.destroy()
call RUNE_MAJOR_ALLIANCE.destroy()
set r = GetRandomInt(2,5)
set RUNE_MAJOR_HORDE = Rune.create(RUNE_ID[r],xh1,yh1,HORDE_MAJOR_RUNE_SPOT)
set r = GetRandomInt(2,5)
set RUNE_MAJOR_ALLIANCE = Rune.create(RUNE_ID[r],xa1,ya1,ALLIANCE_MAJOR_RUNE_SPOT)
endfunction
private function CreateMinorRunes takes nothing returns nothing
local integer r
local real xh1 = GetUnitX(HORDE_MINOR_RUNE_SPOT)
local real yh1 = GetUnitY(HORDE_MINOR_RUNE_SPOT)
local real xa1 = GetUnitX(ALLIANCE_MINOR_RUNE_SPOT)
local real ya1 = GetUnitY(ALLIANCE_MINOR_RUNE_SPOT)
call RUNE_MINOR_HORDE.destroy()
call RUNE_MINOR_ALLIANCE.destroy()
set r = GetRandomInt(6,9)
set RUNE_MINOR_HORDE = Rune.create(RUNE_ID[r],xh1,yh1,HORDE_MINOR_RUNE_SPOT)
set r = GetRandomInt(6,9)
set RUNE_MINOR_ALLIANCE = Rune.create(RUNE_ID[r],xa1,ya1,ALLIANCE_MINOR_RUNE_SPOT)
endfunction
private function CreateRiverRunes takes nothing returns nothing
local integer r
local real xh2 = GetUnitX(HORDE_RIVER_RUNE_SPOT)
local real yh2 = GetUnitY(HORDE_RIVER_RUNE_SPOT)
local real xa2 = GetUnitX(ALLIANCE_RIVER_RUNE_SPOT)
local real ya2 = GetUnitY(ALLIANCE_RIVER_RUNE_SPOT)
if Game.Mode == GAME_MODE_NORMAL or Game.Mode == GAME_MODE_LMS then
call RUNE_RIVER_HORDE.destroy()
call RUNE_RIVER_ALLIANCE.destroy()
set RUNE_RIVER_HORDE = Rune.create(RUNE_ID[0],xh2,yh2,HORDE_RIVER_RUNE_SPOT)
set RUNE_RIVER_ALLIANCE = Rune.create(RUNE_ID[0],xa2,ya2,ALLIANCE_RIVER_RUNE_SPOT)
else
call RUNE_RIVER_HORDE.destroy()
call RUNE_RIVER_ALLIANCE.destroy()
if GetRandomInt(1,2) == 1 then
set r = GetRandomInt(2,9)
set RUNE_RIVER_HORDE = Rune.create(RUNE_ID[r],xh2,yh2,HORDE_RIVER_RUNE_SPOT)
set RUNE_RIVER_ALLIANCE = Rune.create(RUNE_ID[0],xa2,ya2,ALLIANCE_RIVER_RUNE_SPOT)
else
set r = GetRandomInt(2,9)
set RUNE_RIVER_HORDE = Rune.create(RUNE_ID[0],xh2,yh2,HORDE_RIVER_RUNE_SPOT)
set RUNE_RIVER_ALLIANCE = Rune.create(RUNE_ID[r],xa2,ya2,ALLIANCE_RIVER_RUNE_SPOT)
endif
endif
endfunction
private function CreateJumpRunes takes nothing returns nothing
local integer r
local real xj1 = GetUnitX(HORDE_JUMP_RUNE_SPOT)
local real yj1 = GetUnitY(HORDE_JUMP_RUNE_SPOT)
local real xj3 = GetUnitX(ALLIANCE_JUMP_RUNE_SPOT)
local real yj3 = GetUnitY(ALLIANCE_JUMP_RUNE_SPOT)
call RUNE_JUMP_HORDE.destroy()
call RUNE_JUMP_ALLIANCE.destroy()
set RUNE_JUMP_HORDE = Rune.create(RUNE_ID[10],xj1,yj1,HORDE_JUMP_RUNE_SPOT)
set RUNE_JUMP_HORDE.data = 1
set RUNE_JUMP_ALLIANCE = Rune.create(RUNE_ID[10],xj3,yj3,ALLIANCE_JUMP_RUNE_SPOT)
set RUNE_JUMP_ALLIANCE.data = 3
endfunction
public function CreateRandomRune takes nothing returns nothing
if Game.Mode == GAME_MODE_NORMAL then
call CreateMajorRunes()
call CreateMinorRunes()
call CreateRiverRunes()
call CreateJumpRunes()
else
call CreateRiverRunes()
endif
endfunction
private function Periodic takes nothing returns nothing
call CreateRandomRune()
endfunction
public function Setup takes nothing returns nothing
local trigger t = CreateTrigger()
set RUNE_ID[0] = 'rdis' //HEAL AND MANA
set RUNE_ID[1] = 'rma2' //GOLD AND EXP
set RUNE_ID[2] = 'rre1' //FIERCE
set RUNE_ID[3] = 'rhe2' //POWER
set RUNE_ID[4] = 'rspl' //SORCERY
set RUNE_ID[5] = 'rres' //VANGUARD
set RUNE_ID[6] = 'rhe1' //HASTE
set RUNE_ID[7] = 'rreb' //ILLUSION
set RUNE_ID[8] = 'rsps' //INVISIBILITY
set RUNE_ID[9] = 'rre2' //TRUE SIGHT
set RUNE_ID[10] = 'rman' //JUMP
set HORDE_MAJOR_RUNE_SPOT = gg_unit_ncop_0104
set HORDE_MINOR_RUNE_SPOT = gg_unit_ncop_0116
set HORDE_RIVER_RUNE_SPOT = gg_unit_ncop_0019
set HORDE_JUMP_RUNE_SPOT = gg_unit_ncop_0059
set ALLIANCE_MAJOR_RUNE_SPOT = gg_unit_ncop_0001
set ALLIANCE_MINOR_RUNE_SPOT = gg_unit_ncop_0043
set ALLIANCE_RIVER_RUNE_SPOT = gg_unit_ncop_0028
set ALLIANCE_JUMP_RUNE_SPOT = gg_unit_ncop_0060
if Game.Mode == GAME_MODE_NORMAL then
call TriggerRegisterTimerEvent(t,DEFAULT_RUNES_DELAY,true)
elseif Game.Mode == GAME_MODE_LMS then
call TriggerRegisterTimerEvent(t,20.00,true)
elseif Game.Mode == GAME_MODE_OD then
call TriggerRegisterTimerEvent(t,15.00,true)
endif
call TriggerAddCondition(t,function Periodic)
set t = null
endfunction
endlibrary
library RunesEffects uses MiscLibrary
function RestorationRune takes unit u returns nothing
call UnitAddHp(u,150 + 5 * GameLoop.Minutes)
call UnitAddMp(u,100 + 5 * GameLoop.Minutes)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl",u,"overhead"))
endfunction
function GoldRune takes unit u returns nothing
local integer lvl = GetHeroLevel(u)
local Team t = GetUnitTeam(u)
call AddPlayersGold(t,70 + 2 * GameLoop.Minutes,true,null)
call AddTeamExp(t,100 + 10 * GameLoop.Minutes)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Transmute\\PileofGold.mdl",u,"origin"))
endfunction
function HasteRune takes unit u returns nothing
call UnitAddBuff(u,u,40.00,HasteRuneBuff.buff,0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl",u,"origin"))
endfunction
function RageRune takes unit u returns nothing
local FiercenessRuneBuff b = UnitAddBuff(u,u,120.00,FiercenessRuneBuff.buff,0,0).buffAllocIndex
set b.damageDealt = 0.10 + 0.005 * GameLoop.Minutes
set b.damageTaken = b.damageDealt
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Monsoon\\MonsoonBoltTarget.mdl",u,"origin"))
endfunction
function JumpRune takes unit u, item i returns nothing
local Rune r = GetItemUserData(i)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real h
local real a
local real d
local real xt
local real yt
if r != 0 then
if r.data == 1 then
set xt = GetRectCenterX(gg_rct_Jump_1)
set yt = GetRectCenterY(gg_rct_Jump_1)
set h = 600
elseif r.data == 2 then
set xt = GetRectCenterX(gg_rct_Jump_2)
set yt = GetRectCenterY(gg_rct_Jump_2)
set h = 700
elseif r.data == 3 then
set xt = GetRectCenterX(gg_rct_Jump_3)
set yt = GetRectCenterY(gg_rct_Jump_3)
set h = 600
elseif r.data == 4 then
set xt = GetRectCenterX(gg_rct_Jump_4)
set yt = GetRectCenterY(gg_rct_Jump_4)
set h = 700
endif
set a = Angle(x,y,xt,yt)
set d = Distance(x,y,xt,yt)
call SetUnitFacing(u,a * bj_RADTODEG)
call KPJUnit.create(u,d,a,0.9,h,KPJDefaultConfig,KPJ_TYPE_JUMP)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl",u,"origin"))
endif
endfunction
function TrueSightRune takes unit u returns nothing
call UnitAddBuff(u,u,40.00,TrueSightRuneBuff.buff,0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ControlMagic\\ControlMagicTarget.mdl",u,"overhead"))
endfunction
function InvisibilityRune takes unit u returns nothing
call UnitAddBuff(u,u,40.00,InvisibilityRuneBuff.buff,0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ControlMagic\\ControlMagicTarget.mdl",u,"overhead"))
endfunction
function IllusionRune takes unit u returns nothing
local real a = GetRandomReal(1,360) * bj_DEGTORAD
local real d = GetRandomReal(50,100)
local real x = GetUnitX(u) + d * Cos(a)
local real y = GetUnitY(u) + d * Sin(a)
local Illusion i = Illusion.create(GetOwningPlayer(u),u,x,y)
set i.duration = 40.00
set i.damageTaken = 1.0
set i.damageDealt = 0.25 + 0.005 * GameLoop.Minutes
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl",u,"chest"))
endfunction
function DmgRune takes unit u returns nothing
call UnitAddBuff(u,u,120.00,PowerRuneBuff.buff,0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\BattleRoar\\RoarCaster.mdl",u,"origin"))
endfunction
function SorceryRune takes unit u returns nothing
call UnitAddBuff(u,u,120.00,SorceryRuneBuff.buff,0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl",u,"origin"))
endfunction
function VanguardRune takes unit u returns nothing
call UnitAddBuff(u,u,120.00,VanguardRuneBuff.buff,0,0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Defend\\DefendCaster.mdl",u,"overhead"))
endfunction
endlibrary
scope RunesBuff initializer init
globals
private constant integer HASTE_BUFF_ID = 'Bspe'
private constant integer HASTE_ITEM_ID = 'rspd'
private constant string RUNE_SFX = "war3mapImported\\AuraBuff2.mdx"
endglobals
struct InvisibilityRuneBuff extends array
private static method onRemove takes Buff b returns nothing
call Status.Remove(STATUS_INVISIBILITY,b.target)
endmethod
private static method onApply takes Buff b returns nothing
call Status.Add(STATUS_INVISIBILITY,b.target,0,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A07F'
set BUFF_DATA.BuffID = 'B05F'
set BUFF_DATA.Name = "Rune of Invisibility"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct VanguardRuneBuff extends array
integer armor
real rating
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-armor,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-rating,0)
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,b.target,-rating,0)
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,-rating,0)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set armor = 5 + GameLoop.Minutes/5
set rating = 20 + 2 * GameLoop.Minutes
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,rating,0)
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,b.target,rating,0)
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,rating,0)
set sfx = AddSpecialEffectTarget("war3mapImported\\AuraBuffVanguard.mdx",b.target,"origin")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08D'
set BUFF_DATA.BuffID = 'B05G'
set BUFF_DATA.Name = "Rune of Vanguard"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct SorceryRuneBuff extends array
real cd
integer mc
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_CD_REDUCTION,b.target,cd,0)
call Ability.HeroAbilitiesAddManaCostPercent(b.target,mc)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set cd = 0.05 + 0.01 * (GameLoop.Minutes / 2)
set mc = 5 + 1 * (GameLoop.Minutes / 2)
call BonusStruct.AddSpecial(BONUS_TYPE_CD_REDUCTION,b.target,-cd,0)
call Ability.HeroAbilitiesAddManaCostPercent(b.target,-mc)
set sfx = AddSpecialEffectTarget("war3mapImported\\AuraBuffSorcery.mdx",b.target,"origin")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08W'
set BUFF_DATA.BuffID = 'B05H'
set BUFF_DATA.Name = "Rune of Sorcery"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct PowerRuneBuff extends array
integer dmg
integer as
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Hero h = GetUnitData(b.target,"HeroIndex")
set dmg = 20 + 1 * GameLoop.Minutes
set as = 10 + 1 * GameLoop.Minutes
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
set sfx = AddSpecialEffectTarget("war3mapImported\\AuraBuffMight.mdx",b.target,"origin")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A069'
set BUFF_DATA.BuffID = 'B050'
set BUFF_DATA.Name = "Rune of Power"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct FiercenessRuneBuff extends array
real damageDealt
real damageTaken
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set sfx = AddSpecialEffectTarget("war3mapImported\\AuraBuffFierceness.mdx",b.target,"origin")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02W'
set BUFF_DATA.BuffID = 'BO1P'
set BUFF_DATA.Name = "Rune of Fierceness"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct HasteRuneBuff extends array
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitRemoveAbility(b.target,HASTE_BUFF_ID)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local item i = CreateItem(HASTE_ITEM_ID,0,0)
call UnitAddItem(b.target,i)
set sfx = AddSpecialEffectTarget("war3mapImported\\AuraBuffHaste.mdx",b.target,"origin")
set i = null
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Rune of Haste"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct TrueSightRuneBuff extends array
integer sr
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_SIGHT_RANGE,b.target,-sr,0,false)
call Status.Remove(STATUS_TRUE_SIGHT,b.target)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set sr = 50 + 10 * (5 * GameLoop.Minutes)
call BonusStruct.Add(BONUS_TYPE_SIGHT_RANGE,b.target,sr,0,false)
call Status.Add(STATUS_TRUE_SIGHT,b.target,0,0)
set sfx = AddSpecialEffectTarget("Abilities\\Spells\\Human\\MagicSentry\\MagicSentryCaster.mdl",b.target,"overhead")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CZ'
set BUFF_DATA.BuffID = 'BO5R'
set BUFF_DATA.Name = "Rune of True Sight"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onPreDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local FiercenessRuneBuff b2
if UnitHasBuff(data.source,FiercenessRuneBuff.buff) then
set b2 = GetUnitBuff(data.source,FiercenessRuneBuff.buff).buffAllocIndex
set data.mult = data.mult + b2.damageDealt
endif
if UnitHasBuff(data.target,FiercenessRuneBuff.buff) then
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b2 = GetUnitBuff(data.target,FiercenessRuneBuff.buff).buffAllocIndex
set data.mult = data.mult + b2.damageTaken
endif
endif
endfunction
private function init takes nothing returns nothing
call TrueSightRuneBuff.Initialize()
call HasteRuneBuff.Initialize()
call InvisibilityRuneBuff.Initialize()
call PowerRuneBuff.Initialize()
call FiercenessRuneBuff.Initialize()
call SorceryRuneBuff.Initialize()
call VanguardRuneBuff.Initialize()
call DamageEvent.RegisterPreCalculation(Filter(function onPreDmg))
endfunction
endscope
library Item initializer init uses PlayerLib
globals
private Table ItemsData
private trigger OrderBaul
unit array Baul
constant integer ITEM_TYPE_CONSUMABLE = 0 //ITEM_TYPE_PURCHASABLE
constant integer ITEM_TYPE_MISC = 1 //ITEM_TYPE_MISCELLANEOUS
constant integer ITEM_TYPE_WEAPON = 2 //ITEM_TYPE_PERMANENT
constant integer ITEM_TYPE_ARMOR = 3 //ITEM_TYPE_CAMPAIGN
constant integer ITEM_TYPE_TRINKET = 4 //ITEM_TYPE_ARTIFACT
constant integer ITEM_TYPE_MAGIC = 5 //ITEM_TYPE_CHARGED
constant integer BONUS_TYPE_STATUS_RED = -2
constant integer BONUS_TYPE_NOTHING = -3
private constant string array COLOR_LEVEL[4]
private constant string COLOR_ENCHANT = "|cffff8080"
private constant string COLOR_WEAPON = "|cffba55d3"
private constant string COLOR_ARMOR = "|cff66cdaa"
private constant string COLOR_TRINKET = "|cff7759ee"
private constant string COLOR_MAGIC = "|cff00bfff"
private constant string COLOR_TITLE = "|cffffbb77"
private constant string COLOR_ABILITY = "|cff87cefa"
private constant string COLOR_BONUS = "|cff00ff00"
private constant string COLOR_COST = "|cffc0c0c0"
private constant integer BAUL_ID = 'h001'
private constant integer BAUL_ID2 = 'h00G'
endglobals
function GetItemDataByID takes integer id returns ItemData
return ItemsData.integer[id]
endfunction
function AddItemData takes ItemData id returns nothing
set ItemsData.integer[id.itemID] = id
endfunction
function AddItemDummyData takes ItemData id returns nothing
set ItemsData.integer[id.dummyID] = id
endfunction
function AddUnitItem takes unit u, Item it returns nothing
local LinkedList inv = GetUnitData(u,"UnitItems")
if inv != 0 then
set it.inventoryIndex = inv.add(it)
if IsUnitSelected(u,GetOwningPlayer(u)) then
call UIItems_UpdateInventory.evaluate(u,GetOwningPlayer(u))
endif
//call BJDebugMsg("adding:"+GetItemName(it.itemS) + "-"+I2S(inv.size))
endif
endfunction
function GetUnitItemOfTypeAbility takes unit u, integer aid returns Item
local LinkedList inv = GetUnitData(u,"UnitItems")
local Link node
local Item it
if inv != 0 then
set node = inv.head
loop
exitwhen node == 0
set it = node.data
if it.abilityID == aid then
return it
endif
set node = node.next
endloop
endif
return 0
endfunction
function GetUnitItemOfType takes unit u, integer id returns Item
local LinkedList inv = GetUnitData(u,"UnitItems")
local Link node
local Item it
if inv != 0 then
set node = inv.head
loop
exitwhen node == 0
set it = node.data
if it.itemID == id then
return it
endif
set node = node.next
endloop
endif
return 0
endfunction
function UnitHasItemOfType takes unit u, integer id returns boolean
local LinkedList inv = GetUnitData(u,"UnitItems")
local Link node
local Item it
if inv != 0 then
set node = inv.head
loop
exitwhen node == 0
set it = node.data
if it.itemID == id then
return true
endif
set node = node.next
endloop
endif
return false
endfunction
function GetItemSlotIndex takes unit u, item it returns integer
local integer i = 0
local integer ext = UnitInventorySize(u)
loop
exitwhen i == ext
if UnitItemInSlot(u, i) == it then
return i
endif
set i = i + 1
endloop
return -1
endfunction
function BuildText takes Item it, integer t returns string
local string s = ""
local real r1
local real r2
local Link h = it.bonuses.head
local ItemBonus b
if it.enchant != 0 then
set s = s + COLOR_MAGIC + it.typeName + "|n" + COLOR_TITLE+"Gives:|r|n"+COLOR_BONUS
if it.enchant.enchantType != ENCHANT_TYPE_ANY then
set s = s + "+"
endif
set s = s + it.enchant.name+"|r|n"
else
set s = s + COLOR_MAGIC + it.typeName + "|n" + COLOR_TITLE+"Gives:|r|n"
endif
loop
exitwhen h == 0
set b = h.data
set r1 = b.amount + b.increase * (t - 1)
if b.typeBonus >= 10 and b.typeBonus <= 14 then
set r2 = UnitStat.GetModifiedStat(b.typeBonus,r1)
if b.typeBonus == 12 then
set r2 = r2 * 100
endif
set s = s + "+"+I2S(R2I(r1))+"("+R2SW(r2,0,1)+"%)"+" "+b.name+"|n"
elseif b.typeBonus == 20 then
set r2 = r1
set s = s + "+"+I2S(R2I(r2))+"% "+b.name+"|n"
else
if b.typeBonus == BONUS_TYPE_STATUS_RED then
set s = s + "+"+I2S(R2I(r1))+"% "+b.name+"|n"
else
set s = s + "+"+I2S(R2I(r1))+" "+b.name+"|n"
endif
endif
set h = h.next
endloop
if it.abilityName != "" then
set s = s + COLOR_ABILITY+it.abilityName+": |r"
set s = s + it.abilityText+"|n|n"
if t == 1 then
set s = s + COLOR_TITLE+"Tier 1:|r "+it.tier1Text+"|n"
elseif t == 2 then
set s = s + COLOR_TITLE+"Tier 2:|r "+it.tier2Text+"|n"
elseif t == 3 then
set s = s + COLOR_TITLE+"Tier 3:|r "+it.tier3Text+"|n"
endif
endif
return s
endfunction
struct ItemBonus extends array
implement Alloc
integer typeBonus
string name
real amount
real increase
boolean isPercent
public static method create takes integer t, string n, real a, real i returns thistype
local thistype this = thistype.allocate()
set typeBonus = t
set name = n
set amount = a
set increase = i
return this
endmethod
endstruct
struct ItemData extends array
implement Alloc
integer itemID
integer itemType
integer abilityID
integer abilityID2
integer dummyID
integer charges
string typeName
string itemName
string abilityName
string abilityText
string tier1Text
string tier2Text
string tier3Text
integer goldCost
integer honorCost
boolean useDummy
LinkedList bonuses
public method AddBonus takes integer t, string name, real amount, real upamount returns nothing
local ItemBonus b = ItemBonus.create(t,name,amount,upamount)
call bonuses.addLast(b)
endmethod
public static method create takes integer id returns thistype
local thistype this = thistype.allocate()
set itemID = id
call AddItemData(this)
set bj_lastCreatedItem = CreateItem(id,0,0)
set itemType = GetItemLevel(bj_lastCreatedItem)
set itemName = GetItemName(bj_lastCreatedItem)
call RemoveItem(bj_lastCreatedItem)
if itemType == ITEM_TYPE_WEAPON then
set typeName = "Weapon"
elseif itemType == ITEM_TYPE_ARMOR then
set typeName = "Armor"
elseif itemType == ITEM_TYPE_TRINKET then
set typeName = "Trinket"
elseif itemType == ITEM_TYPE_MAGIC then
set typeName = "Magic Accessory"
else
set typeName = ""
set abilityName = ""
set abilityText = ""
set tier1Text = ""
set tier2Text = ""
set tier3Text = ""
endif
if itemType != ITEM_TYPE_CONSUMABLE then
set bonuses = LinkedList.create()
else
set bonuses = 0
endif
return this
endmethod
endstruct
struct Item extends array
implement Alloc
unit wielder
item itemS
player owner
boolean drooped
Enchant enchant
integer tier
boolean pawned
integer inventoryIndex
unit dummy
integer int
real realD
delegate ItemData data
public method giveBonuses takes boolean droop returns nothing
local Link h = bonuses.head
local Hero he = GetPlayerHero(owner)
local ItemBonus b
local real a
loop
exitwhen h == 0
set b = h.data
set a = b.amount + (b.increase * (tier - 1))
if droop then
set a = -a
else
if abilityID != 0 then
call SetUnitAbilityLevel(wielder,abilityID,tier)
endif
if abilityID2 != 0 then
call SetUnitAbilityLevel(wielder,abilityID2,tier)
endif
endif
if b.typeBonus <= 9 then
if b.typeBonus == 0 then
if he.PrimaryAttribute == 1 then
call BonusStruct.Add(BONUS_TYPE_AGILITY,wielder,R2I(a),0,false)
elseif he.PrimaryAttribute == 2 then
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,wielder,R2I(a),0,false)
elseif he.PrimaryAttribute == 3 then
call BonusStruct.Add(BONUS_TYPE_STRENGTH,wielder,R2I(a),0,false)
endif
elseif b.typeBonus == -1 then
call BonusStruct.Add(BONUS_TYPE_AGILITY,wielder,R2I(a),0,false)
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,wielder,R2I(a),0,false)
call BonusStruct.Add(BONUS_TYPE_STRENGTH,wielder,R2I(a),0,false)
elseif b.typeBonus == -2 then
call AddUnitNegativeStatusReduction(wielder,a/100,false)
elseif b.typeBonus != -3 then
call BonusStruct.Add(b.typeBonus,wielder,R2I(a),0,false)
endif
else
if b.typeBonus == 17 or b.typeBonus == 18 then
call BonusStruct.AddSpecial(b.typeBonus,wielder,a/100,0)
elseif b.typeBonus == 19 then
set a = a * -1
call BonusStruct.AddSpecial(b.typeBonus,wielder,a/100,0)
else
call BonusStruct.AddSpecial(b.typeBonus,wielder,a,0)
endif
endif
set h = h.next
endloop
if enchant != 0 then
if droop then
call enchant.remove(wielder,this)
else
call enchant.add(wielder,this)
endif
endif
if itemID == 'bzbf' then
if droop then
if BlzGetUnitAbilityCooldownRemaining(wielder,abilityID) == 0 then
call RemoveSpellNegation(wielder)
endif
else
if BlzGetUnitAbilityCooldownRemaining(wielder,abilityID) == 0 then
call AddSpellNegation(wielder)
endif
endif
return
elseif itemID == 'mgtk' then
if droop then
call NatureAura.Destroy(wielder,abilityID)
else
call NatureAura.Create(wielder,abilityID,'B018',900,tier)
endif
return
elseif itemID == 'wlsd' then
if droop then
call VampiricAura.Destroy(wielder,abilityID)
else
call VampiricAura.Create(wielder,abilityID,'B03R',900,tier)
endif
return
elseif itemID == 'wswd' then
if droop then
call UnitRemoveBuff(wielder,WandererSteps.buff)
else
if not IsUnitInCombat(wielder) then
call UnitAddBuff(wielder,wielder,9000,WandererSteps.buff,tier,0)
endif
endif
return
elseif itemID == 'rde1' then
if droop then
if BlzGetUnitAbilityCooldownRemaining(wielder,abilityID) == 0 then
call RemoveStatusNegation(wielder)
endif
else
if BlzGetUnitAbilityCooldownRemaining(wielder,abilityID) == 0 then
call AddStatusNegation(wielder)
endif
endif
return
elseif itemID == 'pmna' then
if droop then
call ResistanceAura.Destroy(wielder,abilityID)
else
call ResistanceAura.Create(wielder,abilityID,'B05I',900,tier)
endif
return
elseif itemID == 'arsh' then
if droop then
call BlzSetUnitAbilityCooldown(wielder,'A00A',0,45.00)
call BlzSetUnitAbilityCooldown(wielder,'A00A',1,45.00)
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(wielder,'A00A'),ABILITY_SLF_TOOLTIP_NORMAL,0,"Stone of Teleportation CD: 45")
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(wielder,'A00A'),ABILITY_SLF_TOOLTIP_NORMAL,1,"Stone of Teleportation CD: 45")
else
call BlzSetUnitAbilityCooldown(wielder,'A00A',0,35.00)
call BlzSetUnitAbilityCooldown(wielder,'A00A',1,35.00)
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(wielder,'A00A'),ABILITY_SLF_TOOLTIP_NORMAL,0,"Stone of Teleportation CD: 35")
call BlzSetAbilityStringLevelField(BlzGetUnitAbility(wielder,'A00A'),ABILITY_SLF_TOOLTIP_NORMAL,1,"Stone of Teleportation CD: 35")
endif
return
elseif itemID == 'pdiv' then
if droop then
call TrinketBuffs_PhoenixFireEnd.evaluate(this)
else
call TrinketBuffs_PhoenixFireInit.evaluate(this)
endif
return
endif
endmethod
public method levelup takes nothing returns nothing
local string s
if tier != 3 then
call giveBonuses(true)
set tier = tier + 1
call BlzSetItemName(itemS,COLOR_LEVEL[tier] + itemName + " - Tier "+I2S(tier)+"|r")
set s = BuildText(this,tier)
call BlzSetItemExtendedTooltip(itemS,s)
call giveBonuses(false)
if itemID == 'pmna' then
call ResistanceAura.UpdateAuraLevel(wielder,abilityID,tier)
endif
if itemID == 'mgtk' then
call NatureAura.UpdateAuraLevel(wielder,abilityID,tier)
endif
if itemID == 'wlsd' then
call VampiricAura.UpdateAuraLevel(wielder,abilityID,tier)
endif
if IsUnitSelected(wielder,GetOwningPlayer(wielder)) then
call UIItems_UpdateInventory.evaluate(wielder,GetOwningPlayer(wielder))
endif
endif
endmethod
public static method create takes unit u, item i, ItemData d returns thistype
local thistype this = thistype.allocate()
local string s
set wielder = u
set itemS = i
set owner = GetOwningPlayer(u)
set data = d
call SetItemPlayer(i,owner,false)
call SetItemUserData(i,this)
set tier = 1
set drooped = false
set wielder = null
set enchant = 0
set pawned = false
set int = 0
set realD = 0
if d.itemType != 0 and d.itemType != 1 then
call BlzSetItemName(itemS,COLOR_LEVEL[tier] + itemName + " - Tier "+I2S(tier)+"|r")
set s = BuildText(this,tier)
call BlzSetItemExtendedTooltip(itemS,s)
endif
call ItemCleanup.RegisterItem(this)
if d.useDummy then
set dummy = CreateUnit(owner,'u001',GetUnitX(u),GetUnitY(u),0)
call SetUnitUserData(dummy,this)
call UnitAddAbility(dummy,abilityID2)
endif
return this
endmethod
public method destroy takes nothing returns nothing
local LinkedList inv
if not drooped then
set inv = GetUnitData(wielder,"UnitItems")
call inv.remove(inventoryIndex)
set inventoryIndex = 0
call giveBonuses(true)
//call BJDebugMsg("removing:"+GetItemName(itemS) + "-"+I2S(inv.size))
endif
set int = 0
call SetItemUserData(itemS,0)
call RemoveItem(itemS)
set wielder = null
set itemS = null
set owner = null
if enchant != 0 then
call enchant.destroy()
endif
if useDummy then
call RemoveUnit(dummy)
set dummy = null
endif
call this.deallocate()
endmethod
endstruct
private function callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetUnitByIndex(GetTimerData(t))
if IsUnitSelected(u,GetOwningPlayer(u)) then
call UIItems_UpdateInventory.evaluate(u,GetOwningPlayer(u))
endif
call ReleaseTimer(t)
set t = null
set u = null
endfunction
private function OnOrder takes nothing returns nothing
local integer order = GetIssuedOrderId()
local unit u = GetTriggerUnit()
local integer id = GetUnitTypeId(u)
if id == BAUL_ID or id == BAUL_ID2 then
if order >= 852008 and order <= 852013 then
call IssueImmediateOrderById(u,ORDER_stop)
elseif order >= 852002 and order <= 852007 then
call TimerStart(NewTimerEx(GetUnitUserData(u)),0.00,false,function callback)
endif
else
if order >= 852002 and order <= 852007 then
call TimerStart(NewTimerEx(GetUnitUserData(u)),0.00,false,function callback)
endif
endif
set u = null
endfunction
public function RegisterHeroOrder takes unit u returns nothing
call TriggerRegisterUnitEvent(OrderBaul,u,EVENT_UNIT_ISSUED_ORDER)
call TriggerRegisterUnitEvent(OrderBaul,u,EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterUnitEvent(OrderBaul,u,EVENT_UNIT_ISSUED_TARGET_ORDER)
endfunction
private function SetBaul takes nothing returns nothing
local integer i = 2
set OrderBaul = CreateTrigger()
call TriggerAddCondition(OrderBaul,function OnOrder)
set Baul[2] = gg_unit_h001_0163
set Baul[3] = gg_unit_h001_0070
set Baul[4] = gg_unit_h001_0119
set Baul[5] = gg_unit_h001_0015
set Baul[6] = gg_unit_h001_0101
set Baul[7] = gg_unit_h00G_0080
set Baul[8] = gg_unit_h00G_0083
set Baul[9] = gg_unit_h00G_0081
set Baul[10] = gg_unit_h00G_0082
set Baul[11] = gg_unit_h00G_0079
loop
exitwhen i > Game.PLAYER_MAX
set Index[GetUnitUserData(Baul[i])].lock = true
call TriggerRegisterUnitEvent(OrderBaul,Baul[i],EVENT_UNIT_ISSUED_ORDER)
call TriggerRegisterUnitEvent(OrderBaul,Baul[i],EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterUnitEvent(OrderBaul,Baul[i],EVENT_UNIT_ISSUED_TARGET_ORDER)
call PauseUnit(Baul[i],true)
set i = i + 1
endloop
endfunction
private function OnPickItem takes nothing returns nothing
local item i = GetManipulatedItem()
local unit u = GetManipulatingUnit()
local integer id = GetItemTypeId(i)
local player p = GetTriggerPlayer()
local boolean isHero = IsUnitType(u,UNIT_TYPE_HERO)
local integer lvl
local integer typec
local ItemData idd
local Item it
local Item it2
if GetItemType(i) == ITEM_TYPE_POWERUP then
set lvl = GetItemLevel(i)
if lvl == 0 then
set idd = GetItemDataByID(id)
if idd != 0 then
set it = GetUnitItemOfType(u,idd.itemID)
if it != 0 then
call SetItemCharges(it.itemS,GetItemCharges(it.itemS) + it.charges)
else
set i = CreateItem(idd.itemID,0,0)
if not UnitAddItem(u,i) then
if not UnitAddItem(Baul[GetPlayerId(p)],i) then
call SetItemPosition(i,GetPlayerStartLocationX(p),GetPlayerStartLocationY(p))
endif
endif
endif
endif
elseif lvl == 1 then
call EnchantPurchase.execute(id,p,i)
elseif lvl == -1 then
if BlzGetItemIntegerField(i,ITEM_IF_COOLDOWN_GROUP) == 'Amec' then
call UnitRemoveBuff(u,PowerRuneBuff.buff)
call UnitRemoveBuff(u,FiercenessRuneBuff.buff)
call UnitRemoveBuff(u,SorceryRuneBuff.buff)
call UnitRemoveBuff(u,VanguardRuneBuff.buff)
if id == 'rhe2' then
call DmgRune(u)
elseif id == 'rre1' then
call RageRune(u)
elseif id == 'rspl' then
call SorceryRune(u)
elseif id == 'rres' then
call VanguardRune(u)
endif
else
if id == 'rdis' then
call RestorationRune(u)
elseif id == 'rma2' then
call GoldRune(u)
elseif id == 'rhe1' then
call HasteRune(u)
elseif id == 'rre2' then
call TrueSightRune(u)
elseif id == 'rman' then
call JumpRune(u,i)
elseif id == 'rreb' then
call IllusionRune(u)
elseif id == 'rsps' then
call InvisibilityRune(u)
endif
endif
call DestroyEffect(AddSpecialEffect("Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl",GetItemX(i),GetItemY(i)))
endif
else
set it = GetItemUserData(i)
if it == 0 then
set idd = GetItemDataByID(id)
if idd != 0 then
if idd.itemType == ITEM_TYPE_CONSUMABLE then
set it2 = GetUnitItemOfType(u,idd.itemID)
if it2 != 0 then
call SetItemCharges(it2.itemS,GetItemCharges(it2.itemS) + it2.charges)
call RemoveItem(i)
else
set it2 = Item.create(u,i,idd)
set it2.drooped = false
set it2.wielder = u
call AddUnitItem(u,it2)
endif
else
set it2 = Item.create(u,i,idd)
if isHero then
if it2.itemType >= 2 then
set typec = GetUnitData(u,"Type"+I2S(idd.itemType))
if typec < 3 then
set typec = typec + 1
set it2.drooped = false
set it2.wielder = u
call it2.giveBonuses(it2.drooped)
call AddUnitItem(u,it2)
call SetUnitData(u,"Type"+I2S(idd.itemType),typec)
else
set it2.drooped = true
set it2.wielder = null
call UnitRemoveItem(u,it2.itemS)
call Message.ShowToPlayer(p,"You can only have 3 items of the same type",MESSAGE_STYLE_ERROR)
endif
else
if it2.itemType == 1 then
set typec = GetUnitData(u,"Type"+I2S(it2.itemType))
if typec < 2 then
set typec = typec + 1
set it2.drooped = false
set it2.wielder = u
call it2.giveBonuses(it2.drooped)
call AddUnitItem(u,it2)
call SetUnitData(u,"Type"+I2S(it2.itemType),typec)
else
set it2.drooped = true
set it2.wielder = null
call it2.destroy()
call Message.ShowToPlayer(p,"You can only have 2 starting items",MESSAGE_STYLE_ERROR)
endif
else
set it2.drooped = false
set it2.wielder = u
call it2.giveBonuses(it2.drooped)
call AddUnitItem(u,it2)
endif
endif
else
set it2.drooped = false
set it2.wielder = u
endif
endif
endif
else
if it.itemType == ITEM_TYPE_CONSUMABLE then
set it2 = GetUnitItemOfType(u,it.itemID)
if it2 != 0 then
call SetItemCharges(it2.itemS,GetItemCharges(it2.itemS) + GetItemCharges(it.itemS))
call it.destroy()
else
call SetItemPlayer(it.itemS,p,true)
set it.owner = p
set it.wielder = u
set it.drooped = false
call AddUnitItem(u,it)
endif
else
if p == it.owner then
if isHero then
if it.itemType >= 2 then
set typec = GetUnitData(u,"Type"+I2S(it.itemType))
if typec < 3 then
set typec = typec + 1
set it.drooped = false
set it.wielder = u
call it.giveBonuses(it.drooped)
call AddUnitItem(u,it)
call SetUnitData(u,"Type"+I2S(it.itemType),typec)
else
set it.drooped = true
set it.wielder = null
call UnitRemoveItem(u,it.itemS)
call Message.ShowToPlayer(p,"You can only have 3 items of the same type",MESSAGE_STYLE_ERROR)
endif
else
if it.itemType == 1 then
set typec = GetUnitData(u,"Type"+I2S(it.itemType))
if typec < 2 then
set typec = typec + 1
set it.drooped = false
set it.wielder = u
call it.giveBonuses(it.drooped)
call AddUnitItem(u,it)
call SetUnitData(u,"Type"+I2S(it.itemType),typec)
else
set it.drooped = true
set it.wielder = null
call UnitRemoveItem(u,it.itemS)
call Message.ShowToPlayer(p,"You can only have 2 starting items",MESSAGE_STYLE_ERROR)
endif
else
set it.drooped = false
set it.wielder = u
call it.giveBonuses(it.drooped)
call AddUnitItem(u,it)
endif
endif
else
set it.drooped = true
set it.wielder = u
endif
else
call UnitRemoveItem(u,i)
call Message.ShowToPlayer(p,"This item don't belongs you",MESSAGE_STYLE_ERROR)
endif
endif
endif
endif
set i = null
set u = null
set p = null
endfunction
private function OnDropItem takes nothing returns nothing
local item i = GetManipulatedItem()
local unit u = GetManipulatingUnit()
local ItemData id
local Rune r
local LinkedList inv
local integer typec
local Item it
if GetItemType(i) != ITEM_TYPE_POWERUP then
set it = GetItemUserData(i)
if it != 0 then
if GetTriggerPlayer() == it.owner and not it.drooped then
set inv = GetUnitData(u,"UnitItems")
call inv.remove(it.inventoryIndex)
set it.inventoryIndex = 0
set it.drooped = true
call TimerStart(NewTimerEx(GetUnitUserData(u)),0.00,false,function callback)
//call BJDebugMsg("removing:"+GetItemName(it.itemS) + "-"+I2S(inv.size))
if IsUnitType(u,UNIT_TYPE_HERO) then
call it.giveBonuses(it.drooped)
endif
set it.wielder = null
if it.itemType >= 1 then
set typec = GetUnitData(u,"Type"+I2S(it.itemType))
call SetUnitData(u,"Type"+I2S(it.itemType),typec - 1)
endif
endif
if it.pawned then
call it.destroy()
endif
endif
else
set r = GetItemUserData(i)
if r == 0 then
call r.destroy()
endif
endif
set u = null
set i = null
endfunction
private function OnUseItem takes nothing returns nothing
local unit u = GetTriggerUnit()
local Item it
local integer i
set it = GetUnitItemOfType(u,'I00A')
if it != 0 then
set i = GetItemCharges(it.itemS)
set i = i + 1
if i >= 3 then
call AddUnitShield(u,100 + 20 * it.tier,4.00,it.itemID)
call SetItemCharges(it.itemS,0)
else
if not UnitHasBuff(u,Shield.buff) then
call SetItemCharges(it.itemS,i)
endif
endif
endif
endfunction
private function OnPawnItem takes nothing returns nothing
local Item it = GetItemUserData(GetSoldItem())
if it != 0 then
set it.pawned = true
endif
endfunction
private function init takes nothing returns nothing
set ItemsData = Table.create()
call SetBaul()
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_PICKUP_ITEM, function OnPickItem)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DROP_ITEM, function OnDropItem)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_USE_ITEM, function OnUseItem)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_PAWN_ITEM, function OnPawnItem)
set COLOR_LEVEL[1] = "|cff00ff00"
set COLOR_LEVEL[2] = "|cffffff00"
set COLOR_LEVEL[3] = "|cffff0000"
endfunction
endlibrary
library ItemUpgrade initializer init uses PlayerLib, SpellEffectEvent
globals
private constant string SFX_DONE = "Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl"
private constant string BUTTON_PATH = "ReplaceableTextures\\CommandButtons\\BTNPatrol.blp"
private constant string DEFAULT_TOOLTIP = "Preview Item |cffffcc00(D)|r"
private constant string DEFAULT_EXTENDED_TOOLTIP = "Preview the next Tier of the selected item.|nShows his bonuses."
private constant integer GOLD_UPGRADE = 400
private constant integer HONOR_UPGRADE = 15
endglobals
private function UpgradeItemToken takes nothing returns nothing
local unit u = GetTriggerUnit()
local item i = GetSpellTargetItem()
local player p = GetTriggerPlayer()
local Hero he = GetUnitData(u,"HeroIndex")
local Item it = GetItemUserData(i)
local Item token = GetUnitItemOfType(u,'moon')
local boolean done = false
if he != 0 and it != 0 then
if it.tier < 3 then
if it.itemType >= 2 then
call token.destroy()
call it.levelup()
call DestroyEffect(AddSpecialEffectTarget(SFX_DONE,u,"origin"))
set done = true
else
call Message.ShowToPlayer(p,"Invalid Item Type",MESSAGE_STYLE_ERROR)
endif
else
call Message.ShowToPlayer(p,"The item is at max level",MESSAGE_STYLE_ERROR)
endif
else
call Message.ShowToPlayer(p,"Invalid Item",MESSAGE_STYLE_ERROR)
endif
if not done then
if token != 0 then
call SetItemCharges(token.itemS,2)
endif
endif
set p = null
set u = null
set i = null
endfunction
private function init takes nothing returns nothing
call RegisterSpellEffectEvent('A09R',function UpgradeItemToken)
endfunction
endlibrary
library ItemCleanup initializer init
globals
private trigger DeathItemTrigger = CreateTrigger()
endglobals
struct ItemCleanup extends array
static integer wasted = 0
static LinkedList list
static Table tb
public static method RegisterItem takes Item it returns nothing
set tb.integer[GetHandleId(it.itemS)] = list.add(it)
call TriggerRegisterDeathEvent(DeathItemTrigger,it.itemS)
endmethod
public static method OnDeath takes nothing returns nothing
local widget w = GetTriggerWidget()
local integer id = GetHandleId(w)
local Link h
local Item it
set wasted = wasted + 1
set h = tb.integer[id]
set it = h.data
if GetItemUserData(it.itemS) != 0 then
call it.destroy()
endif
call list.remove(h)
call tb.remove(id)
if wasted >= 8 then
set wasted = 0
call TriggerClearConditions(DeathItemTrigger)
call DestroyTrigger(DeathItemTrigger)
set DeathItemTrigger = CreateTrigger()
call TriggerAddCondition(DeathItemTrigger,Condition(function thistype.OnDeath))
set h = list.head
loop
exitwhen h == 0
set it = h.data
call TriggerRegisterDeathEvent(DeathItemTrigger,it.itemS)
set h = h.next
endloop
endif
set w = null
endmethod
endstruct
private function init takes nothing returns nothing
call TriggerAddCondition(DeathItemTrigger,function ItemCleanup.OnDeath)
set ItemCleanup.list = LinkedList.create()
set ItemCleanup.tb = Table.create()
endfunction
endlibrary
scope StashAbilities initializer init
private function SellItem takes nothing returns nothing
local item i = GetSpellTargetItem()
local Item it = GetItemUserData(i)
local player p = GetTriggerPlayer()
local Hero h
if it != 0 then
if GetItemPlayer(i) == p and it.wielder == Baul[GetPlayerId(p)] then
set h = GetPlayerHero(p)
if GetPlayerTeamEx(p) == 1 then
call UnitDropItemTarget(it.wielder,i,gg_unit_n007_0063)
else
call UnitDropItemTarget(it.wielder,i,gg_unit_n004_0176)
endif
endif
endif
set i = null
set p = null
endfunction
private function TransferItem takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetTriggerPlayer()
local item i = GetSpellTargetItem()
local Hero h = GetPlayerHero(p)
local Item it = GetItemUserData(i)
local LinkedList inv = GetUnitData(h.hero,"UnitItems")
if i == null then
set u = null
set p = null
return
endif
if UnitAlive(h.hero) and GetItemPlayer(i) == p and it.wielder == u then
if inv.size != bj_MAX_INVENTORY then
call UnitAddItem(h.hero,i)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl",u,"overhead"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl",h.hero,"overhead"))
else
call Message.ShowToPlayer(p,"Inventory full",MESSAGE_STYLE_ERROR)
call UnitRemoveAbility(u,'A09S')
call UnitAddAbility(u,'A09S')
call UnitMakeAbilityPermanent(u,true,'A09S')
endif
else
call Message.ShowToPlayer(p,"Transfer Failed",MESSAGE_STYLE_ERROR)
call UnitRemoveAbility(u,'A09S')
call UnitAddAbility(u,'A09S')
call UnitMakeAbilityPermanent(u,true,'A09S')
endif
set u = null
set p = null
set i = null
endfunction
private function init takes nothing returns nothing
call RegisterSpellEffectEvent('A06B',function SellItem)
call RegisterSpellEffectEvent('A09S',function TransferItem)
endfunction
endscope
library DisruptionMagus initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HAD1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'ADI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Burst Lightnings"
set up.Text = "Increases |c00b4b4b4Arcane Spark|r Damage."
set up.SupText = "Increases |c00b4b4b4Arcane Spark|r cooldown reduction per enemy hit by 0.10s."
set up.LevelData1 = "+20 Damage"
set up.LevelData2 = "+40 Damage"
set up.LevelData3 = "+60 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNNeutralManaShield.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'ADI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Arcane Imprisonment"
set up.Text = "Reduces |c00b4b4b4Magic Walls|r cooldown."
set up.SupText = "|c00b4b4b4Magic Walls|r effect pierces |c00ffff00Spell Immunity|r."
set up.LevelData1 = "-2s Cooldown"
set up.LevelData2 = "-4s Cooldown"
set up.LevelData3 = "-6s Cooldown"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWispSplode.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'ADI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Superior Knowledge"
set up.Text = "Reduces the duration of |c0000ced1Silence|r while |c00b4b4b4Magic Canalization|r is active."
set up.SupText = "Increases the duration of |c00b4b4b4Magic Canalization|r by 5 seconds."
set up.LevelData1 = "40% Reduction"
set up.LevelData2 = "60% Reduction"
set up.LevelData3 = "80% Reduction"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNManual3.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'ADI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Imbue Magic"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HAD1'
set d.Name = "Disruption Magus"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNHeroArchMage.blp"
set d.WinAni = "stand victory"
set d.Block = 10
set d.Evasion = 25
set d.Resistance = 50
set d.LifeRegen = 0.5
set d.ManaRegen = 1.7
set d.Armor = 3
set d.AttackRange = 500
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'ADA1'
set d.HeroAbility2 = 'ADA2'
set d.HeroAbility3 = 'ADA3'
set d.HeroAbility4 = 'ADA4'
set d.ChooseIconID = 'c005'
set d.ChooseDummy = 'dh10'
set d.spellDamageLevel = 9
set d.attackDamageLevel = 1
set d.healingLevel = 0
set d.survivavilityLevel = 1
set d.movementLevel = 1
set d.crowdControlLevel = 7
set d.HeroFaction = Game.FACTION_HUMAN
set d.InfoID = 'HADI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ArcaneSpark initializer init
globals
private constant integer SPELL_ID = 'ADA1'
private constant integer UPGRADE_ID = 'ADI1'
private constant real STUN_DURATION = 0.35
private constant real COOLDOWN_REDUCTION = 0.50
private constant real AREA_BASE = 300.00
private constant real DMG_BASE = 60.00
private constant real DMG_LVL = 30.00
private constant integer COUNT = 5
public constant real UP_DAMAGE = 20.00
public constant real SUP_CD = 0.10
private constant real MA_CD_REDUCTION = -0.15
private constant string SFX_TARGET = "Abilities\\Weapons\\VoidWalkerMissile\\VoidWalkerMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local Table tb
if up.upID == 'ADI2' then
set a = Ability.GetUnitAbilityByID('ADA2',up.ownerHero.hero)
if a != 0 then
call a.addFlatCooldown(-2.0)
endif
if up.isSuperior then
set MagicWalls.buff.PierceImmune = true
endif
endif
if up.upID == 'ADI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 3 then
set tb = GetUnitData(up.ownerHero.hero,"MCCharges")
if tb.integer[2] != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,up.ownerHero.hero,0.04 * tb.integer[2],0)
endif
endif
endif
endfunction
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
local real x = GetUnitX(t)
local real y = GetUnitY(t)
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local integer c = COUNT
local real dmg = GetDamage(lvl) + UP_DAMAGE * GetUpgradeSkillLevel(u,UPGRADE_ID)
local integer cdc = 1
local real sd = STUN_DURATION
local unit temp
local real cdr = COOLDOWN_REDUCTION
local Ability a = Ability.GetUnitAbilityByID(SPELL_ID,u)
if IsUpgradeSuperior(u,UPGRADE_ID) then
set cdr = cdr + SUP_CD
endif
call GroupEnumUnitsInRange(g,x,y,AREA_BASE,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null or c == 0
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and c > 0 then
if temp != t then
set c = c - 1
set cdc = cdc + 1
endif
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"ArionSpellDamage",0,0)
call Lightning.create("WHNL",u,temp,0.75,0.25,100,100).setLightColor(255,25,255,255)
call DestroyEffect(AddSpecialEffectTarget(SFX_TARGET,temp,"overhead"))
call Status.Add(STATUS_STUN,temp,sd,Status_EFFECT[STATUS_STUN])
endif
endloop
if a != 0 then
call a.addTempFlatCooldown(-(cdr * cdc))
endif
call ReleaseGroup(g)
set g = null
set p = null
set temp = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.activationType = ACTIVATION_TYPE_TARGET
set d.hotkey = "Q"
set d.objectID = SPELL_ID
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DisruptionMagus_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(SFX_TARGET)
endfunction
endscope
scope MagicWalls initializer init
globals
private constant integer SPELL_ID = 'ADA2'
private constant integer UPGRADE_ID = 'ADI2'
private constant real EFFECT_AREA = 250.00
private constant real DELAY = 1.20
private constant string SFX_TARGET = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl"
private constant string SFX_WALL = "Doodads\\Cityscape\\Props\\CrystalLamp\\CrystalLamp.mdx"
endglobals
private function GetDuration takes integer lvl returns real
return 2.5 + 0.5 * lvl
endfunction
struct MagicWalls extends array
real x
real y
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real xu = GetUnitX(b.target)
local real yu = GetUnitY(b.target)
local real a
if Distance(x,y,xu,yu) > EFFECT_AREA - 50 then
set a = Angle(x,y,xu,yu)
call SetUnitX(b.target,x + (EFFECT_AREA - 50) * Cos(a))
call SetUnitY(b.target,y + (EFFECT_AREA - 50) * Sin(a))
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01E'
set BUFF_DATA.BuffID = 'B02M'
set BUFF_DATA.Name = "MagicWalls"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Walls extends array
implement Alloc
effect sfx
real x
real y
real z
Lightning light
thistype prev
public method link takes nothing returns nothing
set light = Lightning.createEx("WHNL",x,y,50,prev.x,prev.y,50,99,99)
call light.setLightColor(255,25,255,255)
endmethod
public static method create takes real xc, real yc returns thistype
local thistype this = thistype.allocate()
set sfx = AddSpecialEffect(SFX_WALL,xc,yc)
set x = xc
set y = yc
set z = GetLocZ(xc,yc)
call BlzSetSpecialEffectHeight(sfx,z - 100)
call BlzSetSpecialEffectColor(sfx,255,150,255)
return this
endmethod
public method destroy takes nothing returns nothing
call BlzSetSpecialEffectAlpha(sfx,0)
call DestroyEffect(sfx)
set sfx = null
call light.destroy()
set prev = 0
call this.deallocate()
endmethod
endstruct
private function Activate takes nothing returns nothing
local timer tr = GetExpiredTimer()
local Table tb = GetTimerData(tr)
local real height = tb.real[3]
local LinkedList list = tb.integer[4]
local real t = tb.real[5]
local integer c = tb.integer[6]
local group g
local unit u
local unit temp
local player p
local real x
local real y
local real xt
local real yt
local real a
local real d
local integer lvl
local boolean sup
local Buff b
local Link h
local Walls w
set t = t + 0.03125
set tb.real[5] = t
if t < DELAY then
set h = list.head
set height = height + 1.30
set c = c + 1
loop
exitwhen h == 0
set w = h.data
call BlzSetSpecialEffectHeight(w.sfx,w.z + height)
if c == 8 then
call DestroyEffect(AddSpecialEffect(SFX_TARGET,w.x,w.y))
endif
set h = h.next
endloop
if c == 8 then
set c = 0
endif
set tb.integer[6] = c
set tb.real[3] = height
else
if tb.integer[7] == 0 then
set tb.integer[7] = 1
set g = NewGroup()
set u = tb.unit[0]
set x = tb.real[1]
set y = tb.real[2]
set p = GetOwningPlayer(u)
set d = tb.real[8]
set lvl = GetUnitAbilityLevel(u,SPELL_ID)
set sup = IsUpgradeSuperior(u,UPGRADE_ID)
call GroupEnumUnitsInRange(g,x,y,EFFECT_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
if (not IsUnitMagicImmune(temp) or sup) and IsUnitType(temp,UNIT_TYPE_HERO) then
set b = UnitAddBuff(temp,u,d,MagicWalls.buff,lvl,0)
set MagicWalls[b.buffAllocIndex].x = x
set MagicWalls[b.buffAllocIndex].y = y
set AIDM.Wcount = AIDM.Wcount + 1
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set u = null
set p = null
set h = list.head
loop
exitwhen h == 0
set w = h.data
call w.link()
set h = h.next
endloop
endif
if t >= tb.real[8] + DELAY then
set h = list.head
loop
exitwhen h == 0
set w = h.data
call w.destroy()
call DestroyEffect(AddSpecialEffect(SFX_TARGET,w.x,w.y))
set h = h.next
endloop
set AIDM.Wcount = 0
call list.destroy()
call tb.flush()
call tb.destroy()
call ReleaseTimer(tr)
else
set g = NewGroup()
set u = tb.unit[0]
set x = tb.real[1]
set y = tb.real[2]
set p = GetOwningPlayer(u)
set sup = IsUpgradeSuperior(u,UPGRADE_ID)
call GroupEnumUnitsInRange(g,x,y,EFFECT_AREA + 100,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
if not UnitHasBuff(temp,MagicWalls.buff) and IsUnitType(temp,UNIT_TYPE_HERO) and (not IsUnitMagicImmune(temp) or sup) then
set xt = GetUnitX(temp)
set yt = GetUnitY(temp)
if Distance(x,y,xt,yt) < EFFECT_AREA + 50 and GetUnitData(temp,"KPJ"+I2S(KPJ_TYPE_KNOCKBACK)) == 0 then
if IsPointInSightOfUnit(temp,x,y,60) then
set a = Angle(x,y,xt,yt)
call SetUnitX(temp,x + (EFFECT_AREA + 50) * Cos(a))
call SetUnitY(temp,y + (EFFECT_AREA + 50) * Sin(a))
endif
endif
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set u = null
set p = null
endif
endif
set tr = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local Table tb = Table.create()
local LinkedList list = LinkedList.create()
local timer t = NewTimerEx(tb)
local integer i = 1
local real a = 30
local real xc
local real yc
local Walls prev = 0
local Walls current
loop
exitwhen i > 6
set xc = x + EFFECT_AREA * Cos(a * bj_DEGTORAD)
set yc = y + EFFECT_AREA * Sin(a * bj_DEGTORAD)
set current = Walls.create(xc,yc)
if prev != 0 then
set current.prev = prev
set prev = current
else
set prev = current
endif
call list.addLast(current)
if i == 6 then
set prev = list.head.data
set prev.prev = current
endif
set i = i + 1
set a = a + 60
endloop
set tb.unit[0] = u
set tb.real[1] = x
set tb.real[2] = y
set tb.real[3] = -100
set tb.integer[4] = list
set tb.real[5] = 0
set tb.integer[6] = 0
set tb.integer[7] = 0
set tb.real[8] = GetDuration(GetUnitAbilityLevel(u,SPELL_ID))
call TimerStart(t,0.03125,true,function Activate)
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call MagicWalls.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DisruptionMagus_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01E',PRELOAD_SECOND)
call Preload(SFX_TARGET)
call Preload(SFX_WALL)
endfunction
endscope
scope MagicCanalization initializer init
globals
private constant integer SPELL_ID = 'ADA3'
private constant integer UPGRADE_ID = 'ADI3'
private constant integer AURA_ID = 'A06F'
private constant real BUFF_DURATION = 20.00
private constant real UP_SILEN_BASE = 0.20
private constant real SUP_BUFF_DURATION = 1.00
endglobals
struct MagicCanalization extends array
real silence
real manaRecover
boolean sup
boolean dm
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if silence != 0 then
call AddUnitStatusReduction(STATUS_SILENCE,b.target,-silence,false)
set silence = 0
endif
if dm then
call UnitRemoveAbility(b.target,AURA_ID)
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set manaRecover = 0.08 + 0.02 * b.level
set sup = IsUpgradeSuperior(b.target,UPGRADE_ID)
if ulvl != 0 then
set silence = UP_SILEN_BASE + UP_SILEN_BASE * ulvl
call AddUnitStatusReduction(STATUS_SILENCE,b.target,silence,false)
endif
if GetHeroMasteryType(b.target) == 2 then
call UnitAddAbility(b.target,AURA_ID)
call UnitMakeAbilityPermanent(b.target,true,AURA_ID)
set dm = true
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0C0'
set BUFF_DATA.BuffID = 'B04H'
set BUFF_DATA.Name = "Magic Canalization"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function MCChargeCallback takes nothing returns nothing
local Table tb = GetTimerData(GetExpiredTimer())
local unit u = tb.unit[0]
local integer current = tb.integer[2]
local Ability a
set current = current - 1
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,u,-10,0)
if GetHeroMasteryType(u) == 3 then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,u,-0.04,0)
endif
set a = GetHeroAbilityById(u,SPELL_ID)
call a.abilityNumber.setValue(current)
set tb.integer[2] = current
if current != 0 then
call TimerStart(tb.timer[1],6.0,false,function MCChargeCallback)
endif
set u = null
endfunction
private function AddMCCharge takes unit u returns nothing
local Table tb = GetUnitData(u,"MCCharges")
local integer max = tb.integer[3]
local integer current = tb.integer[2]
local Ability a
if current != max then
set current = current + 1
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,u,10,0)
if GetHeroMasteryType(u) == 3 then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,u,0.04,0)
endif
set a = GetHeroAbilityById(u,SPELL_ID)
call a.abilityNumber.setValue(current)
set tb.integer[2] = current
endif
if current == 1 then
call TimerStart(tb.timer[1],6.0,false,function MCChargeCallback)
endif
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local MagicCanalization mc
if data.dmgType != udg_DamageTypeAttack and data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime and not data.isAbsorbed then
set b = GetUnitBuff(data.source,MagicCanalization.buff)
set mc = b.buffAllocIndex
if b != 0 then
call UnitAddMp(b.target,data.damageMod * mc.manaRecover)
endif
endif
if data.codeDmg.codeName == "ArionSpellDamage" then
if GetUnitAbilityLevel(data.source,SPELL_ID) != 0 then
call AddMCCharge(data.source)
endif
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local MagicCanalization mc
if GetUnitAbilityLevel(data.target,'ADI4') != 0 then
if GetHeroMasteryType(data.target) == 1 then
set data.mult = data.mult - ((GetUnitState(data.target,UNIT_STATE_MANA)/100) * 0.02)
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
if IsUpgradeSuperior(u,UPGRADE_ID) then
call UnitAddBuff(u,u,BUFF_DURATION + 5.00,MagicCanalization.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
else
call UnitAddBuff(u,u,BUFF_DURATION,MagicCanalization.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local integer lvl = GetLearnedSkillLevel()
local Ability a
local Table tb
if lvl == 1 then
set a = GetHeroAbilityById(u,SPELL_ID)
set a.abilityNumber = AbilityNumber.create(SPELL_ID,u)
call a.abilityNumber.setValue(0)
set tb = tb.create()
set tb.unit[0] = u
set tb.timer[1] = NewTimerEx(tb)
set tb.integer[2] = 0
set tb.integer[3] = 4 + 1 * lvl
call SetUnitData(u,"MCCharges",tb)
else
set tb = GetUnitData(u,"MCCharges")
set tb.integer[3] = 4 + 1 * lvl
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.hotkey = "E"
set d.objectID = SPELL_ID
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call MagicCanalization.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call DamageEvent.RegisterDamage(Filter(function OnDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DisruptionMagus_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope DisruptiveNebula initializer init
globals
private constant integer SPELL_ID = 'ADA4'
private constant integer UPGRADE_ID = 'ADI4'
private constant integer DUMMY_ID = 'h00P'
private constant integer EXTRA_ID = 'A04F'
private constant real DURATION = 8.00
private constant real DMG_BASE = 40.00
private constant real DMG_LVL = 20.00
private constant real MP_BASE = 20.00
private constant real MP_LVL = 20.00
private constant real EFFECT_AREA = 250.00
private constant real UP_SPEED = 25.00
private constant string TARGET_SFX = "Abilities\\Weapons\\DruidoftheTalonMissile\\DruidoftheTalonMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
struct DisruptiveVortex extends array
real dps
real time
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_SILENCE,b.target)
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Table tb = b.int
if tb.unit[0] == null or Distance(GetUnitX(tb.unit[1]),GetUnitY(tb.unit[1]),GetUnitX(b.target),GetUnitY(b.target)) > EFFECT_AREA then
set b.removeInside = true
endif
set time = time + 0.10
if time >= 0.50 then
set time = 0.0
call CodeDamage.Damage(b.owner,b.target,dps,udg_DamageTypePure,"ArionSpellDamage",0,0)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,b.target,"overhead"))
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dps = GetDamage(b.level)
set time = 0
call Status.Add(STATUS_SILENCE,b.target,0,Status_EFFECT[STATUS_SILENCE])
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Disruptive Nebula"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Period = 0.10
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local unit d = tb.unit[1]
local real r = tb.real[2]
local real a = tb.real[4]
local real time = tb.real[6]
local real x = GetUnitX(d)
local real y = GetUnitY(d)
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real dps
local real mp
local unit temp
local real s
local real dis
set time = time + 0.03125
if time >= 0.50 then
set dps = tb.real[8]
set time = 0.00
call GroupEnumUnitsInRange(g,x,y,EFFECT_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
if not UnitHasBuff(temp,DisruptiveVortex.buff) then
call UnitAddBuff(temp,u,9999,DisruptiveVortex.buff,lvl,tb)
call CodeDamage.Damage(u,temp,dps,udg_DamageTypePure,"ArionSpellDamage",0,0)
endif
endif
endloop
call ReleaseGroup(g)
if a != -10 then
set mp = tb.real[7]
call UnitRemoveMp(u,mp)
endif
endif
if a != -10 then
set s = tb.real[3]
set dis = tb.real[5]
set x = x + s * Cos(a)
set y = y + s * Sin(a)
call SetUnitX(d,x)
call SetUnitY(d,y)
set dis = dis - s
if dis <= 0 then
set tb.real[4] = -10
else
set tb.real[5] = dis
endif
endif
set tb.real[6] = time
set r = r - 0.03125
set tb.real[2] = r
if r <= 0 then
call ReleaseTimer(t)
call KillUnit(d)
call tb.flush()
call tb.destroy()
if GetUnitData(u,"DNebula") == tb then
call SetUnitData(u,"DNebula",0)
call UnitRemoveAbility(u,EXTRA_ID)
endif
endif
set g = null
set p = null
set t = null
set u = null
set d = null
endfunction
private function onCastExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local Table tb = GetUnitData(u,"DNebula")
if tb != 0 then
set u = tb.unit[1]
set tb.real[4] = Angle(GetUnitX(tb.unit[1]),GetUnitY(tb.unit[1]),x,y)
set tb.real[5] = Distance(GetUnitX(tb.unit[1]),GetUnitY(tb.unit[1]),x,y)
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local real dur = DURATION + 0.50
local real speed = 275
local AoE aoe
local unit dummy
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set speed = speed + UP_SPEED
set dur = dur + 3.0
endif
set tb.unit[0] = u
set dummy = CreateUnit(GetOwningPlayer(u),DUMMY_ID,x,y,90)
call SetUnitTimeScale(dummy,1.25)
call BlzUnitDisableAbility(dummy,'Amov',true,true)
set tb.unit[1] = dummy
set tb.real[2] = dur
set tb.real[3] = speed / 32
set tb.real[4] = -10
set tb.real[6] = 0.00
set tb.real[7] = (MP_BASE + MP_LVL * lvl)/2
set tb.real[8] = GetDamage(lvl)
set aoe = AoE.create(0,0,dummy,EFFECT_AREA)
call aoe.setTime(dur)
call BlzSetSpecialEffectColor(aoe.sfx,200,0,200)
call SetUnitData(u,"DNebula",tb)
call UnitAddAbility(u,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
call TimerStart(t,0.03215,true,function Callback)
set t = null
set u = null
set dummy = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_POINT
set d.UseAuxDummy = false
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DisruptiveVortex.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCastExtra)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DisruptionMagus_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
library ScarletGuard initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HSG1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'SGI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Heroic Strikes"
set up.Text = "Increases |c00b4b4b4Scarlet Strike|r base damage."
set up.SupText = "Increases |c00b4b4b4Scarlet Strike |rtravel distance by 500."
set up.LevelData1 = "20 Bonus Damage"
set up.LevelData2 = "40 Bonus Damage"
set up.LevelData3 = "60 Bonus Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNArcaniteRanged.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'SGI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Ambush Shield"
set up.Text = "Increases |c00b4b4b4Defensive Assault|r cast range."
set up.SupText = "The |c0099b4d1Defensive Assault|r buff remains for 2 seconds after the spell is finished."
set up.LevelData1 = "+50 Cast Range"
set up.LevelData2 = "+100 Cast Range"
set up.LevelData3 = "+150 Cast Range"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNHumanArmorUpTwo.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'SGI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Crusader Emblem"
set up.Text = "Each stack of |c00b4b4b4War Emblem|r also adds a bonus |c00ffff95Attack Strength|r"
set up.SupText = "Increases |c00b4b4b4War Emblem|r max stacks by 3."
set up.LevelData1 = "+5(0.7%) Attack Strength"
set up.LevelData2 = "+10(1.5%) Attack Strength"
set up.LevelData3 = "+15(2.3%) Attack Strength"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNPeriapt.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'SGI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Elite Crusader"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HSG1'
set d.Name = "Scarlet Guard"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNTheCaptain.blp"
set d.WinAni = "spell slam"
set d.Block = 45
set d.Evasion = 20
set d.Resistance = 25
set d.LifeRegen = 1.8
set d.ManaRegen = 1.1
set d.Armor = 6
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'SGA1'
set d.HeroAbility2 = 'SGA2'
set d.HeroAbility3 = 'SGA3'
set d.HeroAbility4 = 'SGA4'
set d.ChooseIconID = 'c006'
set d.ChooseDummy = 'dh07'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 7
set d.healingLevel = 3
set d.survivavilityLevel = 6
set d.movementLevel = 4
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_HUMAN
set d.InfoID = 'HSGI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ScarletStrike initializer init
globals
private constant integer SPELL_ID = 'SGA1'
private constant integer UPGRADE_ID = 'SGI1'
private constant integer SPELL_DUMMY_ID = 'A006'
private constant real DMG_BASE = 60.00
private constant real DMG_LVL = 40.00
private constant real SLOW_MS = -0.50
private constant real SLOW_DURATION = 1.30
private constant real UP_DAMAGE_BASE = 20.00
private constant real MA_DURATION = 10.00
private constant integer MA_ATTACK_SPEED = 7
endglobals
private function GetUpgradeDamage takes integer ulvl returns real
return UP_DAMAGE_BASE * ulvl
endfunction
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
struct MasteryAS extends array
private static method onStackRemove takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-MA_ATTACK_SPEED,0,true)
endmethod
private static method onStackApply takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,MA_ATTACK_SPEED,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0C4'
set BUFF_DATA.BuffID = 'B04L'
set BUFF_DATA.Name = "Scarlet Strike AS"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 10
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct ScarletStrikeSlow extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,SLOW_MS,0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00O'
set BUFF_DATA.BuffID = 'B003'
set BUFF_DATA.Name = "Scarlet Strike Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
public function ScarletStrikeThrow takes unit u, real x, real y, integer op returns nothing
local real xu = GetUnitX(u)
local real yu = GetUnitY(u)
local unit dummy = Dummy.GetRecycled(GetOwningPlayer(u),xu,yu)
local real damage = GetDamage(GetUnitAbilityLevel(u,SPELL_ID)) + GetUpgradeDamage(GetUpgradeSkillLevel(u,UPGRADE_ID))
local AscalonsSwordArt b = GetUnitBuff(u,AscalonsSwordArt.buff).buffAllocIndex
local real angle = Angle(xu,yu,x,y)
call UnitAddAbility(dummy,SPELL_DUMMY_ID)
if IsUpgradeSuperior(u,UPGRADE_ID) then
call SetUnitAbilityLevel(dummy,SPELL_DUMMY_ID,2)
endif
if op == 2 then
set damage = damage / 2
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
set x = x + 25 * Cos(angle)
set y = y + 25 * Sin(angle)
endif
call SetDummyData(dummy,"caster",GetUnitUserData(u))
call SetDummyData(dummy,"damage",R2I(damage))
call CastDummyWave(dummy,ORDER_carrionswarm,x,y)
call Dummy.RecycleDelayed(dummy,0.5,SPELL_DUMMY_ID)
if b != 0 then
call b.addSword(u)
if GetUpgradeSkillLevel(u,'SGI4') == 1 then
call b.addSword(u)
endif
endif
if GetHeroMasteryType(u) == 2 then
call UnitAddBuff(u,u,MA_DURATION,MasteryAS.buff,0,0)
endif
set dummy = null
endfunction
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local unit h
local real dmg
if GetUnitAbilityLevel(data.source,SPELL_DUMMY_ID) != 0 then
set h = Index[GetDummyData(data.source,"caster")].u
set dmg = I2R(GetDummyData(data.source,"damage"))
call CodeDamage.Damage(h,data.target,dmg,udg_DamageTypeMagicAoe,"",0,0)
call UnitAddBuff(data.target,h,SLOW_DURATION,ScarletStrikeSlow.buff,0,0)
set h = null
endif
endfunction
private function onCast takes nothing returns nothing
call ScarletStrikeThrow(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY(),1)
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_POINT
set d.UseAuxDummy = true
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call MasteryAS.Initialize()
call ScarletStrikeSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ScarletGuard_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(SPELL_DUMMY_ID,PRELOAD_FIRST)
endfunction
endscope
scope DefensiveAssault initializer init
globals
private constant integer SPELL_ID = 'SGA2'
private constant integer UPGRADE_ID = 'SGI2'
private constant real EFFECT_AREA = 145.00
private constant real SPEED = 22.00
private constant real DMG_BASE = 60.00
private constant real DMG_LVL = 30.00
private constant real STUN_DURATION = 1.20
private constant string SHIELD_SFX = "Abilities\\Spells\\Human\\Defend\\DefendCaster.mdl"
private constant string HIT_SFX = "Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
struct DefensiveAssault extends array
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A012'
set BUFF_DATA.BuffID = 'B00C'
set BUFF_DATA.Name = "Deffensive Assault"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function Loop takes nothing returns nothing
local Table t = GetTimerData(GetExpiredTimer())
local unit caster = t.unit[0]
local real distance = t.real[1]
local group enum = t.group[2]
local group damaged = t.group[3]
local real x = GetUnitX(caster)
local real y = GetUnitY(caster)
local player p = t.player[4]
local real cos = t.real[5]
local real sin = t.real[6]
local real damage = GetDamage(GetUnitAbilityLevel(caster,SPELL_ID))
local unit temp
set distance = distance - SPEED
set t.real[1] = distance
if distance > 0 then
set x = x + SPEED * cos
set y = y + SPEED * sin
call SetUnitX(caster,x)
call SetUnitY(caster,y)
call DestroyEffect(AddSpecialEffectTarget(SHIELD_SFX,caster,"origin"))
call GroupEnumUnitsInRange(enum,x,y,EFFECT_AREA,null)
loop
set temp = FirstOfGroup(enum)
exitwhen temp == null
call GroupRemoveUnit(enum,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitInGroup(temp,damaged) and not IsUnitMagicImmune(temp) then
call GroupAddUnit(damaged,temp)
call CodeDamage.Damage(caster,temp,damage,udg_DamageTypePhysicalAoe,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"overhead"))
call Status.Add(STATUS_STUN,temp,STUN_DURATION,Status_EFFECT[STATUS_STUN])
endif
endloop
else
call Status.Remove(STATUS_UNPATH,caster)
call Status.Remove(STATUS_UNTURN,caster)
call ReleaseTimer(GetExpiredTimer())
call ReleaseGroup(damaged)
call ReleaseGroup(enum)
call t.flush()
call t.destroy()
if IsUpgradeSuperior(caster,UPGRADE_ID) then
call SetUnitBuffDuration(caster,DefensiveAssault.buff,2.0)
else
call UnitRemoveBuff(caster,DefensiveAssault.buff)
endif
endif
set caster = null
set enum = null
set damaged = null
set p = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local Table t = Table.create()
local timer tr = NewTimerEx(t)
local real a = Angle(GetUnitX(u),GetUnitY(u),x,y)
set t.unit[0] = u
set t.real[1] = Distance(GetUnitX(u),GetUnitY(u),x,y)
set t.group[2] = NewGroup()
set t.group[3] = NewGroup()
set t.player[4] = GetOwningPlayer(u)
set t.real[5] = Cos(a)
set t.real[6] = Sin(a)
call Status.Add(STATUS_UNPATH,u,0,0)
call Status.Add(STATUS_UNTURN,u,0,0)
call UnitAddBuff(u,u,99999,DefensiveAssault.buff,0,0)
call TimerStart(tr,0.03125,true,function Loop)
set tr = null
set u = null
endfunction
private function onPostDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
if UnitHasBuff(data.target,DefensiveAssault.buff) and data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set data.damageMod = 0
set data.isAbsorbed = true
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DefensiveAssault.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPostCalculation(Filter(function onPostDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ScarletGuard_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A012',PRELOAD_SECOND)
call Preload(HIT_SFX)
call Preload(SHIELD_SFX)
endfunction
endscope
scope WarEmblem initializer init
globals
private constant integer SPELL_ID = 'SGA3'
private constant integer UPGRADE_ID = 'SGI3'
private constant integer STR_BASE = 1
private constant integer STR_LEVEL = 1
private constant integer CHANCE_BASE = 25
private constant real BUFF_DURATION = 10.00
private constant real UP_AS = 5.00
private constant real MA_REDUCTION = 0.12
endglobals
private function GetStrengthBonus takes integer lvl returns integer
return STR_BASE + STR_LEVEL * lvl
endfunction
struct WarEmblem extends array
integer bonus
real as
integer re
private static method onStackRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,-bonus,0,true)
if re == 1 then
set re = 0
call AddUnitStatusReduction(STATUS_STUN,b.target,-MA_REDUCTION,false)
call AddUnitStatusReduction(STATUS_DISARM,b.target,-MA_REDUCTION,false)
endif
if as != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,-as,0)
set as = 0
endif
endmethod
private static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set bonus = GetStrengthBonus(b.level)
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,bonus,0,true)
if GetHeroMasteryType(b.target) == 3 then
set re = 1
call AddUnitStatusReduction(STATUS_STUN,b.target,MA_REDUCTION,false)
call AddUnitStatusReduction(STATUS_DISARM,b.target,MA_REDUCTION,false)
endif
if ulvl != 0 then
set as = UP_AS * ulvl
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,as,0)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00Z'
set BUFF_DATA.BuffID = 'B00B'
set BUFF_DATA.Name = "War Emblem"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 3
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local BuffData bd
local Ability a
if up.upID == UPGRADE_ID and up.isSuperior then
set bd = WarEmblem.buff
set bd.StackMax = bd.StackMax + 3
endif
if up.upID == 'SGI2' then
set a = Ability.GetUnitAbilityByID('SGA2',up.ownerHero.hero)
call a.addCastRange(50)
endif
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local integer chance
if data.dmgType == udg_DamageTypeAttack and not data.isMiss and data.allowOrbs then
set lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
if lvl != 0 and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) and not IsUnitType(data.target,UNIT_TYPE_MECHANICAL) then
set chance = CHANCE_BASE
if data.codeDmg.codeName == "Ascalon" then
set chance = chance + AscalonsSwordArt_GetChanceBonus.evaluate(lvl)
if GetHeroMasteryType(data.source) == 1 then
call UnitAddHp(data.source,data.damageMod * 0.25)
call UnitAddMp(data.source,data.damageMod * 0.25)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl",data.source,"chest"))
endif
endif
if GetRandomInt(1,100) <= chance then
call UnitAddBuff(data.source,data.source,BUFF_DURATION,WarEmblem.buff,lvl,0)
if GetUnitAbilityLevel(data.source,'SGA1') != 0 then
call ScarletStrike_ScarletStrikeThrow(data.source,GetUnitX(data.target),GetUnitY(data.target),2)
endif
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
set d.activationType = ACTIVATION_TYPE_NONE
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call WarEmblem.Initialize()
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ScarletGuard_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A00Z',PRELOAD_SECOND)
endfunction
endscope
scope AscalonsSwordArt initializer init
globals
private constant integer SPELL_ID = 'SGA4'
private constant integer SPELL_EXTRA_ID = 'A011'
private constant integer UPGRADE_ID = 'SGI4'
private constant integer SPELL_DUMMY_SFX = 'A010'
private constant integer MAX_SWORDS = 3
private constant real DMG_SINGLE_BASE = 60.00
private constant real DMG_SINGLE_LEVEL = 60.00
private constant real STR_DAMAGE_BASE = 0.25
private constant real STR_DAMAGE_LEVEL = 0.25
private constant integer CHANCE_SS_BASE = 5
private constant integer CHANCE_SS_LEVEL = 5
private constant real DURATION = 20.00
private constant real UP_DURATION = 5.00
private constant real SWORDS_OFFSET = 100.00
private constant real SWORDS_SPEED = 28.00
private constant real SWORDS_ACCELERATION = 0.65
private constant real SWORDS_HEIGHT = 145.00
private constant string SWORDS_MODEL = "war3mapImported\\MastermindMissile.mdx"
private constant string SWORDS_AOE_SFX = "Abilities\\Spells\\Human\\Feedback\\SpellBreakerAttack.mdl"
endglobals
public function GetChanceBonus takes integer lvl returns integer
return CHANCE_SS_BASE + CHANCE_SS_LEVEL * lvl
endfunction
private function GetDamage takes integer lvl returns real
return DMG_SINGLE_BASE + DMG_SINGLE_LEVEL * lvl
endfunction
private struct AscalonsSwordMissile extends array
private static method onFinish takes Missile missile returns boolean
local DamageOptions op = DamageOptions.create()
set op.allowOrbs = true
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeAttack,"Ascalon",0,op)
call DestroyEffect(AddSpecialEffect(SWORDS_AOE_SFX,missile.impact.x, missile.impact.y))
return true
endmethod
private static method onRemove takes Missile missile returns boolean
local DummySFX dummy = missile.data
call UnitRemoveAbility(dummy.dummy,'A010')
call dummy.destroy()
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissileTarget takes unit source, unit target, DummySFX dummy returns Missile
local Missile missile = Missile.createEx(dummy.dummy,0.00,0.00,50.0)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.target = target
set missile.data = dummy
set missile.speed = 19.00
set missile.acceleration = 0.35
set missile.damage = GetDamage(GetUnitAbilityLevel(source,SPELL_ID))
call AscalonsSwordMissile.launch(missile)
return missile
endfunction
struct AscalonsSwordArt extends array
Table table
public method launchSword takes unit caster, unit target returns nothing
local DummySFX dummy
local LinkedList list
if table.integer[1] != 0 then
set table.integer[1] = table.integer[1] - 1
set list = table.integer[0]
set dummy = list.last.data
call list.remove(list.last)
call SetupMissileTarget(caster,target,dummy)
endif
endmethod
public method addSword takes unit target returns nothing
local DummySFX dummy
local LinkedList list
local Ability a
if table.integer[1] < table.integer[2] then
set table.integer[1] = table.integer[1] + 1
set list = table.integer[0]
set dummy = DummySFX.create(GetUnitX(target),GetUnitY(target),SWORDS_HEIGHT,GetUnitFacing(target),DUMMYSFX_TYPE_NORMAL)
set dummy.SFX = SWORDS_MODEL
set dummy.Scale = 0.6
call dummy.setColor(255,255,0,255)
call UnitAddAbility(dummy.dummy,'A010')
call list.addLast(dummy)
endif
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LinkedList list = table.integer[0]
local Link h = list.head
local DummySFX dummy
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local real a = GetUnitFacing(b.target)
local real aoff = 15.00 * (table.integer[2] - 1)
local real astart = a - aoff
loop
exitwhen h == 0
set dummy = h.data
call SetUnitX(dummy.dummy,x - SWORDS_OFFSET * Cos(astart * bj_DEGTORAD))
call SetUnitY(dummy.dummy,y - SWORDS_OFFSET * Sin(astart * bj_DEGTORAD))
call SetUnitFacing(dummy.dummy,a)
set h = h.next
set astart = astart + 30.00
endloop
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LinkedList list = table.integer[0]
local Link h = list.head
local DummySFX dummy
loop
exitwhen h == 0
set dummy = h.data
call UnitRemoveAbility(dummy.dummy,'A010')
call dummy.destroy()
set h = h.next
endloop
call list.destroy()
call table.flush()
call table.destroy()
call UnitRemoveAbility(b.target,SPELL_EXTRA_ID)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LinkedList list = LinkedList.create()
local integer count = MAX_SWORDS
local integer i = 0
local real a = GetUnitFacing(b.target)
local real aoff = 15.00 * (count - 1)
local real astart = a - aoff
local real height = SWORDS_HEIGHT
local DummySFX dummy
local real x
local real y
loop
set i = i + 1
if i == 1 or i == count and count >= 3 then
set height = height - 20.00
else
set height = SWORDS_HEIGHT
endif
set x = GetUnitX(b.target) - SWORDS_OFFSET * Cos(astart * bj_DEGTORAD)
set y = GetUnitY(b.target) - SWORDS_OFFSET * Sin(astart * bj_DEGTORAD)
set dummy = DummySFX.create(x,y,height,a,DUMMYSFX_TYPE_NORMAL)
set dummy.SFX = SWORDS_MODEL
set dummy.Scale = 0.6
call dummy.setColor(255,255,0,255)
call UnitAddAbility(dummy.dummy,SPELL_DUMMY_SFX)
set astart = astart + 30.00
call list.add(dummy)
exitwhen i == count
endloop
set table = table.create()
set table.integer[0] = list
set table.integer[1] = count
set table.integer[2] = count
call UnitAddAbility(b.target,SPELL_EXTRA_ID)
call UnitMakeAbilityPermanent(b.target,true,SPELL_EXTRA_ID)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02I'
set BUFF_DATA.BuffID = 'B01B'
set BUFF_DATA.Name = "AscalonsSwordArt"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = DURATION
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set d = d + UP_DURATION
endif
call UnitAddBuff(u,u,d,AscalonsSwordArt.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function onCastThrow takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local AscalonsSwordArt b = GetUnitBuff(u,AscalonsSwordArt.buff).buffAllocIndex
if b != 0 then
call b.launchSword(u,t)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.objectID = SPELL_ID
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call AscalonsSwordArt.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(SPELL_EXTRA_ID, function onCastThrow)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ScarletGuard_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(SPELL_EXTRA_ID,PRELOAD_SECOND)
call PreloadGen.Add(SPELL_DUMMY_SFX,PRELOAD_SECOND)
call PreloadGen.Add('A02I',PRELOAD_SECOND)
call Preload(SWORDS_MODEL)
call Preload(SWORDS_AOE_SFX)
endfunction
endscope
library SacredDefender initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HSC1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'SCI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Represion"
set up.Text = "|c00b4b4b4Justice Hammer|r deals a % of target missing hp as bonus damage."
set up.SupText = "|c00b4b4b4Justice Hammer|r deals |c00ee82eePure Damage|r and always makes a critical strike."
set up.LevelData1 = "5% of Missing Hp as Damage"
set up.LevelData2 = "7% of Missing Hp as Damage"
set up.LevelData3 = "9% of Missing Hp as Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNManaRecharge.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'SCI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Protection"
set up.Text = "Increases |c0099b4d1Bastion of Light|r duration."
set up.SupText = "|c0099b4d1Bastion of Light|r dispels 1 debuff from the target at start and end of the buff."
set up.LevelData1 = "+1s Duration"
set up.LevelData2 = "+2s Duration"
set up.LevelData3 = "+3s Duration"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNDevotion.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'SCI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Restoration"
set up.Text = "Reduces |c00b4b4b4Sacred Prism|r Cooldown."
set up.SupText = "Adds 2 seconds duration to |c00b4b4b4Sacred Prism |reffect."
set up.LevelData1 = "1s CD reduction"
set up.LevelData2 = "2s CD reduction"
set up.LevelData3 = "3s CD reduction"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNHealingWave.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'SCI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Light Sage"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HSC1'
set d.Name = "Sacred Defender"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNPaladin.blp"
set d.WinAni = "stand victory"
set d.Block = 30
set d.Evasion = 0
set d.Resistance = 40
set d.LifeRegen = 1.20
set d.ManaRegen = 1.20
set d.Armor = 4
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'SCA1'
set d.HeroAbility2 = 'SCA2'
set d.HeroAbility3 = 'SCA3'
set d.HeroAbility4 = 'SCA4'
set d.ChooseIconID = 'c009'
set d.ChooseDummy = 'dh12'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 1
set d.healingLevel = 7
set d.survivavilityLevel = 6
set d.movementLevel = 1
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_HUMAN
set d.InfoID = 'HSCI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope JusticeHammer initializer init
globals
private constant integer SPELL_ID = 'SCA1'
private constant integer UPGRADE_ID = 'SCI1'
private constant real DAMAGE_BASE = 25.00
private constant real DAMAGE_LEVEL = 50.00
private constant real STUN_DURATION = 2.00
private constant real WB_EFFECT_AREA_BASE = 100.00
private constant real WB_EFFECT_AREA_LVL = 100.00
private constant integer WB_MAX_UNITS = 1
private constant real MA_DAMAGE_INC = 0.50
private constant string TARGET_SFX = "Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl"
private constant string MISSILE_SFX = "war3mapImported\\Judgment of Light.mdx"
endglobals
private function GetMissLifeDmg takes integer ulvl returns real
return 0.03 + 0.02 * ulvl
endfunction
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function WBEffectArea takes integer lvl returns real
return WB_EFFECT_AREA_BASE + WB_EFFECT_AREA_LVL * lvl
endfunction
private function callback takes nothing returns nothing
local timer ti = GetExpiredTimer()
local Table tb = GetTimerData(ti)
local unit u = tb.unit[0]
local unit t = tb.unit[1]
local integer lvl = tb.integer[5]
local unit aux
local DamageOptions op = 0
local integer dmgtype = udg_DamageTypeMagic
local real damage = GetDamage(lvl)
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local real mshp = GetMissLifeDmg(ulvl)
if GetHeroMasteryType(u) == 1 then
set damage = damage + damage * MA_DAMAGE_INC
endif
if IsUpgradeSuperior(u,UPGRADE_ID) then
set op = DamageOptions.create()
set op.trueCritical = true
set dmgtype = udg_DamageTypePure
endif
if tb.boolean[4] then
set aux = tb.unit[2]
if aux != null then
endif
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,aux,"chest"))
if ulvl != 0 then
call CodeDamage.Damage(u,aux,damage + GetUnitMissingLife(aux) * mshp,dmgtype,"",0,op)
else
call CodeDamage.Damage(u,aux,damage,dmgtype,"",0,op)
endif
call Status.Add(STATUS_STUN,aux,STUN_DURATION,Status_EFFECT[STATUS_STUN])
set aux = null
endif
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,t,"chest"))
if ulvl != 0 then
call CodeDamage.Damage(u,t,damage + GetUnitMissingLife(t) * mshp,dmgtype,"",0,op)
else
call CodeDamage.Damage(u,t,damage,dmgtype,"",0,op)
endif
call Status.Add(STATUS_STUN,t,STUN_DURATION,Status_EFFECT[STATUS_STUN])
call tb.flush()
call tb.destroy()
call ReleaseTimer(ti)
set u = null
set t = null
set ti = null
endfunction
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
local Table tb = Table.create()
local group g
local unit temp
local player p
local integer c = WB_MAX_UNITS
local integer i
local integer j
local Hero h
set tb.unit[0] = u
set tb.unit[1] = t
set tb.integer[5] = lvl
if UnitHasBuff(u,WingedBlessing.buff) then
set tb.boolean[4] = true
set g = NewGroup()
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,GetUnitX(t),GetUnitY(t),WBEffectArea(lvl),null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null or c == 0
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and c != 0 and temp != t then
call DestroyEffect(AddSpecialEffectTarget(MISSILE_SFX,temp,"origin"))
set tb.unit[2] = temp
set c = 0
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set temp = null
endif
call DestroyEffect(AddSpecialEffectTarget(MISSILE_SFX,t,"origin"))
call TimerStart(NewTimerEx(tb),0.75,false,function callback)
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == 'SCI4' then
if up.level == 1 then
set a = Ability.GetUnitAbilityByID('SCA4',up.ownerHero.hero)
call a.addFlatCooldown(-30.0)
endif
if GetHeroMasteryType(up.ownerHero.hero) == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(-2.0)
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,SacredDefender_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope BastionOfLight initializer init
globals
private constant integer SPELL_ID = 'SCA2'
private constant integer UPGRADE_ID = 'SCI2'
private constant real SHIELD_LIFE_BASE = 100.00
private constant real SHIELD_LIFE_LEVEL = 40.00
private constant real BUFF_DURATION = 8.00
private constant real EFFECT_AREA = 600.00
private constant real MA_HASTE = 1.50
private constant string AREA_SFX = "Abilities\\Spells\\Undead\\ReplenishHealth\\ReplenishHealthCasterOverhead.mdl"
endglobals
private function GetShieldLife takes integer lvl returns real
return SHIELD_LIFE_BASE + SHIELD_LIFE_LEVEL * lvl
endfunction
private function GetWBShieldInc takes integer lvl returns real
return 100.00 + 100.00 * lvl
endfunction
struct BastionOfLight extends array
real life
real total
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g
local player p
local unit temp
local real heal
if life != total then
set g = NewGroup()
set p = GetOwningPlayer(b.owner)
set heal = total
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),EFFECT_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ALLIED(temp,p) and temp != b.target then
call CodeDamage.Damage(b.owner,temp,heal,udg_DamageTypeHeal,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(AREA_SFX,temp,"overhead"))
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
call UnitDispelBuffs(b.target,1,BUFF_TYPE_NEGATIVE)
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Buff wb = GetUnitBuff(b.target,WingedBlessing.buff)
set life = GetShieldLife(b.level)
set total = life
if wb != 0 then
set life = life + 50 + 50 * wb.level
set total = life
endif
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
call UnitDispelBuffs(b.target,1,BUFF_TYPE_NEGATIVE)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00T'
set BUFF_DATA.BuffID = 'B00G'
set BUFF_DATA.Name = "Bastion of Light"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
if data.dmgType == udg_DamageTypeHeal or data.dmgType == udg_DamageTypeHealOverTime then
if UnitHasBuff(data.source,WingedBlessing.buff) then
if GetHeroMasteryType(data.source) == 3 then
set data.mult = data.mult + WingedBlessing_UP_HEAL_INCREASE
endif
endif
endif
endfunction
private function onAbsorb takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local BastionOfLight b
if not data.isAbsorbed then
set b = GetUnitBuff(data.target,BastionOfLight.buff).buffAllocIndex
if b != 0 and data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b.life = b.life - data.damageMod
if b.life < 0 then
if b.life <= -1 then
set data.damageMod = b.life * -1
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
set b.life = 0
call UnitRemoveBuff(data.target,BastionOfLight.buff)
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = BUFF_DURATION + 1.0 * GetUpgradeSkillLevel(u,UPGRADE_ID)
call UnitAddBuff(GetSpellTargetUnit(),u,d,BastionOfLight.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call BastionOfLight.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPostCalculation(Filter(function onAbsorb))
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,SacredDefender_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A00T',PRELOAD_SECOND)
endfunction
endscope
scope OmniLight initializer init
globals
private constant integer SPELL_ID = 'SCA3'
private constant integer UPGRADE_ID = 'SCI3'
private constant real GREAT_BASE = 80.00
private constant real GREAT_LEVEL = 40.00
private constant real SMALL_BASE = 40.00
private constant real SMALL_LEVEL = 20.00
private constant real BUFF_DURATION = 6.00
private constant real INTERVAL = 2.00
private constant real AREA_EFFECT = 270.00
private constant real WB_AREA_BASE = 80.00
private constant real WB_AREA_LEVEL = 20.00
private constant real SUP_DURATION = 2.00
private constant string HIT_SFX = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
endglobals
private function GetGreatAmount takes integer ulvl returns real
return GREAT_BASE + GREAT_LEVEL * ulvl
endfunction
private function GetSmallAmount takes integer lvl returns real
return SMALL_BASE + SMALL_LEVEL * lvl
endfunction
private function GetWBArea takes integer lvl returns real
return WB_AREA_BASE + WB_AREA_LEVEL * lvl
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
if a != 0 then
call a.addFlatCooldown(-1)
endif
endif
if up.upID == 'SCI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 2 then
set SacredPrism.BUFF_DATA.Period = 1.5
endif
endif
endfunction
struct SacredPrism extends array
AoE aoe
real area
real dmg1
real dmg2
boolean isAlly
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call aoe.destroy()
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g = NewGroup()
local player p = GetOwningPlayer(b.owner)
local unit temp
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if isAlly then
if FILT_UNIT_ALLIED(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"origin"))
call CodeDamage.Damage(b.owner,temp,dmg1,udg_DamageTypeHeal,"",0,0)
if temp != b.target then
call Lightning.create("HWPB",temp,b.target,0.7,0.25,0,150)
endif
endif
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"origin"))
call CodeDamage.Damage(b.owner,temp,dmg2,udg_DamageTypeMagicAoe,"",0,0)
if temp != b.target then
call Lightning.create("HWPB",temp,b.target,0.7,0.25,0,150)
endif
endif
else
if FILT_UNIT_ALLIED(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"origin"))
call CodeDamage.Damage(b.owner,temp,dmg2,udg_DamageTypeHeal,"",0,0)
if temp != b.target then
call Lightning.create("HWPB",temp,b.target,0.7,0.25,0,150)
endif
endif
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"origin"))
call CodeDamage.Damage(b.owner,temp,dmg1,udg_DamageTypeMagicAoe,"",0,0)
if temp != b.target then
call Lightning.create("HWPB",temp,b.target,0.7,0.25,0,150)
endif
endif
endif
endloop
call ReleaseGroup(g)
set p = null
set g = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg1 = GetGreatAmount(b.level)
set dmg2 = GetSmallAmount(b.level)
set isAlly = IsUnitAlly(b.target,GetOwningPlayer(b.owner))
set area = AREA_EFFECT
if UnitHasBuff(b.owner,WingedBlessing.buff) then
set area = area + GetWBArea(GetUnitAbilityLevel(b.owner,'SCA4'))
endif
set aoe = AoE.create(0,0,b.target,area)
call BlzSetSpecialEffectColor(aoe.sfx,255,255,0)
if isAlly then
set b.buffType = BUFF_TYPE_POSITIVE
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A016'
set BUFF_DATA.BuffID = 'B00I'
set BUFF_DATA.Name = "Sacred Prism"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = INTERVAL
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
if IsUpgradeSuperior(u,UPGRADE_ID) then
call UnitAddBuff(t,u,BUFF_DURATION + SUP_DURATION,SacredPrism.buff,lvl,0)
else
call UnitAddBuff(t,u,BUFF_DURATION,SacredPrism.buff,lvl,0)
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if IsUnitAlly(t,GetTriggerPlayer()) then
call SpellTrigger(u,t,lvl)
else
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SacredPrism.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,SacredDefender_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A016',PRELOAD_SECOND)
endfunction
endscope
scope WingedBlessing initializer init
globals
private constant integer SPELL_ID = 'SCA4'
private constant integer UPGRADE_ID = 'SCI4'
public constant real UP_HEAL_INCREASE = 0.20
private constant real BUFF_DURATION = 20.00
endglobals
struct WingedBlessing extends array
real cr
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Ability a = Ability.GetUnitAbilityByID('SCA1',b.target)
if a != 0 then
call a.addCastRange(-cr)
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Ability a = Ability.GetUnitAbilityByID('SCA1',b.target)
set cr = 100 + 100 * b.level
if a != 0 then
call a.addCastRange(cr)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A015'
set BUFF_DATA.BuffID = 'B00H'
set BUFF_DATA.Name = "Winged Blessing"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u returns nothing
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
call UnitAddBuff(u,u,BUFF_DURATION + 5.0,WingedBlessing.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
else
call UnitAddBuff(u,u,BUFF_DURATION,WingedBlessing.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
endif
endfunction
private function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call WingedBlessing.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,SacredDefender_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A015',PRELOAD_SECOND)
endfunction
endscope
library Earthbinder initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HEB1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'EBI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Sharpened Rock"
set up.Text = "Increases |c00b4b4b4Earthen Steel|r travel distance."
set up.SupText = "The |c00b4b4b4Tremors|r granted by |c00b4b4b4Earthen Steel|r makes 100% more damage."
set up.LevelData1 = "+100 Distance"
set up.LevelData2 = "+200 Distance"
set up.LevelData3 = "+300 Distance"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNManaRecharge.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'EBI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Epicenter"
set up.Text = "Increases |c00b4b4b4Tremors|r area of effect."
set up.SupText = "|c00b4b4b4Tremors|r effect made by |c00b4b4b4Earthen Steel|r or |c00b4b4b4Primal Form|r will slow enemies for 2 seconds additionally."
set up.LevelData1 = "+50 AoE"
set up.LevelData2 = "+75 AoE"
set up.LevelData3 = "+100 AoE"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNDevotion.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'EBI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Granite Skin"
set up.Text = "Increases |c00b4b4b4Summon Golems|r Hp base."
set up.SupText = "Increases the amount of Hp the golem receive from hero max Hp by 4%."
set up.LevelData1 = "+100 Hp"
set up.LevelData2 = "+150 Hp"
set up.LevelData3 = "+200 Hp"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNHealingWave.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'EBI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Earth Eminence"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HEB1'
set d.Name = "Earthbinder"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNEarthbinder.blp"
set d.WinAni = "spell slam"
set d.Block = 30
set d.Evasion = 0
set d.Resistance = 30
set d.LifeRegen = 1.00
set d.ManaRegen = 1.50
set d.Armor = 1
set d.AttackRange = 320
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'EBA1'
set d.HeroAbility2 = 'EBA2'
set d.HeroAbility3 = 'EBA3'
set d.HeroAbility4 = 'EBA4'
set d.ChooseIconID = 'c019'
set d.ChooseDummy = 'dh19'
set d.spellDamageLevel = 5
set d.attackDamageLevel = 5
set d.healingLevel = 0
set d.survivavilityLevel = 7
set d.movementLevel = 2
set d.crowdControlLevel = 3
set d.HeroFaction = Game.FACTION_HUMAN
set d.InfoID = 'HEBI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope EarthenSteel initializer init
globals
private constant integer SPELL_ID = 'EBA1'
private constant integer UPGRADE_ID = 'EBI1'
private constant integer EXTRA_ID = 'A008'
private constant real DIST_BASE = 900.00
private constant real DAMAGE_BASE = 50.00
private constant real DAMAGE_LEVEL = 50.00
private constant real UP_DIST = 100.00
private constant string TARGET_SFX = "Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl"
private constant string ART_SFX = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
private constant string MISSILE_SFX = "Abilities\\Weapons\\RexxarMissile\\RexxarMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetDistanceBonus takes integer ulvl returns real
return UP_DIST * ulvl
endfunction
struct EarthenSteelMissile extends array
effect missile1
effect missile2
real offset
boolean returning
group g
group damaged
real time
real AICounter
public static method Return takes Missile missile returns nothing
local thistype this = thistype[missile]
local integer tlvl
call BlzUnitDisableAbility(missile.source,EXTRA_ID,true,true)
call BlzUnitHideAbility(missile.source,SPELL_ID,false)
call BlzSetSpecialEffectTimeScale(missile1,-1)
call BlzSetSpecialEffectTimeScale(missile2,-1)
call BlzSetSpecialEffectYaw(missile1,missile.angle + bj_PI)
call BlzSetSpecialEffectYaw(missile2,missile.angle + bj_PI)
set missile.target = missile.source
set returning = true
set tlvl = GetUnitAbilityLevel(missile.source,'EBA2')
if tlvl != 0 then
call Tremor.evaluate(missile.source,BlzGetLocalSpecialEffectX(missile1),BlzGetLocalSpecialEffectY(missile1),2,0,0)
call Tremor.evaluate(missile.source,BlzGetLocalSpecialEffectX(missile2),BlzGetLocalSpecialEffectY(missile2),2,0,0)
endif
endmethod
private static method onPeriod takes Missile missile returns boolean
local thistype this = missile
local real x1
local real y1
local real x2
local real y2
local real z
local boolean b = false
local effect sfx
local unit temp
set z = GetLocZ(missile.x,missile.y)
if AICounter != 0.00 then
set AICounter = AICounter - 0.03125
if AICounter <= 0.00 then
set AICounter = 0.00
call IssueImmediateOrderById(missile.source,ORDER_manashieldon)
return false
endif
endif
if AIEB.activated and missile.source == AIEB.AI.playerHero.hero then
if not returning then
if Distance(missile.x,missile.y,missile.impact.x,missile.impact.y) < 50.00 then
call IssueImmediateOrderById(missile.source,ORDER_manashieldon)
return false
endif
endif
endif
set time = time + 0.03125
if time >= 0.10 then
set time = 0.00
set b = true
endif
if returning and offset > 20.00 then
set offset = offset - 1.5
endif
call GroupClear(g)
set x1 = missile.x + offset * Cos(missile.angle - 1.5707)
set y1 = missile.y + offset * Sin(missile.angle - 1.5707)
call BlzSetSpecialEffectX(missile1,x1)
call BlzSetSpecialEffectY(missile1,y1)
call BlzSetSpecialEffectHeight(missile1,z - 10.00)
if b then
set sfx = AddSpecialEffect(ART_SFX,x1,y1)
call BlzSetSpecialEffectScale(sfx,0.5)
call DestroyEffect(sfx)
endif
set x2 = missile.x + offset * Cos(missile.angle + 1.5707)
set y2 = missile.y + offset * Sin(missile.angle + 1.5707)
call BlzSetSpecialEffectX(missile2,x2)
call BlzSetSpecialEffectY(missile2,y2)
call BlzSetSpecialEffectHeight(missile2,z - 10.00)
if b then
set sfx = AddSpecialEffect(ART_SFX,x2,y2)
call BlzSetSpecialEffectScale(sfx,0.5)
call DestroyEffect(sfx)
endif
if not returning then
call LineSegment.EnumUnits(g,x1,y1,x2,y2,50.00)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) and not IsUnitInGroup(temp,damaged) then
call GroupAddUnit(damaged,temp)
call CodeDamage.Damage(missile.source,temp,missile.damage,udg_DamageTypePhysicalAoe,"",0,0)
if AIEB.activated and IsUnitType(temp,UNIT_TYPE_HERO) and AICounter == 0.00 then
set AICounter = 0.15625
endif
endif
endloop
endif
set sfx = null
return false
endmethod
private static method onFinish takes Missile missile returns boolean
local thistype this = missile
local integer tlvl
set time = 0
set AIEB.earthenAxe = 0
call SetUnitData(missile.source,"ES_casted",0)
if returning then
set tlvl = GetUnitAbilityLevel(missile.source,'EBA2')
if tlvl != 0 then
call DestroyEffect(AddSpecialEffectTarget(Tremors_CAST_SFX,missile.source,"overhead"))
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
call UnitAddBuff(missile.source,missile.source,Tremors_BUFF_DURATION,Tremors.buff,tlvl,1)
else
call UnitAddBuff(missile.source,missile.source,Tremors_BUFF_DURATION,Tremors.buff,tlvl,0)
endif
endif
else
call BlzUnitDisableAbility(missile.source,EXTRA_ID,true,true)
call BlzUnitHideAbility(missile.source,SPELL_ID,false)
endif
call ReleaseGroup(g)
call ReleaseGroup(damaged)
call BlzSetSpecialEffectTimeScale(missile1,1)
call BlzSetSpecialEffectTimeScale(missile2,1)
call DestroyEffect(missile1)
call DestroyEffect(missile2)
set missile1 = null
set missile2 = null
set g = null
set damaged = null
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, real xt, real yt, integer lvl returns Missile
local real dist = DIST_BASE
local integer ulvl = GetUpgradeSkillLevel(source,UPGRADE_ID)
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real a = Angle(xs,ys,xt,yt)
local effect sfx
local Missile missile
if ulvl != 0 then
set dist = dist + GetDistanceBonus(ulvl)
endif
set missile = Missile.createXYZ(xs,ys,0.00,xs + dist * Cos(a),ys + dist * Sin(a),0)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.speed = 20.00
set missile.model = ""
set missile.level = lvl
set missile.damage = GetDamage(lvl)
call BlzUnitDisableAbility(source,EXTRA_ID,false,false)
call BlzUnitHideAbility(missile.source,SPELL_ID,true)
set sfx = AddSpecialEffect(MISSILE_SFX,xs + 100.00 * Cos(a - 1.5707),ys + 100.00 * Sin(a - 1.5707))
call BlzSetSpecialEffectScale(sfx,1.1)
set EarthenSteelMissile[missile].missile1 = sfx
set sfx = AddSpecialEffect(MISSILE_SFX,xs + 100.00 * Cos(a + 1.5707),ys + 100.00 * Sin(a + 1.5707))
call BlzSetSpecialEffectScale(sfx,1.1)
set EarthenSteelMissile[missile].missile2 = sfx
set EarthenSteelMissile[missile].g = NewGroup()
set EarthenSteelMissile[missile].damaged = NewGroup()
set EarthenSteelMissile[missile].returning = false
set EarthenSteelMissile[missile].offset = 100.00
set EarthenSteelMissile[missile].AICounter = 0.00
set AIEB.earthenAxe = missile
call SetUnitData(source,"ES_casted",missile)
set sfx = null
call EarthenSteelMissile.launch(missile)
return missile
endfunction
private function onCastExtra takes nothing returns nothing
local unit u = GetOrderedUnit()
local Missile m
if GetIssuedOrderId() == ORDER_manashieldon then
set m = GetUnitData(u,"ES_casted")
if m != 0 then
call IssueImmediateOrderById(u,ORDER_manashieldoff)
call EarthenSteelMissile.Return(m)
endif
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local trigger t
if GetLearnedSkillLevel() == 1 then
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t,function onCastExtra)
call UnitAddAbility(u,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
call BlzUnitDisableAbility(u,EXTRA_ID,true,true)
set t = null
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call SetupMissile(u,GetSpellTargetX(),GetSpellTargetY(),GetUnitAbilityLevel(u,SPELL_ID))
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Earthbinder_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Tremors initializer init
globals
private constant integer SPELL_ID = 'EBA2'
private constant integer UPGRADE_ID = 'EBI2'
private constant real DAMAGE_BASE = 40.00
private constant real DAMAGE_LEVEL = 20.00
public constant real BUFF_DURATION = 5.00
private constant real SLOW = 0.45
private constant real AREA_OF_EFFECT = 250.00
private constant real SLOW_DURATION = 1.0
private constant real UP_AOE = 25.00
private constant real SUP_SLOW = 2.00
private constant string AREA_SFX = "war3mapImported\\EpiPulse_1_4.mdx"
public constant string CAST_SFX = "war3mapImported\\SandWaveDamage.mdx"
endglobals
private function GetDamage takes integer lvl returns real
if lvl == 0 then
return 0.00
endif
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetAoe takes integer ulvl returns real
if ulvl == 0 then
return AREA_OF_EFFECT
endif
return AREA_OF_EFFECT + UP_AOE + UP_AOE * ulvl
endfunction
struct TremorsSlow extends array
Movespeed ms
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,75,0,true)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-SLOW,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-75,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A09F'
set BUFF_DATA.BuffID = 'B03H'
set BUFF_DATA.Name = "Tremors Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Tremors extends array
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A09B'
set BUFF_DATA.BuffID = 'B03E'
set BUFF_DATA.Name = "Tremors"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
function Tremor takes unit u, real x, real y, integer op, real a, integer dd returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local real dmg = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
local real aoe = GetAoe(GetUpgradeSkillLevel(u,UPGRADE_ID))
local effect sfx = AddSpecialEffect(AREA_SFX,x,y)
local real sd = SLOW_DURATION
local unit temp
if op == 3 then
call BlzSetSpecialEffectScale(sfx,1.20)
set dmg = a
else
call BlzSetSpecialEffectScale(sfx,0.70)
endif
call DestroyEffect(sfx)
if dd == 1 then
set dmg = dmg * 2
endif
if IsUpgradeSuperior(u,UPGRADE_ID) and op != 1 then
set sd = sd + SUP_SLOW
endif
call GroupEnumUnitsInRange(g,x,y,aoe,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call UnitAddBuff(temp,u,sd,TremorsSlow.buff,0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set sfx = null
endfunction
private function onDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType == udg_DamageTypeAttack and not data.isMiss and data.allowOrbs then
set b = GetUnitBuff(data.source,Tremors.buff)
if b != 0 then
call Tremor(data.source,GetUnitX(data.target),GetUnitY(data.target),1,0,b.int)
call UnitRemoveBuff(data.source,Tremors.buff)
endif
endif
endfunction
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call DestroyEffect(AddSpecialEffectTarget(CAST_SFX,u,"overhead"))
call UnitAddBuff(u,u,BUFF_DURATION,Tremors.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Tremors.Initialize()
call TremorsSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDamage(Filter(function onDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Earthbinder_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A09B',PRELOAD_SECOND)
call PreloadGen.Add('A09F',PRELOAD_SECOND)
endfunction
endscope
scope SummonGolems initializer init
globals
private constant integer SPELL_ID = 'EBA3'
private constant integer UPGRADE_ID = 'EBI3'
private constant integer EXTRA_ID = 'A09C'
private constant integer GOLEMS_ID = 'n00S'
private constant real HERO_HP_BASE = 0.08
private constant real HERO_HP_LEVEL = 0.02
private constant real MAXHP_SHIELD_BASE = 0.60
private constant real MAXHP_SHIELD_LVL = 0.10
private constant real SHIELD_DURATION = 7.00
private constant real SUP_GOLEM_HP = 0.04
private constant string MISSILE_SFX = "war3mapImported\\Asteroid0.mdx"
private constant string SUMMON_SFX = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl"
endglobals
private function GetHeroHpBonus takes integer lvl returns real
return HERO_HP_BASE + HERO_HP_LEVEL * lvl
endfunction
private function GetUpHp takes integer ulvl returns integer
return 50 + 50 * ulvl
endfunction
private function GetMaxHpShield takes integer lvl returns real
return MAXHP_SHIELD_BASE + MAXHP_SHIELD_LVL * lvl
endfunction
struct PrimalFormMissile extends array
private static method onFinish takes Missile missile returns boolean
if missile.data == 1 then
call Tremor.evaluate(missile.source,missile.x,missile.y,3,missile.damage,0)
set AIEB.lastTremor = false
elseif missile.data == 2 then
set AIEB.lastShield = false
call UnitAddBuff(missile.target,missile.source,SHIELD_DURATION,PrimalShield.buff,missile.level,R2I(missile.damage))
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, unit golem, real x, real y, integer lvl, real r, integer op returns Missile
local Missile missile
if op == 1 then
set missile = Missile.createXYZ(GetUnitX(golem),GetUnitY(golem),0.00,x,y,0.00)
set missile.arc = 45.00 * bj_DEGTORAD
elseif op == 2 then
set missile = Missile.create(GetUnitX(golem),GetUnitY(golem),75.00,AngleBetweenUnits(golem,target),0,75.00)
set missile.target = target
endif
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.speed = 15.00
set missile.model = MISSILE_SFX
set missile.scale = 1.0
set missile.level = lvl
set missile.damage = r
set missile.data = op
call PrimalFormMissile.launch(missile)
return missile
endfunction
struct PrimalShield extends array
real life
boolean st
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if st then
set st = false
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set life = b.int
if GetHeroMasteryType(b.owner) == 1 then
set st = true
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A09D'
set BUFF_DATA.BuffID = 'B03F'
set BUFF_DATA.Name = "PrimalShield"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct SummonGolem extends array
integer hploss
public static method onRemove takes Buff b returns nothing
local Ability a
if b.int == 1 then
call SetUnitData(b.owner,"Golem1",0)
set AIEB.golem1 = null
else
call SetUnitData(b.owner,"Golem2",0)
set AIEB.golem2 = null
endif
if GetHeroMasteryType(b.owner) == 3 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,b.owner)
if a != 0 then
call a.addTempFlatCooldown(-5.0)
endif
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
local real hpp = GetHeroHpBonus(b.level)
local real hpb = GetUnitState(b.owner,UNIT_STATE_MAX_LIFE)
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
set hpp = hpp + SUP_GOLEM_HP
endif
set hpb = hpb * hpp
if ulvl != 0 then
set hpb = hpb + I2R(GetUpHp(ulvl))
endif
call BonusStruct.Add(BONUS_TYPE_HP,b.target,R2I(hpb),0,true)
if b.int == 1 then
call SetUnitData(b.owner,"Golem1",GetUnitUserData(b.target))
set AIEB.golem1 = b.target
else
call SetUnitData(b.owner,"Golem2",GetUnitUserData(b.target))
set AIEB.golem2 = b.target
endif
call UnitAddAbility(b.target,'ASMI')
call UnitMakeAbilityPermanent(b.target,true,'ASMI')
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Summon Golem"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
public function onCast2 takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl
local unit h
local real x
local real y
local real r
local Buff b
set b = GetUnitBuff(u,SummonGolem.buff)
set h = b.owner
set lvl = b.level
if IsUnitEnemy(t,GetOwningPlayer(u)) or t == null then
//tremors
if t == null then
set x = GetSpellTargetX()
set y = GetSpellTargetY()
else
set x = GetUnitX(t)
set y = GetUnitY(t)
endif
set r = GetUnitState(u,UNIT_STATE_MAX_LIFE) * (0.20 + 0.10 * lvl)
call SetupMissile(h,null,u,x,y,lvl,r,1)
else
//shield
set r = GetUnitState(u,UNIT_STATE_MAX_LIFE) * GetMaxHpShield(lvl)
call SetupMissile(h,t,u,0,0,lvl,r,2)
endif
call KillUnit(u)
set u = null
set h = null
set t = null
endfunction
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real a = GetUnitFacing(u)
local player p = GetOwningPlayer(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real xc = x + 150 * Cos((a+90) * bj_DEGTORAD)
local real yc = y + 150 * Sin((a+90) * bj_DEGTORAD)
local unit dummy
local integer idg
local unit ga
set idg = GetUnitData(u,"Golem1")
if idg != 0 then
set ga = Index[idg].u
call UnitRemoveBuff(ga,SummonGolem.buff)
call KillUnit(ga)
endif
set idg = GetUnitData(u,"Golem2")
if idg != 0 then
set ga = Index[idg].u
call UnitRemoveBuff(ga,SummonGolem.buff)
call KillUnit(ga)
endif
set dummy = CreateUnit(p,GOLEMS_ID,xc,yc,a)
call DestroyEffect(AddSpecialEffect(SUMMON_SFX,xc,yc))
call SetUnitAnimation(dummy,"birth")
call UnitAddBuff(dummy,u,999999,SummonGolem.buff,lvl,1)
set xc = x + 150 * Cos((a-90) * bj_DEGTORAD)
set yc = y + 150 * Sin((a-90) * bj_DEGTORAD)
set dummy = CreateUnit(p,GOLEMS_ID,xc,yc,a)
call DestroyEffect(AddSpecialEffect(SUMMON_SFX,xc,yc))
call SetUnitAnimation(dummy,"birth")
call UnitAddBuff(dummy,u,999999,SummonGolem.buff,lvl,2)
set u = null
set dummy = null
set p = null
set ga = null
endfunction
private function preDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if not data.isAbsorbed and data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,PrimalShield.buff).buffAllocIndex
if b != 0 then
if GetHeroMasteryType(b.owner) == 1 then
set data.notCritical = true
endif
endif
endif
endfunction
private function postDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local PrimalShield b
if not data.isAbsorbed and data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,PrimalShield.buff).buffAllocIndex
if b != 0 then
set b.life = b.life - data.damageMod
if b.life < 0 then
if b.life <= -1 then
set data.damageMod = b.life * -1
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
set b.life = 0
call UnitRemoveBuff(data.target,PrimalShield.buff)
else
set data.isAbsorbed = true
set data.damageMod = 0
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SummonGolem.Initialize()
call PrimalShield.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCast2)
call DamageEvent.RegisterPreCalculation(Filter(function preDmg))
call DamageEvent.RegisterPostCalculation(Filter(function postDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Earthbinder_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A09D',PRELOAD_SECOND)
endfunction
endscope
scope IronConsistency initializer init
globals
private constant integer SPELL_ID = 'EBA4'
private constant integer UPGRADE_ID = 'EBI4'
private constant integer HP_BASE = 200
private constant integer HP_LEVEL = 100
private constant integer ARMOR_BASE = 2
private constant integer ARMOR_LVL = 2
private constant integer DMG_BASE = 30
private constant integer DMG_LVL = 10
private constant real BUFF_DURATION = 20
private constant string TARGET_SFX = "war3mapImported\\SandExplosion.mdx"
endglobals
private function GetHp takes integer lvl returns integer
return HP_BASE + HP_LEVEL * lvl
endfunction
private function GetArmor takes integer lvl returns integer
return ARMOR_BASE + ARMOR_LVL * lvl
endfunction
private function GetDamage takes integer lvl returns integer
return DMG_BASE + DMG_LVL * lvl
endfunction
struct IronConsistency extends array
integer hp
integer ar
integer dmg
integer as
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_HP,b.target,-hp,0,true)
if b.int == 1 then
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-ar,0,true)
else
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endif
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
set as = 0
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,b.target,"origin"))
if b.int == 1 then
set hp = GetHp(b.level)
set ar = GetArmor(b.level)
set dmg = 0
call BonusStruct.Add(BONUS_TYPE_HP,b.target,hp,0,true)
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,ar,0,true)
else
set hp = GetHp(b.level) / 2
set dmg = GetDamage(b.level)
set ar = 0
call BonusStruct.Add(BONUS_TYPE_HP,b.target,hp,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endif
if GetHeroMasteryType(b.owner) == 2 then
set as = 80
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A09E'
set BUFF_DATA.BuffID = 'B03G'
set BUFF_DATA.Name = "Iron Consistency"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer g1id = GetUnitData(u,"Golem1")
local integer g2id = GetUnitData(u,"Golem2")
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real bd = BUFF_DURATION
local unit golem
call UnitAddBuff(u,u,bd,IronConsistency.buff,lvl,1)
if g1id != 0 then
set golem = GetUnitByIndex(g1id)
call UnitAddBuff(golem,u,bd,IronConsistency.buff,lvl,2)
endif
if g2id != 0 then
set golem = GetUnitByIndex(g2id)
call UnitAddBuff(golem,u,bd,IronConsistency.buff,lvl,2)
endif
set u = null
set golem = null
endfunction
private function OnEnterCombat takes nothing returns nothing
local unit u = GetEventCombatEnterUnit()
local Buff b = GetUnitBuff(u,IronConsistency.buff)
if b!= 0 then
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
call b.pause(true)
endif
endif
set u = null
endfunction
private function OnLeaveCombat takes nothing returns nothing
local unit u = GetEventCombatLeaveUnit()
local Buff b = GetUnitBuff(u,IronConsistency.buff)
if b!= 0 then
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
call b.pause(false)
endif
endif
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID then
call RegisterCombatEvent(function OnEnterCombat,EVENT_UNIT_ENTER_COMBAT)
call RegisterCombatEvent(function OnLeaveCombat,EVENT_UNIT_LEAVE_COMBAT)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call IronConsistency.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Earthbinder_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A09E',PRELOAD_SECOND)
endfunction
endscope
library GryphonRider initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HGR1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'GRI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Stardust"
set up.Text = "Increases |c00b4b4b4Stellar Strike|r slow duration."
set up.SupText = "Enemy heroes hit by |c00b4b4b4Stellar Strike|r gives double bonus |c00ffff95Attack Speed|r."
set up.LevelData1 = "+1s Duration"
set up.LevelData2 = "+2s Duration"
set up.LevelData3 = "+3s Duration"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNManaRecharge.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'GRI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Iron Fortitude"
set up.Text = "Increases |c00b4b4b4Iron Will|r duration"
set up.SupText = "|c00b4b4b4Iron Will|r will release the current level of |c00b4b4b4Storm Hammers|r when it absorbs damage but deals only 40% of damage."
set up.LevelData1 = "+1s Duration"
set up.LevelData2 = "+2s Duration"
set up.LevelData3 = "+3s Duration"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNDevotion.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'GRI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Thunder Attacks"
set up.Text = "Increases |c00b4b4b4Storm Hammers|r damage."
set up.SupText = "Increases |c00b4b4b4Storm Hammers|r jumps by 2 and AoE by 200."
set up.LevelData1 = "+25 Damage"
set up.LevelData2 = "+50 Damage"
set up.LevelData3 = "+75 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNHealingWave.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'GRI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Master of the Skies"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HGR1'
set d.Name = "Gryphon Rider"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNGryphonRider.blp"
set d.WinAni = "attack"
set d.Block = 10
set d.Evasion = 30
set d.Resistance = 45
set d.LifeRegen = 1.00
set d.ManaRegen = 1.00
set d.Armor = 6
set d.AttackRange = 450
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'GRA1'
set d.HeroAbility2 = 'GRA2'
set d.HeroAbility3 = 'GRA3'
set d.HeroAbility4 = 'GRA4'
set d.ChooseIconID = 'c025'
set d.ChooseDummy = 'dh25'
set d.spellDamageLevel = 7
set d.attackDamageLevel = 7
set d.healingLevel = 0
set d.survivavilityLevel = 4
set d.movementLevel = 5
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_HUMAN
set d.InfoID = 'HGRI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope StellarStrike initializer init
globals
private constant integer SPELL_ID = 'GRA1'
private constant integer UPGRADE_ID = 'GRI1'
private constant real DAMAGE_BASE = 80.00
private constant real DAMAGE_LEVEL = 40.00
private constant integer AS_BONUS = 6
private constant integer AS_BONUS_LVL = 1
private constant real SLOW_DURATION = 2.00
private constant real DURATION = 7.00
private constant real SLOW = 0.50
private constant real AREA = 230.00
private constant real MA_AREA = 500.00
private constant string HIT_SFX = "war3mapImported\\StormBoltMissileBlue.mdx"
endglobals
private function GetSpeed takes integer lvl returns integer
return AS_BONUS + AS_BONUS_LVL * lvl
endfunction
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct StellarStrike extends array
integer as
integer asb
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set asb = GetSpeed(b.level)
set as = asb * b.int
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AO'
set BUFF_DATA.BuffID = 'B03S'
set BUFF_DATA.Name = "Stellar Strike"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct StellarStrikeSlow extends array
Movespeed ms
integer as
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,50,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-SLOW,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-50,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AN'
set BUFF_DATA.BuffID = 'B03I'
set BUFF_DATA.Name = "Stellar Strike Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local real h = tb.real[4]
local effect sfx = tb.effect[5]
local unit u
local group g
local player p
local unit temp
local real dmg
local integer lvl
local integer c = 0
local real d
local boolean b
set h = h - tb.real[6]
call BlzSetSpecialEffectHeight(sfx,h)
set tb.real[4] = h
if h <= 100 then
set u = tb.unit[0]
set g = NewGroup()
set p = GetOwningPlayer(u)
set lvl = tb.integer[3]
set dmg = GetDamage(lvl)
call GroupEnumUnitsInRange(g,tb.real[1],tb.real[2],AREA,null)
set b = IsUpgradeSuperior(u,UPGRADE_ID)
set d = SLOW_DURATION + 1 * GetUpgradeSkillLevel(u,UPGRADE_ID)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call UnitAddBuff(temp,u,d,StellarStrikeSlow.buff,0,0)
if b and IsUnitType(temp,UNIT_TYPE_HERO) then
set c = c + 2
else
set c = c + 1
endif
endif
endloop
if c != 0 then
if GetHeroMasteryType(u) == 2 then
call GroupClear(g)
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),MA_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ALLIED(temp,p) then
call UnitAddBuff(temp,u,DURATION,StellarStrike.buff,lvl,c)
endif
endloop
else
call UnitAddBuff(u,u,DURATION,StellarStrike.buff,lvl,c)
endif
endif
call DestroyEffect(sfx)
set sfx = AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl",tb.real[1],tb.real[2])
call BlzSetSpecialEffectScale(sfx,1.3)
call ReleaseGroup(g)
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set g = null
set p = null
set u = null
endif
set t = null
set sfx = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local effect sfx
local real z = GetLocZ(x,y)
set tb.unit[0] = u
set tb.real[1] = x
set tb.real[2] = y
set tb.integer[3] = lvl
set tb.real[4] = 1000 + z
set tb.real[6] = tb.real[4] / 16
set sfx = AddSpecialEffect(HIT_SFX,x,y)
call BlzSetSpecialEffectScale(sfx,3.5)
call BlzSetSpecialEffectPitch(sfx,90 * bj_DEGTORAD)
call BlzSetSpecialEffectHeight(sfx,1000 + z)
set tb.effect[5] = sfx
call TimerStart(t,0.03125,true,function Callback)
set sfx = null
set t = null
set u = null
set sfx = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call StellarStrike.Initialize()
call StellarStrikeSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GryphonRider_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(HIT_SFX)
endfunction
endscope
scope IronWill initializer init
globals
private constant integer SPELL_ID = 'GRA2'
private constant integer UPGRADE_ID = 'GRI2'
private constant integer COUNT_BASE = 2
private constant integer COUNT_LEVEL = 2
private constant real INC_BASE = 0.02
private constant real INC_LVL = 0.005
private constant real INC_DURATION = 5.00
private constant real DURATION = 5.00
private constant integer MA_COUNT = 2
private constant string SHIELD_SFX = "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldTarget.mdl"
private constant string BONUS_SFX = "war3mapImported\\s_MagicLightning Aura.mdx"
endglobals
private function GetInc takes integer lvl returns real
return INC_BASE + INC_LVL * lvl
endfunction
private function GetCount takes integer lvl returns integer
return COUNT_BASE + COUNT_LEVEL * lvl
endfunction
struct IronWill extends array
integer count
real inc
real incharge
boolean sup
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Ability a
call DestroyEffect(sfx)
set sfx = null
if GetUnitAbilityLevel(b.target,SPELL_ID) != 0 then
set a = GetHeroAbilityById(b.target,SPELL_ID)
call a.abilityNumber.setValue(0)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Ability a
set count = GetCount(b.level)
set incharge = GetInc(b.level)
set inc = incharge * count
set sfx = AddSpecialEffectTarget(SHIELD_SFX,b.target,"chest")
set sup = IsUpgradeSuperior(b.owner,UPGRADE_ID)
if GetUnitAbilityLevel(b.target,SPELL_ID) != 0 then
set a = GetHeroAbilityById(b.target,SPELL_ID)
call a.abilityNumber.setValue(count)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AP'
set BUFF_DATA.BuffID = 'B03T'
set BUFF_DATA.Name = "Iron Will"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onPreDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local IronWill w
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.source,IronWill.buff)
if b != 0 then
set w = b.buffAllocIndex
set data.mult = data.mult + w.inc
endif
endif
endfunction
private function onPostDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local IronWill w
local Ability a
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if not data.isAbsorbed and data.damageMod > 0 then
set b = GetUnitBuff(data.target,IronWill.buff)
if b != 0 then
set w = b.buffAllocIndex
set data.damageMod = 0
set data.isAbsorbed = true
set w.count = w.count - 1
if GetUnitAbilityLevel(data.target,SPELL_ID) != 0 then
set a = GetHeroAbilityById(data.target,SPELL_ID)
call a.abilityNumber.setValue(w.count)
endif
if w.sup then
call CastChain.evaluate(data.target,data.source,b.owner,true)
endif
set w.inc = w.incharge * w.count
if w.count == 0 then
call UnitRemoveBuff(data.target,IronWill.buff)
endif
endif
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local real d = DURATION + GetUpgradeSkillLevel(u,UPGRADE_ID)
local boolean m = GetHeroMasteryType(u) == 1
if u != t and m then
call UnitAddBuff(u,u,d,IronWill.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
endif
call UnitAddBuff(t,u,d,IronWill.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set t = null
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local Ability a
if GetLearnedSkillLevel() == 1 then
set a = GetHeroAbilityById(u,SPELL_ID)
set a.abilityNumber = AbilityNumber.create(a.objectID,u)
call a.abilityNumber.setValue(0)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call IronWill.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPostCalculation(Filter(function onPostDmg))
call DamageEvent.RegisterPreCalculation(Filter(function onPreDmg))
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GryphonRider_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(SHIELD_SFX)
call Preload(BONUS_SFX)
endfunction
endscope
scope StormHammers initializer init
globals
private constant integer SPELL_ID = 'GRA3'
private constant integer UPGRADE_ID = 'GRI3'
private constant integer DUMMY_ID = 'A0AK'
private constant real DAMAGE_BASE = 75.00
private constant real DAMAGE_LVL = 25.00
private constant integer ATTACK_COUNT = 6
private constant real DURATION = 5.00
private constant real UP_DMG = 25.00
private constant real MA_DURATION = 4.00
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LVL * lvl
endfunction
function CastChain takes unit source, unit target, unit owner, boolean reduced returns boolean
local unit d = Ability.GetUnitAbilityByID(SPELL_ID,owner).auxDummy
local boolean b
call SetUnitX(d,GetUnitX(source))
call SetUnitY(d,GetUnitY(source))
call UnitRemoveAbility(d,DUMMY_ID)
call UnitAddAbility(d,DUMMY_ID)
if IsUpgradeSuperior(owner,UPGRADE_ID) then
call SetUnitAbilityLevel(d,DUMMY_ID,2)
endif
if reduced then
call SetUnitUserData(d,1)
else
call SetUnitUserData(d,0)
endif
set b = IssueTargetOrderById(d,ORDER_chainlightning,target)
set d = null
return b
endfunction
struct StormHammers extends array
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AQ'
set BUFF_DATA.BuffID = 'B03U'
set BUFF_DATA.Name = "Storm Hammers"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call SetUnitData(u,"SHc",0)
call UnitAddBuff(u,u,DURATION,StormHammers.buff,0,0)
set u = null
endfunction
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local unit u
local real d
if GetUnitAbilityLevel(data.source,DUMMY_ID) != 0 then
set u = GetUnitByIndex(GetDummyData(data.source,"caster"))
set d = GetDamage(GetUnitAbilityLevel(u,SPELL_ID)) + UP_DMG * GetUpgradeSkillLevel(u,UPGRADE_ID)
if GetUnitUserData(data.source) == 1 then
set d = d * 0.40
endif
call CodeDamage.Damage(u,data.target,d,udg_DamageTypeMagicAoe,"",0,0)
set u = null
endif
endfunction
private function onDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer c
local boolean sw
local Buff b
local Ability a
if data.dmgType == udg_DamageTypeAttack and not data.isMiss then
if GetUnitAbilityLevel(data.source,SPELL_ID) != 0 then
set b = GetUnitBuff(data.source,StormHammers.buff)
if b != 0 then
call CastChain(data.source,data.target,data.source,false)
if GetHeroMasteryType(data.source) == 3 then
call b.restart()
endif
else
set c = GetUnitData(data.source,"SHc")
set c = c + 1
set a = GetHeroAbilityById(data.source,SPELL_ID)
set sw = true
if c == 6 then
set c = 0
set sw = CastChain(data.source,data.target,data.source,false)
endif
if sw then
call a.abilityNumber.setValue(c)
call SetUnitData(data.source,"SHc",c)
endif
endif
endif
endif
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local unit d
local Ability a
if GetLearnedSkillLevel() == 1 then
set a = GetHeroAbilityById(u,SPELL_ID)
set d = a.auxDummy
call UnitAddAbility(d,DUMMY_ID)
call MakeFly(d)
call SetDummyData(d,"caster",GetUnitUserData(u))
call SetUnitFlyHeight(d,270,0)
set a.abilityNumber = AbilityNumber.create(a.objectID,u)
call a.abilityNumber.setValue(0)
set d = null
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.activationType = ACTIVATION_TYPE_TARGET
set d.UseAuxDummy = true
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call StormHammers.Initialize()
call DamageEvent.RegisterDamage(Filter(function onDmg))
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GryphonRider_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(DUMMY_ID,PRELOAD_SECOND)
endfunction
endscope
scope SkyDive initializer init
globals
private constant integer SPELL_ID = 'GRA4'
private constant integer UPGRADE_ID = 'GRI4'
private constant integer EXTRA1_ID = 'A0AL'
private constant real DAMAGE_BASE = 150.00
private constant real MISSILE_DISTANCE = 1000.00
private constant real MISSILE_DELAY = 0.75
private constant real STUN_DURATION = 1.75
private constant real UP_CD = -20.00
private constant string MISSILE_SFX = "war3mapImported\\Storm Bolt.mdx"
private constant string CENTER_SFX = "Abilities\\Spells\\Other\\Aneu\\AneuCaster.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE * lvl
endfunction
struct HammerMissile extends array
real time
private static method onPeriod takes Missile missile returns boolean
local thistype this = missile
if missile.speed == 0 then
set time = time + 0.03125
if time >= MISSILE_DELAY then
set missile.speed = 20.00
endif
endif
return false
endmethod
private static method onFinish takes Missile missile returns boolean
local DamageOptions op
if not TriggerSpellNegation(missile.target) then
set op = DamageOptions.create()
set op.allowOrbs = true
set op.ignoreAllArmor = true
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeAttack,"",0,op)
call Status.Add(STATUS_STUN,missile.target,STUN_DURATION,Status_EFFECT[STATUS_STUN])
call DestroyEffect(AddSpecialEffectTarget(MISSILE_SFX,missile.target,"chest"))
endif
if TriggerSpellReflection(missile.target) then
call SkyDive_SetupMissile.evaluate(missile.target,missile.source,missile.level)
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),150.00,AngleBetweenUnits(source,target),0,75.00)
set missile.target = target
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl)
set missile.speed = 0.00
set missile.model = MISSILE_SFX
set missile.scale = 1.0
set HammerMissile[missile].time = 0
call HammerMissile.launch(missile)
return missile
endfunction
struct SkyDive extends array
real width
real tall
real xCenter
real yCenter
real cos
real sin
real ang
real angle
integer steps
integer lvl
group affected
unit dummy
effect sfx
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local real alpha = ang * bj_DEGTORAD
local real cosalpha = Cos(alpha)
local real sinalpha = Sin(alpha)
local real xoff = (width * cosalpha * cos - tall * sinalpha * sin) + xCenter
local real yoff = (width * cosalpha * sin + tall * sinalpha * cos) + yCenter
local group g
local player p
local unit temp
set ang = ang + 4
call SetUnitAnimationByIndex(b.target,4)
call SetUnitFacing(b.target,Angle(x,y,xoff,yoff) * bj_RADTODEG)
call SetUnitX(b.target,xoff)
call SetUnitY(b.target,yoff)
call SetUnitX(dummy,xoff)
call SetUnitY(dummy,yoff)
set steps = steps + 1
if ModuloInteger(steps,5) == 0 then
set g = NewGroup()
set p = GetOwningPlayer(b.target)
call GroupEnumUnitsInRange(g,xCenter,yCenter,1000.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and IsUnitVisible(temp,p) and not IsUnitInGroup(temp,affected) then
if IsPointInEllipse(xCenter,yCenter,GetUnitX(temp),GetUnitY(temp),800,200,angle) then
call SetupMissile(b.target,temp,lvl)
call GroupAddUnit(affected,temp)
exitwhen true
endif
endif
endloop
call ReleaseGroup(g)
set p = null
set g = null
endif
if steps == 90 or GetUnitData(b.target,"KPJ0") != 0 or GetUnitData(b.target,"KPJ1") != 0 then
set b.removeInside = true
endif
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_UNPATH,b.target)
call Status.Remove(STATUS_UNTURN,b.target)
call UnitRemoveAbility(b.target,'A09O')
call UnitRemoveAbility(b.target,EXTRA1_ID)
call BlzUnitHideAbility(b.target,SPELL_ID,false)
call DestroyEffect(sfx)
call ReleaseGroup(affected)
call RemoveUnit(dummy)
set dummy = null
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Table tb = b.int
local player p = GetOwningPlayer(b.target)
local real degAngle
set angle = tb.real[0]
set degAngle = angle * bj_RADTODEG
set ang = (degAngle + 180) * bj_DEGTORAD
set xCenter = GetUnitX(b.target) + 500 * Cos(angle)
set yCenter = GetUnitY(b.target) + 500 * Sin(angle)
set angle = ang
set cos = Cos(ang)
set sin = Sin(ang)
set width = 500
set tall = 200
set steps = 0
set affected = NewGroup()
set lvl = GetUnitAbilityLevel(b.target,SPELL_ID)
call tb.flush()
call tb.destroy()
set dummy = CreateUnit(p,'h00O',GetUnitX(b.target),GetUnitY(b.target),0)
call SetUnitFlyHeight(dummy,270.00,0)
call Status.Add(STATUS_UNPATH,b.target,0,0)
call Status.Add(STATUS_UNTURN,b.target,0,0)
set sfx = AddSpecialEffect(CENTER_SFX,xCenter,yCenter)
call BlzSetSpecialEffectScale(sfx,2.0)
if Game.LocalPlayer != p then
call BlzSetSpecialEffectScale(sfx,0)
endif
call UnitAddAbility(b.target,'A09O')
call UnitMakeAbilityPermanent(b.target,true,'A09O')
call BlzUnitHideAbility(b.target,SPELL_ID,true)
call UnitAddAbility(b.target,EXTRA1_ID)
call UnitMakeAbilityPermanent(b.target,true,EXTRA1_ID)
set p = null
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Sky Dive"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCastCancel takes nothing returns nothing
local unit u = GetTriggerUnit()
local Buff b = GetUnitBuff(u,SkyDive.buff)
if b != 0 then
call b.remove()
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local Table tb = Table.create()
set tb.real[0] = Angle(GetUnitX(u),GetUnitY(u),GetSpellTargetX(),GetSpellTargetY())
call UnitAddBuff(u,u,99,SkyDive.buff,GetUnitAbilityLevel(u,SPELL_ID),tb)
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID and up.level == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(UP_CD)
endif
endfunction
private function onStatus takes nothing returns nothing
local StatusObject s = EVENT_STATUS
local Buff b = GetUnitBuff(s.target,SkyDive.buff)
if b != 0 and s.status <= 10 and s.status != 3 and s.status != 7 then
call UnitRemoveBuff(s.target,SkyDive.buff)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SkyDive.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA1_ID, function onCastCancel)
call RegisterUnitStatusEvent(function onStatus)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GryphonRider_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
//call PreloadGen.Add(DUMMY_ID,PRELOAD_SECOND)
endfunction
endscope
library DwarfRunner initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HDR1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'DRI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Improved Guns"
set up.Text = "Increases |c00b4b4b4Front Guns|r distance traveled."
set up.SupText = "While |c00b4b4b4Titanium Bullets|r is active deals |c00ee82eePure|r damage."
set up.LevelData1 = "+100 Distance"
set up.LevelData2 = "+200 Distance"
set up.LevelData3 = "+300 Distance"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'DRI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Pocket Fan"
set up.Text = "|c00b4b4b4Overheat|r increases attack speed."
set up.SupText = "Reduce |c00b4b4b4Overheat|r mana cost by 50%."
set up.LevelData1 = "Up to 20% AS"
set up.LevelData2 = "Up to 30% AS"
set up.LevelData3 = "Up to 40% AS"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'DRI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Dwarf Tech"
set up.Text = "|c00b4b4b4Engineering Upgrade|r also adds Int, Str or Agi based on the effect selected."
set up.SupText = "Removes |c00b4b4b4Enginnering Upgrade|r cooldown."
set up.LevelData1 = "+6 Attribute"
set up.LevelData2 = "+12 Attribute"
set up.LevelData3 = "+18 Attribute"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'DRI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Improved Ammo"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HDR1'
set d.Name = "Dwarf Runner"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNDwarfCar.blp"
set d.WinAni = "attack"
set d.Block = 40
set d.Evasion = 10
set d.Resistance = 40
set d.LifeRegen = 0.5
set d.ManaRegen = 1.5
set d.Armor = 2
set d.AttackRange = 500
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'DRA1'
set d.HeroAbility2 = 'DRA2'
set d.HeroAbility3 = 'DRA3'
set d.HeroAbility4 = 'DRA4'
set d.ChooseIconID = 'c028'
set d.ChooseDummy = 'dh28'
set d.spellDamageLevel = 5
set d.attackDamageLevel = 8
set d.healingLevel = 2
set d.survivavilityLevel = 4
set d.movementLevel = 7
set d.crowdControlLevel = 1
set d.HeroFaction = Game.FACTION_HUMAN
set d.InfoID = 'HDRI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope FrontGuns initializer init
globals
private constant integer SPELL_ID = 'DRA1'
private constant integer UPGRADE_ID = 'DRI1'
private constant real DAMAGE_BASE = 60.00
private constant real DAMAGE_LEVEL = 40.00
private constant real AREA_OF_EFFECT = 150.00
private constant real DISTANCE = 500.00
private constant real SLOW = -0.75
private constant real EU_DMG = 30.00
private constant real UP_DIST = 100.00
private constant real SUP_DMG = 100.00
private constant string MISSILE_SFX = "Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl"
private constant string TARGET_SFX = "Abilities\\Weapons\\Rifle\\RifleImpact.mdl"
private constant string IMPACT_SFX = "Abilities\\Weapons\\FlyingMachine\\FlyingMachineImpact.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct FrontGunsSlow extends array
Movespeed ms
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,SLOW,0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0BE'
set BUFF_DATA.BuffID = 'B048'
set BUFF_DATA.Name = "Front Guns"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct FrontGunsMissile extends array
private static method onFinish takes Missile missile returns boolean
call DestroyEffect(AddSpecialEffect(IMPACT_SFX,missile.x,missile.y))
return true
endmethod
private static method onCollide takes Missile missile, unit hit returns boolean
if FILT_UNIT_ENEMY(hit,missile.owner) then
if missile.data == -1 then
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypePure,"",0,0)
else
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypePhysicalAoe,"",0,0)
endif
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,hit,"overhead"))
call UnitAddBuff(hit,missile.source,0.7,FrontGunsSlow.buff,missile.level,0)
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real x, real y, real a, integer op returns Missile
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local real d = DISTANCE + UP_DIST * GetUpgradeSkillLevel(source,UPGRADE_ID)
local real xt
local real yt
local Missile missile
local real ac
local real z = 70.00
if op == 1 then
set ac = a - 1.5707
set x = x + 60.00 * Cos(ac)
set y = y + 60.00 * Sin(ac)
set z = 70.00
elseif op == 3 then
set ac = a + 1.5707
set x = x + 60.00 * Cos(ac)
set y = y + 60.00 * Sin(ac)
set z = 70.00
endif
set xt = x + d * Cos(a)
set yt = y + d * Sin(a)
set missile = Missile.createXYZ(x,y,z,xt,yt,z)
set missile.source = source
set missile.level = lvl
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl)
set missile.speed = 45.00
set missile.model = MISSILE_SFX
set missile.scale = 1.0
if op == 2 then
set missile.collision = AREA_OF_EFFECT
endif
if GetUnitAbilityLevel(source,'A0B9') != 0 then
set missile.damage = missile.damage + EU_DMG * GetUnitAbilityLevel(source,'DRA3')
if IsUpgradeSuperior(source,UPGRADE_ID) then
set missile.data = -1
endif
endif
call FrontGunsMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real a = GetUnitFacing(u) * bj_DEGTORAD
call SetupMissile(u,x,y,a,1)
call SetupMissile(u,x,y,a,2)
call SetupMissile(u,x,y,a,3)
if GetHeroMasteryType(u) == 3 then
call SetupMissile(u,x,y,a+bj_PI,1)
call SetupMissile(u,x,y,a+bj_PI,2)
call SetupMissile(u,x,y,a+bj_PI,3)
//
call SetupMissile(u,x,y,a+bj_PI/2,1)
call SetupMissile(u,x,y,a+bj_PI/2,2)
call SetupMissile(u,x,y,a+bj_PI/2,3)
//
call SetupMissile(u,x,y,a-bj_PI/2,1)
call SetupMissile(u,x,y,a-bj_PI/2,2)
call SetupMissile(u,x,y,a-bj_PI/2,3)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FrontGunsSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DwarfRunner_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope Overheat initializer init
globals
private constant integer SPELL_ID = 'DRA2'
private constant integer UPGRADE_ID = 'DRI2'
private constant integer DAMAGE_BASE = 2
private constant integer DAMAGE_LEVEL = 2
private constant integer MS_BASE = 5
private constant integer MS_LVL = 2
private constant real STUN_DURATION = 2.00
private constant real HEAL_BASE = 15.00
private constant real HEAL_LVL = 15.00
private constant string EXPLOSION_SFX = "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
private constant string COOL_SFX = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
endglobals
private function GetDamagePartial takes integer lvl returns integer
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetMs takes integer lvl returns integer
return MS_BASE + MS_LVL * lvl
endfunction
private function GetHeal takes integer lvl returns real
return HEAL_BASE + HEAL_LVL * lvl
endfunction
struct Overheat extends array
Movespeed ms
integer dmglvl
integer count
integer count2
real time
real interval
boolean run
real manacost
integer as
integer msx
public method update takes Buff b returns nothing
local integer rlvl = GetUnitAbilityLevel(b.target,SPELL_ID)
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
if rlvl != b.level then
set b.level = rlvl
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmglvl * count,0,true)
call ms.destroy()
set msx = GetMs(b.level)
set ms = Movespeed.create(b.target,0,msx * count)
set dmglvl = GetDamagePartial(b.level)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmglvl * count,0,true)
endif
if ulvl != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as * count,0,true)
set as = 1 + 1 * ulvl
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as * count,0,true)
endif
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LoadingBar lb = GetUnitData(b.target,"OHBar")
if count != 0 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmglvl * count,0,true)
endif
call ms.destroy()
if lb != 0 then
call lb.setPercent(0)
call lb.show(false)
endif
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as * count,0,true)
set as = 0
endif
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LoadingBar lb = GetUnitData(b.target,"OHBar")
local real mp
local real heal = 0
local effect sfx
set time = time + 0.10
if time >= interval then
set time = 0.0
if run then
set count2 = count2 + 1
call lb.setPercent(100 * (count * 5 + count2) / 50)
if count2 >= 5 then
set count2 = 0
set mp = GetUnitState(b.target,UNIT_STATE_MANA)
if mp >= manacost and count != 10 then
call UnitRemoveMp(b.target,manacost)
set count = count + 1
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmglvl,0,true)
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endif
call ms.change(0,msx * count)
if count >= 10 then
set run = false
set interval = 0.30
call BlzSetAbilityIcon(SPELL_ID,"ReplaceableTextures\\CommandButtons\\BTNFire.blp")
if GetUnitAbilityLevel(b.target,'A0BA') == 0 then
call DestroyEffect(AddSpecialEffectTarget(EXPLOSION_SFX,b.target,"origin"))
call Status.Add(STATUS_STUN,b.target,STUN_DURATION,Status_EFFECT[STATUS_STUN])
endif
endif
else
set run = false
set interval = 0.30
call BlzSetAbilityIcon(SPELL_ID,"ReplaceableTextures\\CommandButtons\\BTNFire.blp")
endif
endif
else
set count2 = count2 + 1
call lb.setPercent(100 * (count * 5 - count2) / 50)
if count2 >= 5 then
if GetUnitAbilityLevel(b.target,'A0BA') != 0 then
set heal = GetHeal(GetUnitAbilityLevel(b.target,'DRA3'))
if GetHeroMasteryType(b.target) == 1 then
set heal = heal + GetUnitMissingLife(b.target) * 0.01
endif
call CodeDamage.Damage(b.target,b.target,heal,udg_DamageTypeHeal,"",0,0)
set sfx = AddSpecialEffectTarget(COOL_SFX,b.target,"origin")
call BlzSetSpecialEffectScale(sfx,1.2)
call DestroyEffect(sfx)
set sfx = null
endif
set count2 = 0
set count = count - 1
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmglvl,0,true)
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endif
call ms.change(0,msx * count)
if count == 0 then
set b.removeInside = true
endif
endif
endif
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LoadingBar lb = GetUnitData(b.target,"OHBar")
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
call lb.show(true)
set dmglvl = GetDamagePartial(b.level)
set ms = Movespeed.create(b.target,0,0)
set run = true
set manacost = 5 + 5 * b.level
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set manacost = manacost / 2
endif
set count = 0
set count2 = 0
set interval = 0.10
set time = 0.0
set msx = GetMs(b.level)
if ulvl != 0 then
set as = 1 + 1 * ulvl
else
set as = 0
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0BF'
set BUFF_DATA.BuffID = 'B049'
set BUFF_DATA.Name = "Overheat"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Period = 0.10
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local LoadingBar lb
local Buff b = GetUnitBuff(u,Overheat.buff)
if GetLearnedSkillLevel() == 1 then
set lb = LoadingBar.create()
set lb.target = u
set lb.zOffset = 180
set lb.xOffset = -20
call lb.setSize(1.4)
call lb.show(true)
set lb.active = true
call lb.setColorPlayer(Player(12))
call SetUnitData(u,"OHBar",lb)
if GetPlayerController(GetTriggerPlayer()) == MAP_CONTROL_COMPUTER then
call BlzUnitDisableAbility(u,SPELL_ID,true,false)
endif
endif
if b != 0 then
call Overheat[b.buffAllocIndex].update(b)
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Buff b = GetUnitBuff(u,Overheat.buff)
local Overheat ob
local integer rflvl
local group g
local unit temp
local player p
local real st
local real x
local real y
if b == 0 then
call BlzSetAbilityIcon(SPELL_ID,"ReplaceableTextures\\CommandButtons\\BTNCancel.blp")
call UnitAddBuff(u,u,9999,Overheat.buff,lvl,0)
else
set ob = Overheat[b.buffAllocIndex]
if ob.run then
call BlzSetAbilityIcon(SPELL_ID,"ReplaceableTextures\\CommandButtons\\BTNFire.blp")
set ob.run = false
set ob.count2 = 0
set ob.interval = 0.30
else
if true then
call BlzSetAbilityIcon(SPELL_ID,"ReplaceableTextures\\CommandButtons\\BTNCancel.blp")
set ob.run = true
//set ob.count2 = 0
set ob.interval = 0.10
endif
endif
endif
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local Buff b
if up.upID == UPGRADE_ID then
set b = GetUnitBuff(up.ownerHero.hero,Overheat.buff)
if b != 0 then
call Overheat[b.buffAllocIndex].update(b)
endif
endif
if up.upID == 'DRI3' and up.isSuperior then
set a = Ability.GetUnitAbilityByID('DRA3',up.ownerHero.hero)
call a.addFlatCooldown(-1)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Overheat.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DwarfRunner_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope EngineeringUpgrade initializer init
globals
private constant integer SPELL_ID = 'DRA3'
private constant integer UPGRADE_ID = 'DRI3'
private constant integer EXTRA_ID1 = 'A0B9'
private constant integer EXTRA_ID2 = 'A0BA'
private constant integer EXTRA_ID3 = 'A0BB'
private constant real UP_DMG = 40.00
private constant real SUP_DIST = 400.00
private constant string CHANGE_SFX = "war3mapImported\\Bullet.mdx"
endglobals
private function onOrder takes nothing returns nothing
local unit u = GetOrderedUnit()
local integer i
local integer ulvl
if GetIssuedOrderId() == ORDER_manashieldon then
call UnitRemoveAbility(u,'B03K')
set i = GetUnitData(u,"EU_OP") + 1
set ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
if i == 2 then
call UnitRemoveAbility(u,EXTRA_ID1)
call UnitAddAbility(u,EXTRA_ID2)
call SetUnitAbilityLevel(u,EXTRA_ID2,ulvl + 1)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID2)
elseif i == 3 then
call UnitRemoveAbility(u,EXTRA_ID2)
call UnitAddAbility(u,EXTRA_ID3)
call SetUnitAbilityLevel(u,EXTRA_ID3,ulvl + 1)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID3)
if GetHeroMasteryType(u) == 2 then
call SetUnitData(u,"RF_AttackRate",60)
call BlzSetUnitAttackCooldown(u,1.8 - (0.10 + 0.10 * GetUnitAbilityLevel(u,SPELL_ID)) * 2,0)
else
call SetUnitData(u,"RF_AttackRate",30)
call BlzSetUnitAttackCooldown(u,1.8 - (0.10 + 0.10 * GetUnitAbilityLevel(u,SPELL_ID)),0)
endif
else
call UnitRemoveAbility(u,EXTRA_ID3)
call UnitAddAbility(u,EXTRA_ID1)
call SetUnitAbilityLevel(u,EXTRA_ID1,ulvl + 1)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID1)
call BlzSetUnitAttackCooldown(u,1.8,0)
set i = 1
endif
call SetUnitData(u,"EU_OP",i)
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local trigger t
if GetLearnedSkillLevel() == 1 then
call UnitAddAbility(u,EXTRA_ID1)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID1)
call SetUnitData(u,"EU_OP",1)
if GetPlayerController(GetTriggerPlayer()) != MAP_CONTROL_COMPUTER then
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t,function onOrder)
set t = null
endif
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DwarfRunner_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(EXTRA_ID1,PRELOAD_SECOND)
call PreloadGen.Add(EXTRA_ID2,PRELOAD_SECOND)
call PreloadGen.Add(EXTRA_ID3,PRELOAD_SECOND)
endfunction
endscope
scope APCanon initializer init
globals
private constant integer SPELL_ID = 'DRA4'
private constant integer UPGRADE_ID = 'DRI4'
private constant real BUFF_DURATION = 15.00
private constant real CCB_BASE = 30.00
private constant real CCB_LVL = 10.00
private constant string MISSILE_SFX = "war3mapImported\\Tank Shell Black.mdx"
private constant string CASTER_SFX = "war3mapImported\\Windwalk Fire.mdx"
private constant string HIT_SFX = "Abilities\\Weapons\\CannonTowerMissile\\CannonTowerMissile.mdl"
endglobals
struct APCanon extends array
real crit
integer range
effect sfx
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BlzSetUnitWeaponRealField(b.target,UNIT_WEAPON_RF_ATTACK_PROJECTILE_SPEED,0,1500)
call BlzSetUnitWeaponIntegerField(b.target,UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE,0,6)
call BlzSetUnitWeaponStringField(b.target,UNIT_WEAPON_SF_ATTACK_PROJECTILE_ART,0,"Abilities\\Weapons\\CannonTowerMissile\\CannonTowerMissile.mdl")
call DestroyEffect(sfx)
set sfx = null
call AddUnitAnimationProperties(b.target,"alternate",false)
call AddHeroAttackRange(b.target,-(range/25))
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BlzSetUnitWeaponRealField(b.target,UNIT_WEAPON_RF_ATTACK_PROJECTILE_SPEED,0,999999)
call BlzSetUnitWeaponIntegerField(b.target,UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE,0,0)
call BlzSetUnitWeaponStringField(b.target,UNIT_WEAPON_SF_ATTACK_PROJECTILE_ART,0,"")
set crit = CCB_BASE + CCB_LVL * b.level
set range = 100 * b.level
call AddHeroAttackRange(b.target,range/25)
set sfx = AddSpecialEffectTarget(CASTER_SFX,b.target,"origin")
call AddUnitAnimationProperties(b.target,"alternate",true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "APCanon"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct APCanonMissile extends array
private static method onCollide takes Missile missile, unit hit returns boolean
local DamageOptions op
if IsUnitEnemy(hit,missile.owner) then
set op = DamageOptions.create()
set op.mainAttack = true
set op.allowOrbs = true
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypeAttack,"CanonAttack",0,0)
if missile.speed == 60 and GetRandomInt(1,100) <= 25 then
call Status.Add(STATUS_STUN,hit,0.20,Status_EFFECT[STATUS_STUN])
endif
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,hit,"overhead"))
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, unit target, real dmg returns Missile
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local real d = BlzGetUnitWeaponRealField(source,UNIT_WEAPON_RF_ATTACK_RANGE,0) * 2
local real x = GetUnitX(source)
local real y = GetUnitY(source)
local real xt
local real yt
local Missile missile
local real a = AngleBetweenUnits(source,target)
local real z = 80.00
set xt = x + d * Cos(a)
set yt = y + d * Sin(a)
set missile = Missile.createXYZ(x,y,z,xt,yt,z)
set missile.source = source
set missile.level = lvl
set missile.owner = GetOwningPlayer(source)
set missile.damage = dmg
if GetUpgradeSkillLevel(source,UPGRADE_ID) != 0 then
set missile.speed = 60.00
else
set missile.speed = 45.00
endif
set missile.model = MISSILE_SFX
set missile.scale = 1.5
set missile.collision = 140
call APCanonMissile.launch(missile)
return missile
endfunction
private function onPreDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local real r
if data.codeDmg.codeName == "CanonAttack" then
set b = GetUnitBuff(data.source,APCanon.buff)
set data.criticalChanceAdd = data.criticalChanceAdd + APCanon[b.buffAllocIndex].crit
endif
if data.dmgType == udg_DamageTypeAttack then
if GetUnitAbilityLevel(data.source,'A0BB') != 0 then
set r = I2R(GetUnitData(data.source,"RF_AttackRate")) / 100
set data.mult = data.mult - r
endif
endif
endfunction
private function OnDummyDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
if GetUnitTypeId(data.source) == 'HDR1' then
call SetupMissile(data.source,data.target,data.damageMod)
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,BUFF_DURATION,APCanon.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call APCanon.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDmg))
call DamageEvent.RegisterDummyDamage(Filter(function OnDummyDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DwarfRunner_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Overdrive initializer init
globals
private constant integer SPELL_ID = 'DRA4'
private constant integer UPGRADE_ID = 'DRI4'
private constant integer DUMMY_ID = 'h00Q'
private constant integer EXTRA_ID2 = 'A0BD'
private constant real BUFF_DURATION = 16.00
private constant real AGI_TO_DMG = 0.01
private constant real ACD_BASE = 2.00
private constant real ACD_LVL = 0.20
private constant real RACD_BASE = 0.50
private constant integer RF_DR_BASE = 50
private constant integer RF_DR_LVL = 5
private constant string KNOCK_SFX = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
endglobals
struct ODKnock extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "ODKnock"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Overdrive extends array
real dmg
real acd
real ifa
unit dummy
integer agi
effect sfx
boolean hiden
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local real a = GetUnitFacing(b.target)
local player p = GetOwningPlayer(b.target)
local integer rlvl = GetUnitAbilityLevel(b.target,'A0BB')
local integer cagi = GetHeroAgi(b.target,true)
local real cd
local real bacd = 0
local integer d
local group g
local unit temp
local real ms = GetUnitMoveSpeed(b.target)
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
if IsUnitHidden(b.target) or Status.UnitHasStatus(STATUS_CYCLONE,b.target) or Status.UnitHasStatus(STATUS_HEX,b.target) or Status.UnitHasStatus(STATUS_DISARM,b.target) or Status.UnitHasStatus(STATUS_STUN,b.target) or Status.UnitHasStatus(STATUS_ENTANGLE,b.target) or Status.UnitHasStatus(STATUS_FEAR,b.target) or Status.UnitHasStatus(STATUS_SLEEP,b.target) then
if not hiden then
call PauseUnit(dummy,true)
set hiden = true
endif
else
if hiden then
set hiden = false
call PauseUnit(dummy,false)
endif
endif
if not hiden then
set d = BlzGetUnitBaseDamage(b.target,0) + BonusStruct.GetFlatBonus(BONUS_TYPE_DAMAGE,b.target)
if rlvl != 0 then
set bacd = RACD_BASE
set d = d*(RF_DR_BASE + RF_DR_LVL * GetUnitAbilityLevel(b.target,'DRA3'))/100
endif
call BlzSetUnitBaseDamage(dummy,d,0)
if cagi != agi or bacd != 0 then
set agi = cagi
set cd = (acd - bacd) - (ifa * (I2R(agi / 10)))
if cd < 0.20 then
set cd = 0.20
endif
call BlzSetUnitAttackCooldown(dummy,cd,0)
endif
if b.int == 3 then
if IsUnitMoving(b.target) and IsUnitInCombat(b.target) then
set b.elapsedTime = b.elapsedTime - 0.03125
endif
endif
endif
//KNOCK
set g = NewGroup()
set x = x + 100 * Cos(a * bj_DEGTORAD)
set y = y + 100 * Sin(a * bj_DEGTORAD)
call GroupEnumUnitsInRange(g,x,y,120.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
if not UnitHasBuff(temp,ODKnock.buff) then
if IsPointInSightOfAngle(a,x,y,GetUnitX(temp),GetUnitY(temp),90) then
if GetUnitMoveSpeed(temp) < ms then
call KPJUnit.create(temp,250,(a + 180.00) * bj_DEGTORAD,0.50,250,KPJDefaultConfig3,KPJ_TYPE_JUMP)
call DestroyEffect(AddSpecialEffectTarget(KNOCK_SFX,temp,"origin"))
call Status.Add(STATUS_STUN,temp,1.0,Status_EFFECT[STATUS_STUN])
call UnitAddBuff(temp,temp,3.00,ODKnock.buff,0,0)
endif
endif
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call KillUnit(dummy)
call UnitRemoveAbility(b.target,EXTRA_ID2)
call AddUnitAnimationProperties(b.target,"alternate",false)
call BlzUnitHideAbility(b.target,'Aatk',false)
call UnitRemoveAbility(b.target,'Abun')
call AddHeroAttackRange(b.target,-8)
call DestroyEffect(sfx)
set sfx = null
set dummy = null
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local integer d
local real bacd = 0
set acd = ACD_BASE - ACD_LVL * b.level
set ifa = AGI_TO_DMG
set b.int = GetHeroMasteryType(b.target)
if b.int == 2 then
set ifa = ifa + AGI_TO_DMG
endif
set sfx = AddSpecialEffectTarget(CASTER_SFX,b.target,"origin")
call AddUnitAnimationProperties(b.target,"alternate",true)
set dummy = CreateUnit(GetOwningPlayer(b.target),DUMMY_ID,x,y,0)
call RemoveGuardPosition(dummy)
call SetDummyData(dummy,"Buff",b)
call BlzUnitHideAbility(b.target,'Aatk',true)
call UnitAddAbility(b.target,'Abun')
call UnitMakeAbilityPermanent(b.target,true,'Abun')
call UnitAddAbility(b.target,EXTRA_ID2)
call UnitMakeAbilityPermanent(b.target,true,EXTRA_ID2)
call AddHeroAttackRange(b.target,8)
call SetUnitAcquireRange(dummy,GetUnitAcquireRange(b.target))
set agi = GetHeroAgi(b.target,true)
set d = BlzGetUnitBaseDamage(b.target,0) + BonusStruct.GetFlatBonus(BONUS_TYPE_DAMAGE,b.target)
if GetUnitAbilityLevel(b.target,'A0BB') != 0 then
set bacd = RACD_BASE
set d = d*(RF_DR_BASE + RF_DR_LVL * GetUnitAbilityLevel(b.target,'DRA3'))/100
endif
call BlzSetUnitBaseDamage(dummy,d,0)
call BlzSetUnitAttackCooldown(dummy,(acd - bacd) - ifa * (I2R(agi / 10)),0)
set hiden = false
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Overdrive"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onPreDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local real d
local Buff b
if GetUnitTypeId(data.source) == DUMMY_ID then
set d = data.damageMod
set data.damageMod = 0
set b = GetDummyData(data.source,"Buff")
if b != 0 then
call CodeDamage.Damage(b.target,data.target,d,udg_DamageTypeAttack,"ODAttack",0,0)
endif
endif
if data.codeDmg.codeName == "ODAttack" then
set data.allowOrbs = true
set data.mainAttack = true
endif
endfunction
private function onCastAttack takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local player p = GetOwningPlayer(u)
local Buff b = GetUnitBuff(u,Overdrive.buff)
local unit temp
local unit r1 = null
local unit r2 = null
local unit r3 = null
local real d1 = 99999
local real d2 = 99999
local real d3 = 99999
local real dt
local group g
if b != 0 then
set g = NewGroup()
call GroupEnumUnitsInRange(g,x,y,150,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
set dt = Distance(x,y,GetUnitX(temp),GetUnitY(temp))
if FILT_HERO_ENEMY(temp,p) then
if dt < d1 then
set d1 = dt
set r1 = temp
endif
elseif FILT_VALID_STRUCTURE(temp) and IsUnitEnemy(temp,p) then
if dt < d2 then
set d2 = dt
set r2 = temp
endif
elseif FILT_UNIT_ENEMY(temp,p) then
if dt < d3 then
set d3 = dt
set r3 = temp
endif
endif
endloop
if r1 != null then
call IssueTargetOrderById(Overdrive[b.buffAllocIndex].dummy,ORDER_attack,r1)
elseif r2 != null then
call IssueTargetOrderById(Overdrive[b.buffAllocIndex].dummy,ORDER_attack,r2)
elseif r3 != null then
call IssueTargetOrderById(Overdrive[b.buffAllocIndex].dummy,ORDER_attack,r3)
endif
call ReleaseGroup(g)
set r1 = null
set r2 = null
set r3 = null
endif
set u = null
set temp = null
set p = null
set g = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,BUFF_DURATION,Overdrive.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Overdrive.Initialize()
call ODKnock.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID2, function onCastAttack)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DwarfRunner_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library Mindbender initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HMB1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'MBI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Psy Tempest"
set up.Text = "Reduces |c00b4b4b4Psy Storm|r cooldown."
set up.SupText = "|c00b4b4b4Psy Storm|r also |c0000ced1Stuns|r the enemies for the same duration."
set up.LevelData1 = "-1s Cooldown"
set up.LevelData2 = "-2s Cooldown"
set up.LevelData3 = "-3s Cooldown"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'MBI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Arcane Barrage"
set up.Text = "Increases |c00b4b4b4Arcane Missiles|r base damage."
set up.SupText = "Adds 2 extra charges to |c00b4b4b4Arcane Missiles|r."
set up.LevelData1 = "+10 Base Damage"
set up.LevelData2 = "+20 Base Damage"
set up.LevelData3 = "+30 Base Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'MBI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Flying Mage"
set up.Text = "|c00b4b4b4Levitate|r also increases the |c00ffff95Movement Speed|r."
set up.SupText = "During |c0099b4d1Levitate|r the hero becomes immune to |c0000ced1Ensnare|r and |c0000ced1Entangle|r status."
set up.LevelData1 = "+12% Ms"
set up.LevelData2 = "+18% Ms"
set up.LevelData3 = "+24% Ms"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'MBI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Superior Arcanist"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HMB1'
set d.Name = "Mindbender"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNMindbender.blp"
set d.WinAni = "channeling"
set d.Block = 0
set d.Evasion = 30
set d.Resistance = 50
set d.LifeRegen = 1.0
set d.ManaRegen = 2.5
set d.Armor = 0
set d.AttackRange = 500
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'MBA1'
set d.HeroAbility2 = 'MBA2'
set d.HeroAbility3 = 'MBA3'
set d.HeroAbility4 = 'MBA4'
set d.ChooseDummy = 'dh36'
set d.spellDamageLevel = 9
set d.attackDamageLevel = 1
set d.healingLevel = 0
set d.survivavilityLevel = 3
set d.movementLevel = 4
set d.crowdControlLevel = 3
set d.HeroFaction = Game.FACTION_HUMAN
set d.InfoID = 'HMBI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope PsyStorm initializer init
globals
private constant integer SPELL_ID = 'MBA1'
private constant integer UPGRADE_ID = 'MBI1'
private constant real DAMAGE_BASE = 20.00
private constant real DAMAGE_LEVEL = 10.00
private constant real AREA_OF_EFFECT = 160.00
private constant real DISTANCE = 650.00
private KPJConfig SpellKPJ
private constant string EFFECT_SFX = "Abilities\\Spells\\Other\\Tornado\\TornadoElemental.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local effect sfx = tb.effect[0]
local unit u = tb.unit[1]
local real time = tb.real[3]
local real time2 = tb.real[5]
local real dmg = tb.real[2]
local LinkedList list = tb.integer[4]
local unit temp
local Link h = list.head
set time = time + 0.03125
set time2 = time2 + 0.03125
set tb.real[3] = time
if time2 >= 0.50 then
set time2 = 0.00
loop
exitwhen h == 0
set temp = GetUnitByIndex(h.data)
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
set h = h.next
endloop
endif
set tb.real[5] = time2
if time >= 2.0 then
call DestroyEffect(sfx)
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
endif
set t = null
set sfx = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real xu = GetUnitX(u)
local real yu = GetUnitY(u)
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real a = Angle(xu,yu,x,y)
local effect sfx = AddSpecialEffect(EFFECT_SFX,xu,yu)
local player p = GetOwningPlayer(u)
local group g = NewGroup()
local real dmg = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
local LinkedList list = LinkedList.create()
local boolean sup = IsUpgradeSuperior(u,UPGRADE_ID)
local unit temp
local real d
local Buff b
local Table tb = Table.create()
set tb.effect[0] = sfx
set tb.unit[1] = u
set tb.real[2] = dmg
set tb.real[3] = 0.00
set tb.integer[4] = list
set tb.real[5] = 0.00
set x = xu + DISTANCE * Cos(a)
set y = yu + DISTANCE * Sin(a)
call BlzSetSpecialEffectScale(sfx,1.4)
call BlzSetSpecialEffectPitch(sfx,-90)
call BlzSetSpecialEffectZ(sfx,GetLocZ(xu,yu) + 200.00)
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectColor(sfx,255,0,255)
call BlzSetSpecialEffectTimeScale(sfx,1.75)
call LineSegment.EnumUnits(g,xu,yu,x,y,AREA_OF_EFFECT)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
set d = DISTANCE - Distance(xu,yu,GetUnitX(temp),GetUnitY(temp)) + 50
call KPJUnit.create(temp,d,a,2.0,0,SpellKPJ,KPJ_TYPE_KNOCKBACK)
call list.add(GetUnitUserData(temp))
if sup then
call Status.Add(STATUS_STUN,temp,2.0,Status_EFFECT[STATUS_STUN])
endif
endif
endloop
call ReleaseGroup(g)
call TimerStart(NewTimerEx(tb),0.03125,true,function Callback)
set sfx = null
set g = null
set p = null
set b = GetUnitBuff(u,ArcaneOverload.buff)
if b != 0 then
call DestroyEffect(AddSpecialEffectTarget(ArcaneOverload_CAST_SFX,u,"origin"))
set b.duration = b.duration + ArcaneOverload[b.buffAllocIndex].dur
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set SpellKPJ = KPJConfig.create()
set SpellKPJ.friction = 0
set SpellKPJ.gravity = 0.5
set SpellKPJ.disable = true
set SpellKPJ.hardDisable = false
set SpellKPJ.killTrees = true
set SpellKPJ.sfxModel = "Abilities\\Spells\\Undead\\DevourMagic\\DevourMagicBirthMissile.mdl"
set SpellKPJ.sfxTime = 0.10
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Mindbender_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(EFFECT_SFX)
endfunction
endscope
scope ArcaneMissiles initializer init
globals
private constant integer SPELL_ID = 'MBA2'
private constant integer UPGRADE_ID = 'MBI2'
private constant real DAMAGE_BASE = 70.00
private constant real INT_BASE = 0.40
private constant real INT_LEVEL = 0.20
private constant real UP_DMG = 10.00
private constant string MISSILE_SFX = "war3mapImported\\ArcaneMissileComplete.mdx"
endglobals
private function GetDamageInt takes integer lvl returns real
return INT_BASE + INT_LEVEL * lvl
endfunction
struct ArcaneMissile extends array
private static method onFinish takes Missile missile returns boolean
local real dmg
if TriggerSpellReflection(missile.target) then
call ArcaneMissiles_SetupMissile.evaluate(missile.target,missile.source,missile.level)
endif
if not TriggerSpellNegation(missile.target) then
set dmg = DAMAGE_BASE + UP_DMG * GetUpgradeSkillLevel(missile.source,UPGRADE_ID)
set dmg = dmg + GetHeroInt(missile.source,true) * missile.damage
call CodeDamage.Damage(missile.source,missile.target,dmg,udg_DamageTypeMagic,"ArcaneMissiles",0,0)
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),100.00,AngleBetweenUnits(source,target),0,100.00)
set missile.source = source
set missile.target = target
set missile.level = lvl
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamageInt(lvl)
set missile.speed = 18.00
set missile.model = MISSILE_SFX
set missile.scale = 1.2
call ArcaneMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local unit r1
local unit r2
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local integer c = 0
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local unit temp
local Buff b = GetUnitBuff(u,ArcaneOverload.buff)
call SetupMissile(u,t,lvl)
call GroupEnumUnitsInRange(g,GetUnitX(t),GetUnitY(t),400,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null or c == 2
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and temp != t then
call SetupMissile(u,temp,lvl)
set c = c + 1
endif
endloop
call ReleaseGroup(g)
if b != 0 then
call DestroyEffect(AddSpecialEffectTarget(ArcaneOverload_CAST_SFX,u,"origin"))
set b.duration = b.duration + ArcaneOverload[b.buffAllocIndex].dur
endif
set u = null
set t = null
set g = null
set p = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetLearnedSkillLevel()
local Ability a
if lvl == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call a.addMaxCharges(6)
endif
if GetHeroMasteryType(u) == 2 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call BlzSetAbilityRealLevelField(BlzGetUnitAbility(a.owner,a.objectID),ABILITY_RLF_COOLDOWN,a.level - 1,3)
set a.level = a.level - 1
call a.updateTooltip(true)
endif
set u = null
endfunction
private function onPreDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local ArcaneOverload b
if data.codeDmg.codeName == "ArcaneMissiles" then
if GetHeroMasteryType(data.source) == 3 then
set data.slifestealAdd = data.slifestealAdd + 0.30
set data.spellStrAdd = data.spellStrAdd + 60
endif
endif
if data.dmgType <= 6 then
set b = GetUnitBuff(data.target,ArcaneOverload.buff).buffAllocIndex
if data.source == b.thisBuff.owner then
set data.criticalChanceAdd = data.criticalChanceAdd + b.crit
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.isCharged = true
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID,function onLearn)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Mindbender_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope Levitate initializer init
globals
private constant integer SPELL_ID = 'MBA3'
private constant integer UPGRADE_ID = 'MBI3'
private constant real BUFF_DURATION = 10.00
private constant integer MC_BASE = 5
private constant real UP_MS = 0.06
private RSound Sound
endglobals
private function GetManaCost takes integer lvl returns integer
return MC_BASE * lvl
endfunction
struct Levitate extends array
integer mc
real xu
real yu
real x
real y
real s
boolean run
boolean anim
real ang
Movespeed ms
boolean sup
unit dummy
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Ability a = Ability.GetUnitAbilityByID('MBA1',b.target)
if a != 0 then
call a.addManaCost(0,mc)
endif
set a = Ability.GetUnitAbilityByID('MBA2',b.target)
if a != 0 then
call a.addManaCost(0,mc)
endif
set a = Ability.GetUnitAbilityByID('MBA3',b.target)
if a != 0 then
call a.addManaCost(0,mc)
endif
set a = Ability.GetUnitAbilityByID('MBA4',b.target)
if a != 0 then
call a.addManaCost(0,mc)
endif
call Status.Remove(STATUS_UNTURN,b.target)
call Status.Remove(STATUS_UNPATH,b.target)
if not UnitAlive(b.target) then
call SetUnitAnimation(b.target,"death")
else
if not run then
call SetUnitAnimation(b.target,"stand")
endif
endif
if ms != 0 then
call ms.destroy()
endif
if sup then
call AddUnitStatusReduction(STATUS_ENTANGLE,b.target,0,false)
call AddUnitStatusReduction(STATUS_ENSNARE,b.target,0,false)
set sup = false
endif
call SetUnitFlyHeight(b.target,0.00,0.2)
call BlzSetUnitRealField(b.target,UNIT_RF_FLY_HEIGHT,0.00)
call RemoveUnit(dummy)
set dummy = null
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if run and not Status.UnitHasStatus(STATUS_STUN,b.target) then
set xu = GetUnitX(b.target)
set yu = GetUnitY(b.target)
set s = GetUnitMoveSpeed(b.target) / 32
set ang = Angle(xu,yu,x,y)
if Distance(xu,yu,x,y) >= s then
call SetUnitX(b.target,xu + s * Cos(ang))
call SetUnitY(b.target,yu + s * Sin(ang))
else
set run = false
set anim = false
call SetUnitAnimation(b.target,"stand")
endif
if anim then
call SetUnitAnimationByIndex(b.target,1)
endif
endif
call SetUnitX(dummy,xu)
call SetUnitY(dummy,yu)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Ability a = Ability.GetUnitAbilityByID('MBA1',b.target)
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set mc = GetManaCost(b.level)
if a != 0 then
call a.addManaCost(0,-mc)
endif
set a = Ability.GetUnitAbilityByID('MBA2',b.target)
if a != 0 then
call a.addManaCost(0,-mc)
endif
set a = Ability.GetUnitAbilityByID('MBA3',b.target)
if a != 0 then
call a.addManaCost(0,-mc)
endif
set a = Ability.GetUnitAbilityByID('MBA4',b.target)
if a != 0 then
call a.addManaCost(0,-mc)
endif
call Status.Add(STATUS_UNTURN,b.target,0,0)
call Status.Add(STATUS_UNPATH,b.target,0,0)
if ulvl != 0 then
set ms = Movespeed.create(b.target,UP_MS + UP_MS * ulvl,0)
else
set ms = 0
endif
set sup = IsUpgradeSuperior(b.target,UPGRADE_ID)
if sup then
call AddUnitStatusReduction(STATUS_ENTANGLE,b.target,0,true)
call AddUnitStatusReduction(STATUS_ENSNARE,b.target,0,true)
endif
set run = false
set anim = false
set xu = GetUnitX(b.target)
set yu = GetUnitY(b.target)
set dummy = CreateUnit(GetOwningPlayer(b.target),'h00O',xu,yu,0)
call BlzSetUnitRealField(dummy,UNIT_RF_SIGHT_RADIUS,BlzGetUnitRealField(b.target,UNIT_RF_SIGHT_RADIUS))
call MakeFly(b.target)
call SetUnitFlyHeight(b.target,120.00,0.2)
call BlzSetUnitRealField(b.target,UNIT_RF_FLY_HEIGHT,120.00)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A03C'
set BUFF_DATA.BuffID = 'B056'
set BUFF_DATA.Name = "Levitate"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Buff b = GetUnitBuff(u,ArcaneOverload.buff)
call UnitAddBuff(u,u,BUFF_DURATION,Levitate.buff,lvl,0)
if b != 0 then
call DestroyEffect(AddSpecialEffectTarget(ArcaneOverload_CAST_SFX,u,"origin"))
set b.duration = b.duration + ArcaneOverload[b.buffAllocIndex].dur
endif
call Sound.play(GetUnitX(u),GetUnitY(u),0,100)
set u = null
endfunction
private function OnOrder takes nothing returns nothing
local unit u = GetOrderedUnit()
local eventid ev = GetTriggerEventId()
local item it
local unit t
local integer id
local real dist
local real a
local Levitate b = GetUnitBuff(u,Levitate.buff).buffAllocIndex
if b != 0 then
set id = GetIssuedOrderId()
if ev == EVENT_UNIT_ISSUED_POINT_ORDER then
if id == ORDER_smart or id == ORDER_move or id == ORDER_attack then
set b.run = true
set b.anim = true
set b.x = GetOrderPointX()
set b.y = GetOrderPointY()
call BlzSetUnitFacingEx(u,Angle(b.xu,b.yu,b.x,b.y) * bj_RADTODEG)
else
set b.anim = false
set dist = Distance(b.xu,b.yu,GetOrderPointX(),GetOrderPointY())
//set b.x = GetOrderPointX()
//set b.y = GetOrderPointY()
call BlzSetUnitFacingEx(u,Angle(b.xu,b.yu,GetOrderPointX(),GetOrderPointY()) * bj_RADTODEG)
endif
elseif ev == EVENT_UNIT_ISSUED_TARGET_ORDER then
set it = GetOrderTargetItem()
set t = GetOrderTargetUnit()
if t != null then
set a = Angle(b.xu,b.yu,GetUnitX(t),GetUnitY(t))
if id == ORDER_smart then
if IsUnitAlly(t,GetTriggerPlayer()) then
set b.run = true
set b.anim = true
set b.x = GetUnitX(t)
set b.y = GetUnitY(t)
else
set b.anim = false
endif
else
if id == ORDER_attack then
set dist = Distance(b.xu,b.yu,GetUnitX(t),GetUnitY(t))
if dist > BlzGetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_RANGE,0) then
set b.run = true
set b.anim = true
set b.x = b.xu + (dist - BlzGetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_RANGE,0)) * Cos(a)
set b.y = b.yu + (dist - BlzGetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_RANGE,0)) * Sin(a)
else
set b.anim = false
endif
else
set b.anim = false
endif
endif
call BlzSetUnitFacingEx(u,a * bj_RADTODEG)
else
if it != null then
if id == ORDER_smart then
set b.run = true
set b.anim = true
set b.x = GetItemX(it)
set b.y = GetItemY(it)
else
set b.anim = false
endif
call BlzSetUnitFacingEx(u,Angle(b.xu,b.yu,GetItemX(it),GetItemY(it)) * bj_RADTODEG)
endif
endif
set it = null
set t = null
elseif ev == EVENT_UNIT_ISSUED_ORDER then
if id == ORDER_stop then
set b.anim = false
set b.run = false
endif
endif
endif
set u = null
set ev= null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local trigger t
if GetLearnedSkillLevel() == 1 then
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t,function OnOrder)
set t = null
if GetPlayerController(GetTriggerPlayer()) == MAP_CONTROL_COMPUTER then
call BlzUnitDisableAbility(u,SPELL_ID,true,false)
endif
endif
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == 'MBI1' then
set a = Ability.GetUnitAbilityByID('MBA1',up.ownerHero.hero)
call a.addFlatCooldown(-1)
endif
if up.upID == 'MBI2' and up.isSuperior then
set a = Ability.GetUnitAbilityByID('MBA2',up.ownerHero.hero)
call a.addMaxCharges(2)
endif
if up.upID == 'MBI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 2 and up.level == 2 then
set a = Ability.GetUnitAbilityByID('MBA2',up.ownerHero.hero)
call BlzSetAbilityRealLevelField(BlzGetUnitAbility(a.owner,a.objectID),ABILITY_RLF_COOLDOWN,a.level - 1,3)
set a.level = a.level - 1
call a.updateTooltip(true)
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Levitate.Initialize()
set Sound = RSound.create("war3mapImported\\569172.mp3", true, true, 12700, 12700)
call RegisterSpellLearn(SPELL_ID,function onLearn)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Mindbender_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope ArcaneOverload initializer init
globals
private constant integer SPELL_ID = 'MBA4'
private constant integer UPGRADE_ID = 'MBI4'
private constant integer INT_BASE = 6
private constant real CRIT_BASE = 0.02
private constant real DUR_BASE = 0.50
private constant real DUR_LEVEL = 0.25
private constant real BUFF_DURATION = 3.00
public constant string CAST_SFX = "war3mapImported\\Holy Light.mdx"
endglobals
private function GetIntBonus takes integer lvl returns integer
return INT_BASE + INT_BASE * lvl
endfunction
private function GetCritBonus takes integer lvl returns real
return CRIT_BASE + CRIT_BASE * lvl
endfunction
private function GetDurationBonus takes integer lvl returns real
return DUR_BASE + DUR_LEVEL * lvl
endfunction
struct ArcaneOverload extends array
integer int
integer str
real crit
real dur
boolean period
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,b.target,-int,0,true)
if str != 0 then
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,-str,0,true)
set str = 0
endif
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if period then
if Status.UnitHasStatus(STATUS_SILENCE,b.target) then
set b.elapsedTime = b.elapsedTime - 0.03125
endif
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set int = GetIntBonus(b.level)
set crit = GetCritBonus(b.level)
set dur = GetDurationBonus(b.level)
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,b.target,int,0,true)
if GetUpgradeSkillLevel(b.target,UPGRADE_ID) != 0 then
set period = true
else
set period = false
endif
if GetHeroMasteryType(b.target) == 1 then
set str = GetHeroInt(b.target,true) * 25 / 100
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,str,0,true)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A039'
set BUFF_DATA.BuffID = 'B057'
set BUFF_DATA.Name = "Arcane Overload"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,BUFF_DURATION,ArcaneOverload.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ArcaneOverload.Initialize()
call RegisterSpellCastEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Mindbender_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library FelRider initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HFR1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'FRI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Nether Chains"
set up.Text = "|c00b4b4b4Fel Blade|r also adds a bonus |c00ffff95Attack Damage|r."
set up.SupText = "Removes |c00b4b4b4Fel Blade|r bounces limit per unit."
set up.LevelData1 = "+5 Damage per bounce"
set up.LevelData2 = "+7 Damage per bounce"
set up.LevelData3 = "+9 Damage per bounce"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNShadowStrike.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'FRI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Wildhound"
set up.Text = "Increases |c00b4b4b4Devourer Bite|r damage based on the target max mana."
set up.SupText = "|c00b4b4b4Devourer Bite|r also reduces all |c0000ff00Healing|r received by 50%."
set up.LevelData1 = "+8% of Max Mana as damage"
set up.LevelData2 = "+10% of Max Mana as damage"
set up.LevelData3 = "+12% of Max Mana as damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNFelHound.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'FRI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Abyssal Empower"
set up.Text = "Increases the damage base of |c00b4b4b4Outworld Fire|r."
set up.SupText = "|c00b4b4b4Outworld Fire|r makes area damage in 300 aoe."
set up.LevelData1 = "+20 Damage"
set up.LevelData2 = "+40 Damage"
set up.LevelData3 = "+60 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNOrbOfDarkness.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'FRI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Fel Lust"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HFR1'
set d.Name = "Fel Rider"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNFelRider.blp"
set d.WinAni = "spell"
set d.Block = 20
set d.Evasion = 30
set d.Resistance = 30
set d.LifeRegen = 0.5
set d.ManaRegen = 1.2
set d.Armor = 5
set d.AttackRange = 125
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'FRA1'
set d.HeroAbility2 = 'FRA2'
set d.HeroAbility3 = 'FRA3'
set d.HeroAbility4 = 'FRA4'
set d.ChooseIconID = 'c007'
set d.ChooseDummy = 'dh11'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 5
set d.healingLevel = 5
set d.survivavilityLevel = 5
set d.movementLevel = 4
set d.crowdControlLevel = 1
set d.HeroFaction = Game.FACTION_ORC
set d.InfoID = 'HFRI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope FelBlade initializer init
globals
private constant integer SPELL_ID = 'FRA1'
private constant integer UPGRADE_ID = 'FRI1'
private constant real DAMAGE_BASE = 100.00
private constant real DAMAGE_LEVEL = 20.00
private constant integer BOUNCES_AS = 14
private constant real DURATION = 10.00
private constant real DURATION_PER_BOUNCE = 0.50
private constant integer UP_DAMAGE = 3
private constant integer UP_DAMAGE_LVL = 2
private constant real SUP_SPELL_LS = 0.05
private constant real SUP_SPELL_STR = 20.00
private constant string CHAIN_SFX = "war3mapImported\\GreenManaBurst.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct FelBlade extends array
real splife
real spstr
integer dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-(BOUNCES_AS * b.int),0,true)
if dmg != 0 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-(dmg * b.int),0,true)
set dmg = 0
endif
if splife != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,b.target,-splife,0)
set splife = 0.0
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,-spstr,0)
set spstr = 0.0
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,BOUNCES_AS * b.int,0,true)
if ulvl != 0 then
set dmg = UP_DAMAGE + UP_DAMAGE_LVL * ulvl
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg * b.int,0,true)
endif
if GetHeroMasteryType(b.target) == 3 then
set splife = SUP_SPELL_LS * b.int
set spstr = SUP_SPELL_STR * b.int
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_LIFESTEAL,b.target,splife,0)
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,spstr,0)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02L'
set BUFF_DATA.BuffID = 'B01D'
set BUFF_DATA.Name = "Fel Blade"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct FelBladeDebuff extends array
private static method onRemove takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,BOUNCES_AS,0,true)
endmethod
private static method onApply takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-BOUNCES_AS,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02M'
set BUFF_DATA.BuffID = 'B01E'
set BUFF_DATA.Name = "Fel Blade Debuff"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct FelBladeChain extends array
private static method FilterUnits takes unit u, player p, Chain c returns boolean
return FILT_UNIT_ENEMY(u,p) and not IsUnitMagicImmune(u)
endmethod
private static method onHit takes Chain c returns nothing
local LinkedList list = c.data
local Buff b
call CodeDamage.Damage(c.caster,c.target,c.damage,udg_DamageTypeMagicAoe,"",0,0)
set b = UnitAddBuff(c.target,c.caster,10.00,FelBladeDebuff.buff,0,0)
if b != 0 then
call list.add(b)
endif
endmethod
private static method onEnd takes Chain c returns nothing
local LinkedList list = c.data
local Link node = list.head
local Buff b
local real d = DURATION + (DURATION_PER_BOUNCE * c.bounces)
loop
exitwhen node == 0
set b = node.data
call SetUnitBuffDuration(b.target,b.data,d)
set node = node.next
endloop
call list.destroy()
call UnitAddBuff(c.caster,c.caster,d,FelBlade.buff,0,c.bounces)
endmethod
private static method ConfigMissile takes Chain c, unit origin returns nothing
set c.dummy = DummySFX.create(GetUnitX(origin),GetUnitY(origin),50.00,AngleBetweenUnits(origin,c.target),DUMMYSFX_TYPE_NORMAL)
set c.dummy.SFX = CHAIN_SFX
set c.dummy.Scale = 2.00
call c.dummy.setColor(0,128,128,255)
endmethod
implement ChainManager
endstruct
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
local Chain c = Chain.create()
set c.caster = u
set c.target = t
set c.damage = GetDamage(lvl)
set c.speed = 23.00
set c.area = 500.00
set c.maxBounces = 2 + 1 * lvl
set c.data = LinkedList.create()
if not IsUpgradeSuperior(u,UPGRADE_ID) then
set c.jumpOnce = true
endif
call FelBladeChain.Fire(c)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FelBladeDebuff.Initialize()
call FelBlade.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FelRider_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A02M',PRELOAD_SECOND)
call PreloadGen.Add('A02L',PRELOAD_SECOND)
call Preload(CHAIN_SFX)
endfunction
endscope
scope DevourerBite initializer init
globals
private constant integer SPELL_ID = 'FRA2'
private constant integer UPGRADE_ID = 'FRI2'
private constant real DAMAGE_BASE = 45.00
private constant real DAMAGE_LEVEL = 30.00
private constant real MANA_BURNED_BASE = 15.00
private constant real MANA_BURNED_LEVEL = 5.00
private constant real DURATION = 7.00
private constant real UP_DAMAGE_BASE = 0.06
private constant real UP_DAMAGE_LEVEL = 0.02
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetDamageUpgrade takes integer ulvl returns real
if ulvl == 0 then
return 0.00
endif
return UP_DAMAGE_BASE + UP_DAMAGE_LEVEL * ulvl
endfunction
private function GetManaBurned takes integer lvl returns real
return MANA_BURNED_BASE + MANA_BURNED_LEVEL * lvl
endfunction
struct DevourerBite extends array
real manab
private static method onRemove takes Buff b returns nothing
call DisableHeroRegen(b.target,false,false)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitRemoveMp(b.target,manab)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set manab = GetManaBurned(b.level)
call DisableHeroRegen(b.target,false,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A013'
set BUFF_DATA.BuffID = 'B00D'
set BUFF_DATA.Name = "Devourer Bite"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
local real dmg = GetDamage(lvl)
local real dmgex = BlzGetUnitMaxMana(t) * GetDamageUpgrade(GetUpgradeSkillLevel(u,UPGRADE_ID))
call CodeDamage.Damage(u,t,dmg + dmgex,udg_DamageTypePhysical,"",0,0)
call UnitAddBuff(t,u,DURATION,DevourerBite.buff,lvl,0)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_TARGET
set d.UseAuxDummy = false
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DevourerBite.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FelRider_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A013',PRELOAD_SECOND)
endfunction
endscope
scope OutworldFire initializer init
globals
private constant integer SPELL_ID = 'FRA3'
private constant integer UPGRADE_ID = 'FRI3'
private constant integer MAX_STRIKES = 3
private constant real DAMAGE_BASE = 20.00
private constant real DAMAGE_LEVEL = 10.00
private constant real DMG_PER_MANA = 0.05
private constant real SLOW = -0.40
private constant real SLOW_DURATION = 2.50
private constant real BUFF_DURATION = 8.00
private constant real UP_DAMAGE_BASE = 20.00
private constant real SUP_AREA = 300.00
private constant string HIT_SFX = "war3mapImported\\DarkSwirl.mdl"
endglobals
private function GetUpgradeDamage takes integer ulvl returns real
return UP_DAMAGE_BASE * ulvl
endfunction
private function GetDamageBase takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct OutworldFireSlow extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,SLOW,0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Outworld Fire Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct OutworldFire extends array
integer strikes
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set strikes = MAX_STRIKES
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02N'
set BUFF_DATA.BuffID = 'B01F'
set BUFF_DATA.Name = "Outworld Fire"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onPreDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b1
if data.dmgType == udg_DamageTypeHeal or data.dmgType == udg_DamageTypeHealOverTime then
set b1 = GetUnitBuff(data.target,DevourerBite.buff)
if b1 != 0 then
if IsUpgradeSuperior(b1.owner,UPGRADE_ID) then
set data.mult = data.mult - 0.50
endif
endif
endif
endfunction
private function onDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local OutworldFire b
local integer lvl
local real dmg
local real dif
local group g
local unit temp
local player p
if data.dmgType == udg_DamageTypeAttack and not data.isMiss and data.mainAttack then
if UnitHasBuff(data.source,OutworldFire.buff) and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) and not IsUnitType(data.target,UNIT_TYPE_MECHANICAL) then
set b = GetUnitBuff(data.source,OutworldFire.buff).buffAllocIndex
set b.strikes = b.strikes - 1
set dmg = GetDamageBase(b.thisBuff.level) + GetUpgradeDamage(GetUpgradeSkillLevel(data.source,UPGRADE_ID))
set dif = GetUnitState(data.target,UNIT_STATE_MAX_MANA)
if dif > 0 then
set dif = dif - GetUnitState(data.target,UNIT_STATE_MANA)
set dmg = dmg + dif * DMG_PER_MANA
endif
if b.strikes == 0 then
call UnitRemoveBuff(data.source,OutworldFire.buff)
endif
if IsUpgradeSuperior(data.source,UPGRADE_ID) then
set g = NewGroup()
set p = GetOwningPlayer(data.source)
call GroupEnumUnitsInRange(g,GetUnitX(data.target),GetUnitY(data.target),SUP_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"overhead"))
call CodeDamage.Damage(data.source,temp,dmg,udg_DamageTypeMagic,"OF",0,0)
if UnitHasBuff(temp,DevourerBite.buff) then
call UnitAddBuff(temp,data.source,SLOW_DURATION,OutworldFireSlow.buff,0,0)
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
else
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,data.target,"overhead"))
call CodeDamage.Damage(data.source,data.target,dmg,udg_DamageTypeMagic,"OF",0,0)
if UnitHasBuff(data.target,DevourerBite.buff) then
call UnitAddBuff(data.target,data.source,SLOW_DURATION,OutworldFireSlow.buff,0,0)
endif
endif
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,BUFF_DURATION,OutworldFire.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call OutworldFire.Initialize()
call OutworldFireSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDmg))
call DamageEvent.RegisterDamage(Filter(function onDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FelRider_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A02N',PRELOAD_SECOND)
call Preload(HIT_SFX)
endfunction
endscope
scope FelOnslaught initializer init
globals
private constant integer SPELL_ID = 'FRA4'
private constant integer UPGRADE_ID = 'FRI4'
private constant integer AURA_ID = 'A014'
private constant integer MAX_STACKS = 10
private constant real HEAL_BASE = 60.00
private constant real HEAL_LEVEL = 30.00
private constant integer MOVE_SPEED_BASE = 8
private constant integer MOVE_SPEED_LEVEL = 2
private constant integer ATTACK_STR_BASE = 6
private constant integer ATTACK_STR_LEVEL = 2
private constant real MA_HEAL = 100.00
private constant real BUFF_DURATION = 15.00
private unit OWNER
endglobals
private function GetMS takes integer lvl returns integer
return MOVE_SPEED_BASE + MOVE_SPEED_LEVEL * lvl
endfunction
private function GetASTR takes integer lvl returns integer
return ATTACK_STR_BASE + ATTACK_STR_LEVEL * lvl
endfunction
private function GetHeal takes integer lvl returns real
return HEAL_BASE + HEAL_LEVEL * lvl
endfunction
struct FelOnslaught extends array
Movespeed ms
integer as
boolean dm
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,-as,0)
if dm then
call AddUnitStatusReduction(STATUS_ENSNARE,b.target,0,false)
call AddUnitStatusReduction(STATUS_ENTANGLE,b.target,0,false)
set dm = false
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer stacks = GetUnitData(b.target,"FelStacks")
local integer sp = GetMS(b.level) * stacks
local Ability a = GetUnitData(b.target,"FelNumber")
set as = GetASTR(b.level) * stacks
set ms = Movespeed.create(b.target,0.0,sp)
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,as,0)
call SetUnitData(b.target,"FelStacks",0)
call SetUnitData(b.target,"FelNumber",0)
call a.abilityNumber.setValue(0)
if GetHeroMasteryType(b.target) == 2 then
call AddUnitStatusReduction(STATUS_ENSNARE,b.target,0,true)
call AddUnitStatusReduction(STATUS_ENTANGLE,b.target,0,true)
set dm = true
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02O'
set BUFF_DATA.BuffID = 'B01G'
set BUFF_DATA.Name = "FelOnslaught"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct ManaStalkerMissile extends array
private static method onFinish takes Missile missile returns boolean
local integer stacks = GetUnitData(missile.target,"FelStacks")
local Ability a
if stacks != MAX_STACKS then
set stacks = stacks + 1
set a = GetUnitData(missile.target,"FelNumber")
call a.abilityNumber.setValue(stacks)
call SetUnitData(missile.target,"FelStacks",stacks)
call CodeDamage.Damage(missile.target,missile.target,missile.damage,udg_DamageTypeHeal,"",0,0)
if missile.level == 3 then
call UnitAddMp(missile.target,missile.damage * 0.50)
endif
endif
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, unit target, integer data returns nothing
local real x = GetUnitX(source)
local real y = GetUnitY(source)
local real xt = GetUnitX(target)
local real yt = GetUnitY(target)
local real angle = Angle(x,y,xt,yt)
local Missile missile = Missile.create(x, y,50.0,angle,0,50.0)
set missile.source = source
set missile.owner = GetOwningPlayer(target)
set missile.target = target
set missile.damage = GetHeal(GetUnitAbilityLevel(target,SPELL_ID)) + data
set missile.level = GetHeroMasteryType(target)
if missile.level == 3 then
set missile.damage = missile.damage + MA_HEAL
endif
set missile.data = data
set missile.speed = 35.00
set missile.model = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
set missile.scale = 1.0
call ManaStalkerMissile.launch(missile)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,BUFF_DURATION,FelOnslaught.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function onCastEnemy takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id
local integer mc
if GetUnitAbilityLevel(u,'B00E') != 0 then
if IsUnitVisible(u,GetOwningPlayer(OWNER)) and UnitAlive(OWNER) then
set id = GetSpellAbilityId()
set mc = BlzGetAbilityManaCost(id,GetUnitAbilityLevel(u,id) - 1)
if mc != 0 then
call SetupMissile(u,OWNER,mc)
endif
endif
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer stacks = GetUnitData(u,"FelStacks")
local Ability a
if GetLearnedSkillLevel() == 1 then
set OWNER = u
call UnitAddAbility(u,AURA_ID)
call UnitMakeAbilityPermanent(u,true,AURA_ID)
set a = GetHeroAbilityById(u,SPELL_ID)
set a.abilityNumber = AbilityNumber.create(a.objectID,u)
call a.abilityNumber.setValue(0)
call SetUnitData(u,"FelNumber",a)
endif
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
if up.upID == UPGRADE_ID then
call SetUnitAbilityLevel(up.ownerHero.hero,AURA_ID,2)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FelOnslaught.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function onCastEnemy)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FelRider_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A02O',PRELOAD_SECOND)
endfunction
endscope
library BoneCrusher initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HJK1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'BRI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Destructive Spin"
set up.Text = "Increases |c00b4b4b4Deadly Spin|r area of effect."
set up.SupText = "Increases |c00b4b4b4Deadly Spin|r |c0000ced1Stun|r duration by 1s."
set up.LevelData1 = "+50 Area of Effect"
set up.LevelData2 = "+100 Area of Effect"
set up.LevelData3 = "+150 Area of Effect"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWhirlwind.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'BRI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "War Machine"
set up.Text = "|c00b4b4b4Uncontrolled Anger|r gives a |c00ffff95Lifesteal|r bonus."
set up.SupText = "Removes |c00b4b4b4Uncontrolled Anger|r Hp cost."
set up.LevelData1 = "+20% Lifesteal"
set up.LevelData2 = "+30% Lifesteal"
set up.LevelData3 = "+40% Lifesteal"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNBattleStations.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'BRI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Sharpen Weapon"
set up.Text = "The |c00b4b4b4Crushing Blows|r also ignores an amount of |c00ffff95Armor|r of the attacked enemy."
set up.SupText = "Increases |c00b4b4b4Crushing Blows|r splash damage by 60% and area of effect by 150."
set up.LevelData1 = "2 ignored Armor"
set up.LevelData2 = "3 ignored Armor"
set up.LevelData3 = "4 ignored Armor"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAbility_Warrior_PunishingBlow.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'BRI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Orc Wildness"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HJK1'
set d.Name = "Bone Crusher"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNGarrosh Hellscream.blp"
set d.WinAni = "attack slam"
set d.Block = 30
set d.Evasion = 0
set d.Resistance = 30
set d.LifeRegen = 0.5
set d.ManaRegen = 0.5
set d.Armor = 3
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'BRA1'
set d.HeroAbility2 = 'BRA2'
set d.HeroAbility3 = 'BRA3'
set d.HeroAbility4 = 'BRA4'
set d.ChooseIconID = 'c012'
set d.ChooseDummy = 'dh04'
set d.spellDamageLevel = 2
set d.attackDamageLevel = 7
set d.healingLevel = 5
set d.survivavilityLevel = 5
set d.movementLevel = 2
set d.crowdControlLevel = 3
set d.HeroFaction = Game.FACTION_ORC
set d.InfoID = 'HBRI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope DeadlySpin initializer init
globals
private constant integer SPELL_ID = 'BRA1'
private constant integer UPGRADE_ID = 'BRI1'
private constant real DAMAGE_BASE = 70.00
private constant real DAMAGE_LEVEL = 50.00
private constant real STUN_DURATION = 1.00
private constant real BUFF_DURATION = 12.00
private constant real SPELL_AREA = 250.00
private constant real SUP_STUN_DURATION = 1.00
private constant real UP_AREA_EFFECT = 50.00
private constant string AREA_SFX = "war3mapImported\\Cutting Slam.mdx"
private constant string HIT_SFX = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local real dmg = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
local effect e = AddSpecialEffect(AREA_SFX,x,y)
local real st = STUN_DURATION
local real a = SPELL_AREA
local real sfxsize = 1.4
local real d
local unit temp
local real xt
local real yt
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
if ulvl != 0 then
set a = a + UP_AREA_EFFECT * ulvl
set sfxsize = sfxsize + 0.1 * ulvl
endif
call BlzSetSpecialEffectScale(e,sfxsize)
if IsUpgradeSuperior(u,UPGRADE_ID) then
set st = st + SUP_STUN_DURATION
endif
call BlzSetSpecialEffectColor(e,255,0,0)
call DestroyEffect(e)
call GroupEnumUnitsInRange(g,x,y,a,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
set xt = GetUnitX(temp)
set yt = GetUnitY(temp)
set d = Distance(x,y,xt,yt)
if d > 75 then
call KPJUnit.create(temp,d - 75,Angle(xt,yt,x,y),0.8,0,KPJDefaultConfig4,KPJ_TYPE_KNOCKBACK)
endif
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypePhysicalAoe,"",0,0)
call Status.Add(STATUS_STUN,temp,st,Status_EFFECT[STATUS_STUN])
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"chest"))
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set e = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,BoneCrusher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01P',PRELOAD_SECOND)
call Preload(AREA_SFX)
call Preload(HIT_SFX)
endfunction
endscope
scope UncontrolledAnger initializer init
globals
private constant integer SPELL_ID = 'BRA2'
private constant integer UPGRADE_ID = 'BRI2'
private constant integer AS_BASE = 35
private constant integer AS_LEVEL = 5
private constant real MS_BASE = 0.25
private constant real HP_COST_BASE = 100.00
private constant real CURRENT_HP = 0.12
private constant real MINIMUM_DAMAGE = 50.00
private constant real BUFF_DURATION = 3.75
private constant real UP_LIFESTEAL = 0.10
private constant string ABSORB_SFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
endglobals
private function GetAttackSpeed takes integer lvl returns integer
return AS_BASE + AS_LEVEL * lvl
endfunction
struct UncontrolledAngerAttack extends array
real damage
effect sfx
boolean crit
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Hero h = GetUnitData(b.target,"HeroIndex")
call DestroyEffect(sfx)
if h.heroAI != 0 then
set h.heroAI.courageAdd = h.heroAI.courageAdd - 50
endif
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Hero h = GetUnitData(b.target,"HeroIndex")
set damage = 0
set crit = false
set sfx = AddSpecialEffectTarget(ABSORB_SFX,b.target,"weapon")
if h.heroAI != 0 then
set h.heroAI.courageAdd = h.heroAI.courageAdd + 50
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Uncontrolled Anger Attack"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct UncontrolledAnger extends array
boolean absorbed
Movespeed ms
integer as
boolean crit
real life
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call SetUnitVertexColor(b.target,255,255,255,255)
if life != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,-life,0)
set life = 0
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set absorbed = false
if ulvl != 0 then
set life = UP_LIFESTEAL + UP_LIFESTEAL * ulvl
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,life,0)
else
set life = 0
endif
set ms = Movespeed.create(b.target,MS_BASE,0)
set as = GetAttackSpeed(b.level)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call SetUnitVertexColor(b.target,255,50,50,255)
if GetHeroMasteryType(b.target) == 3 then
set crit = true
else
set crit = false
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01Q'
set BUFF_DATA.BuffID = 'B00R'
set BUFF_DATA.Name = "CounterAssault"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function OnPostDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local UncontrolledAnger b = 0
local UncontrolledAngerAttack b2 = 0
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,UncontrolledAnger.buff).buffAllocIndex
if b != 0 and not data.isAbsorbed then
if not b.absorbed and IsUnitType(data.source,UNIT_TYPE_HERO) and data.damageMod >= MINIMUM_DAMAGE then
set b.absorbed = true
set b2 = UnitAddBuff(data.target,data.target,10.00,UncontrolledAngerAttack.buff,0,0).buffAllocIndex
set b2.damage = data.damageMod
set b2.crit = b.crit
set data.damageMod = 0
set data.isAbsorbed = true
endif
endif
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local UncontrolledAngerAttack b2 = 0
local integer c = 0
set b2 = GetUnitBuff(data.source,UncontrolledAngerAttack.buff).buffAllocIndex
if b2 != 0 and data.dmgType == udg_DamageTypeAttack and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) then
set data.add = data.add + b2.damage
set data.trueAttack = true
if b2.crit then
set c = 1
set data.criticalChanceAdd = data.criticalChanceAdd + 25.00
endif
call DestroyEffect(AddSpecialEffectTarget(ABSORB_SFX,data.target,"overhead"))
call UnitRemoveBuff(data.source,UncontrolledAngerAttack.buff)
call CodeDamage.Damage(data.source,data.source,b2.damage,udg_DamageTypeHeal,"UA_Heal",c,0)
endif
if data.codeDmg.codeName == "UA_Heal" then
if data.codeDmg.data == 1 then
set data.criticalChanceAdd = data.criticalChanceAdd + 25.00
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real hp = GetUnitState(u,UNIT_STATE_LIFE) * CURRENT_HP
if not IsUpgradeSuperior(u,UPGRADE_ID) then
call UnitRemoveHp(u,hp)
endif
call UnitAddBuff(u,u,BUFF_DURATION,UncontrolledAnger.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
public function UA_KeyPress takes nothing returns nothing
local player p = GetTriggerPlayer()
local Hero h = GetPlayerHero(p)
local unit u = h.hero
local Ability a
local real hp
call SyncSelections()
if IsUnitSelected(u,p) then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
if not a.isOnCooldown() then
if IsUnitDisabled(u) then
call a.forceCooldown()
set hp = GetUnitState(u,UNIT_STATE_LIFE) * CURRENT_HP
if not IsUpgradeSuperior(u,UPGRADE_ID) then
call UnitRemoveHp(u,hp)
endif
call UnitAddBuff(u,u,BUFF_DURATION,UncontrolledAnger.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\BattleRoar\\RoarCaster.mdl",h.hero,"origin"))
endif
endif
endif
set p = null
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local trigger t
if up.upID == 'BRI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 2 then
set t = CreateTrigger()
call BlzTriggerRegisterPlayerKeyEvent(t,GetOwningPlayer(up.ownerHero.hero),OSKEY_W,0,true)
call TriggerAddAction(t,function UA_KeyPress)
set t = null
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call UncontrolledAnger.Initialize()
call UncontrolledAngerAttack.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call DamageEvent.RegisterPostCalculation(Filter(function OnPostDamage))
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,BoneCrusher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01Q',PRELOAD_SECOND)
call Preload(ABSORB_SFX)
endfunction
endscope
scope CrushingBlows initializer init
globals
private constant integer SPELL_ID = 'BRA3'
private constant integer UPGRADE_ID = 'BRI3'
private constant real DAMAGE_BASE = 15.00
private constant real DAMAGE_LEVEL = 5.00
private constant real SPLASH_AREA = 500.00
private constant real BONUS_AREA = 250.00
private constant integer IGNORE_ARMOR_BASE = 1
private constant integer IGNORE_ARMOR_LEVEL = 1
private constant string SPLASH_SFX = "Abilities\\Spells\\Other\\Stampede\\MissileDeath.mdx"
endglobals
private function GetIgnoreArmor takes integer ulvl returns integer
return IGNORE_ARMOR_BASE + IGNORE_ARMOR_LEVEL * ulvl
endfunction
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct CrushingBlowsSplash extends array
real splash
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
//call DestroyEffect(sfx)
//set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set splash = 0.60 + 0.10 * b.level
//set sfx = AddSpecialEffectTarget(ABSORB_SFX,b.target,"weapon")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Crushing Blows Splash"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local CrushingBlowsSplash b
local InnerWrath iw
local Ability ab
local DamageOptions op
local real splash
local integer lvl
local group g
local unit temp
local real x
local real y
local real a
local real area
local player p
local real dmg
if data.dmgType == udg_DamageTypeAttack and data.damageMod != 0 and data.mainAttack then
set lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
if BlzGetUnitAbilityCooldownRemaining(data.source,SPELL_ID) == 0 and lvl != 0 then
call BlzStartUnitAbilityCooldown(data.source,SPELL_ID,9 - 1 * lvl)
set g = NewGroup()
set x = GetUnitX(data.source)
set y = GetUnitY(data.source)
set p = GetOwningPlayer(data.source)
set area = SPLASH_AREA
set splash = (0.60 + 0.10 * lvl)
if IsUpgradeSuperior(data.source,UPGRADE_ID) then
set splash = splash + 0.60
set area = area + 150
endif
set dmg = data.damageMod * splash
set a = GetUnitFacing(data.source)
call GroupEnumUnitsInRange(g,x,y,area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and temp != data.target then
if IsPointInSightOfAngle(a,x,y,GetUnitX(temp),GetUnitY(temp),90.00) then
set op = DamageOptions.create()
set op.notCritical = true
call CodeDamage.Damage(data.source,temp,dmg,udg_DamageTypeAttack,"",0,op)
call DestroyEffect(AddSpecialEffectTarget(SPLASH_SFX,temp,"overhead"))
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
endif
if data.damageMod >= 50.00 then
set iw = GetUnitBuff(data.target,InnerWrath.buff).buffAllocIndex
if iw != 0 and iw.cd != 0.0 then
set ab = Ability.GetUnitAbilityByID('BRA2',data.target)
if ab.isOnCooldown() then
call ab.addCooldownRemaining(-iw.cd)
endif
endif
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local group g
local unit temp
local player p
local integer c
local real area
local integer ulvl
local integer lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
if lvl != 0 and data.mainAttack then
if not IsUnitIllusion(data.source) and data.dmgType == udg_DamageTypeAttack and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) and not IsUnitType(data.target,UNIT_TYPE_MECHANICAL) then
set g = NewGroup()
set c = 0
set p = GetOwningPlayer(data.source)
set area = BONUS_AREA
if IsUpgradeSuperior(data.source,UPGRADE_ID) then
set area = area + 150
endif
call GroupEnumUnitsInRange(g,GetUnitX(data.target),GetUnitY(data.target),area,null)
set ulvl = GetUpgradeSkillLevel(data.source,UPGRADE_ID)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
set c = c + 1
endif
endloop
set data.add = data.add + GetDamage(lvl) * c
if ulvl != 0 then
set data.ignoreArmor = data.ignoreArmor + GetIgnoreArmor(ulvl)
endif
call ReleaseGroup(g)
set g = null
set p = null
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call CrushingBlowsSplash.Initialize()
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call DamageEvent.RegisterDamage(Filter(function OnDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,BoneCrusher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope InnerWrath initializer init
globals
private constant integer SPELL_ID = 'BRA4'
private constant integer UPGRADE_ID = 'BRI4'
private constant integer STRENGHT_BASE = 5
private constant integer DAMAGE_BASE = 20
private constant real BUFF_DURATION = 10.00
private constant real COOLDOWN_BASE = 0.25
private constant real UP_DURATION = 5.00
private constant string AREA_SFX = "war3mapImported\\RedCharkaExplosion.mdx"
endglobals
private function GetStrenght takes integer lvl returns integer
return STRENGHT_BASE + STRENGHT_BASE * lvl
endfunction
private function GetDamage takes integer lvl returns integer
return DAMAGE_BASE + DAMAGE_BASE * lvl
endfunction
private function GetCDReduction takes integer lvl returns real
return COOLDOWN_BASE + COOLDOWN_BASE * lvl
endfunction
struct InnerWrath extends array
integer str
integer dmg
real cd
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,-str,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set str = GetStrenght(b.level)
set dmg = GetDamage(b.level)
if b.int == 0 then
set cd = GetCDReduction(b.level)
else
set cd = 0.0
endif
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,str,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01T'
set BUFF_DATA.BuffID = 'B00U'
set BUFF_DATA.Name = "Inner Warth"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real d = BUFF_DURATION
local group g
local unit temp
local player p
local real x
local real y
call DestroyEffect(AddSpecialEffectTarget(AREA_SFX,u,"origin"))
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set d = d + UP_DURATION
endif
call UnitAddBuff(u,u,d,InnerWrath.buff,lvl,0)
if GetHeroMasteryType(u) == 1 then
set g = NewGroup()
set p = GetOwningPlayer(u)
set x = GetUnitX(u)
set y = GetUnitY(u)
call GroupEnumUnitsInRange(g,x,y,500.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ALLIED(temp,p) and temp != u then
call UnitAddBuff(u,temp,d,InnerWrath.buff,lvl,1)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call InnerWrath.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,BoneCrusher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01T',PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
library Zealot initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HZE1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'ZEI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Blade Expertise"
set up.Text = "Increases |c00b4b4b4Tearing Slash|r distance and speed."
set up.SupText = "Converts |c00b4b4b4Tearing Slash|r damage type to |c00d1d1d1Attack Damage|r type (do not applies on attack effects)."
set up.LevelData1 = "+50 Distance and 10 Speed."
set up.LevelData2 = "+100 Distance and 20 Speed."
set up.LevelData3 = "+150 Distance and 30 Speed."
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'ZEI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Dark Persecutor"
set up.Text = "Increases |c00b4b4b4Berserk Shadow|r base movement speed."
set up.SupText = "|c00b4b4b4Berserker Shadow|r gains 100% of the zealot's Hp and Armor."
set up.LevelData1 = "+40 Movement"
set up.LevelData2 = "+50 Movement"
set up.LevelData3 = "+60 Movement"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'ZEI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Killing Spree"
set up.Text = "|c00b4b4b4Killer Instinct|r also increases |c00ffff95Resistance|r while is active."
set up.SupText = "|c00b4b4b4Killer Instinct|r also increases |c00ffff95Lifesteal|r by 25%."
set up.LevelData1 = "+25(3.9%) Resistance"
set up.LevelData2 = "+50(7.8%) Resistance"
set up.LevelData3 = "+75(11.7%) Resistance"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'ZEI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Fierce Bloodline"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HZE1'
set d.Name = "Zealot"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNHeroBlademaster.blp"
set d.WinAni = "stand victory"
set d.Block = 0
set d.Evasion = 50
set d.Resistance = 50
set d.LifeRegen = 1.1
set d.ManaRegen = 0.8
set d.Armor = 5
set d.AttackRange = 125
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'ZEA1'
set d.HeroAbility2 = 'ZEA2'
set d.HeroAbility3 = 'ZEA3'
set d.HeroAbility4 = 'ZEA4'
set d.ChooseIconID = 'c021'
set d.ChooseDummy = 'dh21'
set d.spellDamageLevel = 4
set d.attackDamageLevel = 7
set d.healingLevel = 2
set d.survivavilityLevel = 4
set d.movementLevel = 4
set d.crowdControlLevel = 5
set d.HeroFaction = Game.FACTION_ORC
set d.InfoID = 'HZEI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope TearingSlash initializer init
globals
private constant integer SPELL_ID = 'ZEA1'
private constant integer EXTRA_ID = 'A09U'
private constant integer UPGRADE_ID = 'ZEI1'
private constant real DAMAGE_BASE = 60.00
private constant real DAMAGE_LEVEL = 60.00
private constant real AREA_OF_EFFECT = 120.00
private constant real DISTANCE = 850.00
private constant real BUFF_DURATION = 5.0
private constant real UP_DISTANCE = 50.00
private constant real UP_SPEED = 10.00
private constant string MISSILE_SFX = "war3mapImported\\BladeBeamFinal.mdx"
private constant string TARGET_SFX = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct TearingSlash extends array
integer ar
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,ar,0,true)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ar = 2 * b.level
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-ar,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A09T'
set BUFF_DATA.BuffID = 'B03M'
set BUFF_DATA.Name = "Tearing Slash"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct TearingSlashMissile extends array
integer dmgType
private static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = thistype[missile]
if FILT_UNIT_ENEMY(hit,missile.owner) then
call UnitAddBuff(hit,missile.source,BUFF_DURATION,TearingSlash.buff,missile.level,0)
call CodeDamage.Damage(missile.source,hit,missile.damage,dmgType,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,hit,"chest"))
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real x, real y, integer op returns Missile
local real xu = GetUnitX(source)
local real yu = GetUnitY(source)
local real a = Angle(xu,yu,x,y)
local real d = DISTANCE
local integer ulvl
local integer lvl
local real dmg
local Missile missile
if op == 2 then
set source = GetPlayerHero(GetOwningPlayer(source)).hero
endif
set ulvl = GetUpgradeSkillLevel(source,UPGRADE_ID)
set d = d + UP_DISTANCE * ulvl
set x = xu + d * Cos(a)
set y = yu + d * Sin(a)
set missile = Missile.createXYZ(xu,yu,50.00,x,y,50.00)
set missile.source = source
set lvl = GetUnitAbilityLevel(source,SPELL_ID)
set dmg = GetDamage(lvl)
set missile.level = lvl
set missile.collision = AREA_OF_EFFECT
set missile.owner = GetOwningPlayer(source)
if op == 1 then
set missile.damage = dmg
else
set missile.damage = dmg / 2
endif
set missile.speed = 25.00 + UP_SPEED * ulvl
set missile.model = MISSILE_SFX
set missile.scale = 1.3
call SetUnitVertexColor(missile.dummy,255,25,0,255)
if IsUpgradeSuperior(source,UPGRADE_ID) then
set TearingSlashMissile[missile].dmgType = udg_DamageTypeAttack
else
set TearingSlashMissile[missile].dmgType = udg_DamageTypePhysicalAoe
endif
call TearingSlashMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
call SetupMissile(u,x,y,1)
set u = null
endfunction
private function onCast2 takes nothing returns nothing
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
call SetupMissile(GetTriggerUnit(),x,y,2)
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call TearingSlash.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCast2)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Zealot_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope BerserkerClone initializer init
globals
private constant integer SPELL_ID = 'ZEA2'
private constant integer UPGRADE_ID = 'ZEI2'
private constant integer DUMMY_ID = 'n019'
private constant integer ABI1_ID = 'A09U'
private constant integer ABI4_ID = 'A09V'
private constant real DURATION = 15.00
private constant real DAMAGE_FACTOR_BASE = 0.15
private constant real DAMAGE_FACTOR_LVL = 0.05
private constant real AC_BASE = 1.00
private constant real HEAL_BASE = 75.00
private constant real HEAL_LVL = 50.00
private constant integer UP_SPEED = 30
private constant string SUMMON_SFX = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_FACTOR_BASE + DAMAGE_FACTOR_LVL * lvl
endfunction
private function GetHeal takes integer lvl returns real
return HEAL_BASE + HEAL_LVL * lvl
endfunction
struct BerserkClone extends array
implement Alloc
unit u
unit clone
real multiplier
timer time
integer level
Movespeed ms
public static method create takes unit caster returns thistype
local thistype this = thistype.allocate()
local real xu = GetUnitX(caster)
local real yu = GetUnitY(caster)
local real a = GetRandomReal(1,360) * bj_DEGTORAD
local real x = xu + 125 * Cos(a)
local real y = yu + 125 * Sin(a)
local integer ulvl = GetUpgradeSkillLevel(caster,UPGRADE_ID)
local player p = GetOwningPlayer(caster)
call DestroyEffect(AddSpecialEffect(SUMMON_SFX,x,y))
set u = caster
set multiplier = 0.50
set clone = CreateUnit(p,DUMMY_ID,x,y,GetUnitFacing(u))
set level = GetUnitAbilityLevel(caster,SPELL_ID)
set time = NewTimer()
call TimerStart(time,DURATION,false,null)
call SetUnitData(u,"BerserkC",this)
call SetUnitData(clone,"BerserkC",this)
call UnitApplyTimedLife(clone,'BTLF',DURATION)
call LockIndex(clone,true)
if IsUpgradeSuperior(u,UPGRADE_ID) then
set multiplier = 1.0
endif
if GetUnitAbilityLevel(u,'ZEA1') == 0 then
call BlzUnitDisableAbility(clone,ABI1_ID,true,false)
endif
if GetUnitAbilityLevel(u,'ZEA4') == 0 then
call BlzUnitDisableAbility(clone,ABI4_ID,true,false)
endif
call BlzSetUnitMaxHP(clone,R2I(BlzGetUnitMaxHP(u) * multiplier))
call BlzSetUnitArmor(clone,BlzGetUnitArmor(u) * multiplier)
call BlzSetUnitBaseDamage(clone,(40 + 20 * level) + R2I(GetHeroAgi(u,true) * GetDamage(level)),0)
call BlzSetUnitAttackCooldown(clone,AC_BASE,0)
if ulvl != 0 then
set ms = Movespeed.create(clone,0,UP_SPEED + 10 * ulvl)
endif
set p = null
return this
endmethod
public method destroy takes nothing returns nothing
local Buff b = GetUnitBuff(u,KillerInstinct.buff)
local Ability a
local real heal
call SetUnitData(u,"BerserkC",0)
set b.int = 0
call ReleaseTimer(time)
if ms != 0 then
call ms.destroy()
endif
if UnitAlive(u) then
set heal = GetHeal(level)
if GetHeroMasteryType(u) == 1 then
set heal = heal + BlzGetUnitMaxHP(clone) * 0.10
endif
call CodeDamage.Damage(u,u,heal,udg_DamageTypeHeal,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(SUMMON_SFX,u,"chest"))
endif
if GetHeroMasteryType(u) == 3 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
if a.isOnCooldown() then
call a.addCooldownRemaining(-TimerGetRemaining(time))
endif
endif
call RemoveUnit(clone)
call DestroyUnitIndex(clone)
call DestroyEffect(AddSpecialEffect(SUMMON_SFX,GetUnitX(clone),GetUnitY(clone)))
set u = null
set ms = 0
set time = null
call this.deallocate()
endmethod
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local fogmodifier fg = tb.fogmodifier[1]
call FogModifierStop(fg)
call DestroyFogModifier(fg)
call Status.Remove(STATUS_HIDE,u)
call Status.Remove(STATUS_INVULNERABLE,u)
call BerserkClone.create(u)
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set t = null
set u = null
set fg = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local BerserkClone bc = GetUnitData(u,"BerserkC")
local Table tb = Table.create()
if bc != 0 then
call bc.destroy()
endif
set tb.fogmodifier[1] = CreateFogModifierRadius(GetTriggerPlayer(),FOG_OF_WAR_VISIBLE,GetUnitX(u),GetUnitY(u),800,true,false)
call FogModifierStart(tb.fogmodifier[1])
set tb.unit[0] = u
call Status.Add(STATUS_HIDE,u,0,0)
call Status.Add(STATUS_INVULNERABLE,u,0,0)
call TimerStart(NewTimerEx(tb),0.50,false,function Callback)
call DestroyEffect(AddSpecialEffect(SUMMON_SFX,GetUnitX(u),GetUnitY(u)))
set u = null
endfunction
private function onDeath takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id = GetUnitTypeId(u)
local BerserkClone bc
if id == DUMMY_ID then
set bc = GetUnitData(u,"BerserkC")
if bc != 0 then
call bc.destroy()
endif
endif
set u = null
endfunction
private function onPreDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Hero h
if data.dmgType == udg_DamageTypeAttack then
if GetUnitTypeId(data.source) == DUMMY_ID then
set h = GetPlayerHero(GetOwningPlayer(data.source))
if GetHeroMasteryType(h.hero) == 3 then
set udg_DamageEventSource = h.hero
set data.source = h.hero
set data.allowOrbs = true
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function onDeath)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Zealot_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(SUMMON_SFX)
endfunction
endscope
scope KillerInstinct initializer init
globals
private constant integer SPELL_ID = 'ZEA3'
private constant integer UPGRADE_ID = 'ZEI3'
private constant integer SPEED_BASE = 30
private constant integer SPEED_LEVEL = 10
private constant real PERIOD = 0.50
private constant real HP_BASE = 30.00
private constant real HP_LEVEL = 10.00
private constant real UP_RESISTANCE = 25.00
private constant real SUP_LIFESTEAL = 0.25
endglobals
private function GetSpeed takes integer lvl returns integer
return SPEED_BASE + SPEED_LEVEL * lvl
endfunction
private function GetHp takes integer lvl returns real
return HP_BASE + HP_LEVEL * lvl
endfunction
struct KillerInstinct extends array
integer as
real hpcost
real res
boolean ls
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int == -1 or b.int > 0 then
call UnitRemoveHp(b.target,hpcost/2)
else
call UnitRemoveHp(b.target,hpcost)
endif
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
if b.int == -1 then
call UnitRemoveAbility(b.target,'A09W')
endif
call AddUnitAnimationProperties(b.target,"alternate",false)
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-res,0)
set res = 0
endif
if ls then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,-SUP_LIFESTEAL,0)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl
set as = GetSpeed(b.level)
set hpcost = GetHp(b.level)/2
if b.int == -1 then
call UnitAddAbility(b.target,'A09W')
call UnitMakeAbilityPermanent(b.target,true,'A09W')
else
set ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
if ulvl != 0 then
set res = UP_RESISTANCE * ulvl
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,res,0)
endif
set ls = IsUpgradeSuperior(b.target,UPGRADE_ID)
if ls then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,SUP_LIFESTEAL,0)
endif
endif
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call AddUnitAnimationProperties(b.target,"alternate",true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Killer Instinct"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = PERIOD
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetUnitByIndex(GetTimerData(t))
local BerserkClone bc
if GetUnitAbilityLevel(u,'BEim') == 0 then
set bc = GetUnitData(u,"BerserkC")
call UnitRemoveBuff(u,KillerInstinct.buff)
if bc != 0 then
call UnitRemoveBuff(bc.clone,KillerInstinct.buff)
endif
endif
call ReleaseTimer(t)
set t = null
set u = null
endfunction
private function onOrder takes nothing returns nothing
local unit u = GetOrderedUnit()
local integer id = GetIssuedOrderId()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local BerserkClone bc
local timer t
if id == ORDER_immolation and lvl != 0 then
set bc = GetUnitData(u,"BerserkC")
call UnitAddBuff(u,u,999999,KillerInstinct.buff,lvl,bc)
if bc != 0 then
call UnitAddBuff(bc.clone,bc.clone,999999,KillerInstinct.buff,lvl,-1)
endif
elseif id == ORDER_unimmolation and lvl != 0 then
set t = NewTimerEx(GetUnitUserData(u))
call TimerStart(t,0.0,false,function callback)
set t = null
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call KillerInstinct.Initialize()
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function onOrder)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Zealot_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Ravager initializer init
globals
private constant integer SPELL_ID = 'ZEA4'
private constant integer UPGRADE_ID = 'ZEI4'
private constant integer ABI4_ID = 'A09V'
private constant real BUFF_DURATION = 4.00
private constant real SLOW = 0.60
private constant real DMG_BASE = 200.00
private constant real DMG_LEVEL = 50.00
private constant real MA_SPEED = 0.25
private constant string AREA_SFX = "war3mapImported\\FireNova.mdx"
private constant string SPIN_SFX = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
struct RavagerAttackDPS extends array
real dps
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dps,udg_DamageTypePhysicalOverTime,"",0,0)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dps = I2R(b.int) / 8.0
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0C2'
set BUFF_DATA.BuffID = 'B04K'
set BUFF_DATA.Name = "Ravager Attack Dps"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct RavagerAttackSlow extends array
Movespeed ms
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-0.40,0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A06N'
set BUFF_DATA.BuffID = 'B05E'
set BUFF_DATA.Name = "Ravager Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Ravager extends array
effect sfx1
private static method onFinish takes Buff b returns nothing
local group g
local player p
local real dmg
local unit temp
local effect sfx
local integer ulvl
if b.int != 1 then
set g = NewGroup()
set p = GetOwningPlayer(b.target)
set ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set dmg = GetDamage(GetUnitAbilityLevel(b.owner,SPELL_ID))
set sfx = AddSpecialEffect(AREA_SFX,GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectScale(sfx,0.50)
call DestroyEffect(sfx)
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),220,null)
if b.int == 2 then
set dmg = dmg / 2
endif
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call UnitAddBuff(temp,b.owner,BUFF_DURATION,RavagerAttackSlow.buff,0,0)
call Status.Add(STATUS_SILENCE,temp,BUFF_DURATION,Status_EFFECT[STATUS_SILENCE])
if GetUnitLifePercent(temp) <= 50 and ulvl != 0 then
call UnitAddBuff(temp,b.owner,4.0,RavagerAttackDPS.buff,0,R2I(dmg))
endif
call CodeDamage.Damage(b.owner,temp,dmg,udg_DamageTypePhysicalAoe,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set sfx = null
endif
endmethod
private static method onPeriodic takes Buff b returns nothing
local KPJUnit k = GetUnitData(b.target,"KPJ1")
if k != 0 then
if k.data != SPELL_ID then
set b.removeInside = true
endif
endif
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_INVULNERABLE,b.target)
call SetUnitTimeScale(b.target,1.0)
call SetUnitVertexColor(b.target,255,255,255,255)
call DestroyEffect(sfx1)
set sfx1 = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
call Status.Add(STATUS_INVULNERABLE,b.target,0,0)
call SetUnitTimeScale(b.target,0.68)
call SetUnitVertexColor(b.target,255,255,255,170)
set sfx1 = AddSpecialEffectTarget(SPIN_SFX,b.target,"weapon")
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Ravager"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real xt = GetSpellTargetX()
local real yt = GetSpellTargetY()
local AoE aoe
local KPJUnit k
set k = KPJUnit.create(u,Distance(x,y,xt,yt),Angle(x,y,xt,yt),0.70,500.00,KPJDefaultConfig,KPJ_TYPE_JUMP)
set k.data = SPELL_ID
call UnitAddBuff(u,u,0.70,Ravager.buff,0,0)
set aoe = AoE.create(xt,yt,null,220)
call BlzSetSpecialEffectColor(aoe.sfx,245,66,87)
call aoe.setTime(0.80)
set u = null
endfunction
private function onCast2 takes nothing returns nothing
local unit u = GetTriggerUnit()
local Hero h = GetPlayerHero(GetTriggerPlayer())
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real xh = GetUnitX(h.hero)
local real yh = GetUnitY(h.hero)
local real xt = GetSpellTargetX()
local real yt = GetSpellTargetY()
local AoE aoe
local KPJUnit k
set k = KPJUnit.create(u,Distance(x,y,xt,yt),Angle(x,y,xt,yt),0.55,500.00,KPJDefaultConfig,KPJ_TYPE_JUMP)
set k.data = SPELL_ID
call UnitAddBuff(u,h.hero,0.55,Ravager.buff,0,2)
set aoe = AoE.create(xt,yt,null,220)
call BlzSetSpecialEffectColor(aoe.sfx,220,66,87)
call aoe.setTime(0.80)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Ravager.Initialize()
call RavagerAttackSlow.Initialize()
call RavagerAttackDPS.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(ABI4_ID, function onCast2)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Zealot_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library Headhunter initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HHH1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'HHI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Long Spear"
set up.Text = "Increases |c00b4b4b4Piercing Spear|r travel distance and cast range."
set up.SupText = "|c00b4b4b4Piercing Spear|r skewers an extra enemy hero."
set up.LevelData1 = "+50 Range"
set up.LevelData2 = "+100 Range"
set up.LevelData3 = "+150 Range"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'HHI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Madness"
set up.Text = "|c00b4b4b4Frenzy|r add a bonus |c00ffff95Attack Strength|r."
set up.SupText = "|c00b4b4b4Frenzy|r removes all debuffs upon ending."
set up.LevelData1 = "+20(3.1%) Attack Strength"
set up.LevelData2 = "+30(4.6%) Attack Strength"
set up.LevelData3 = "+40(6.2%) Attack Strength"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'HHI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Hunter Pride"
set up.Text = "|c00b4b4b4Stack Heads|r charges increases the |c00ffff95Resistance|r."
set up.SupText = "Increases |c00b4b4b4Stack Heads|r max charges by 5 and increases the damage bonus by 50."
set up.LevelData1 = "+5(0.7%) Resistance"
set up.LevelData2 = "+10(1.5%) Resistance"
set up.LevelData3 = "+15(2.3%) Resistance"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'HHI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Thick Poison"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HHH1'
set d.Name = "Headhunter"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNHeadHunterBerserker.blp"
set d.WinAni = "attack"
set d.Block = 20
set d.Evasion = 20
set d.Resistance = 20
set d.LifeRegen = 2.0
set d.ManaRegen = 0.5
set d.Armor = 2
set d.AttackRange = 300
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'HHA1'
set d.HeroAbility2 = 'HHA2'
set d.HeroAbility3 = 'HHA3'
set d.HeroAbility4 = 'HHA4'
set d.ChooseIconID = 'c023'
set d.ChooseDummy = 'dh23'
set d.spellDamageLevel = 5
set d.attackDamageLevel = 6
set d.healingLevel = 4
set d.survivavilityLevel = 5
set d.movementLevel = 2
set d.crowdControlLevel = 2
set d.HeroFaction = Game.FACTION_ORC
set d.InfoID = 'HHHI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope PiercingSpear initializer init
globals
private constant integer SPELL_ID = 'HHA1'
private constant integer UPGRADE_ID = 'HHI1'
private constant real DAMAGE_BASE = 90.00
private constant real DAMAGE_LEVEL = 40.00
private constant real AREA_OF_EFFECT = 90.00
private constant real DISTANCE = 650.00
private constant real UP_DIST = 50.00
private constant real MA_COOLDOWN = 5.00
//private constant string MISSILE_SFX = "war3mapImported\\JavelinToss.mdx"
private constant string MISSILE_SFX = "war3mapImported\\SpearOfMars.mdx"
private constant string HIT_SFX = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
private KPJConfig PS_K
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct PiercingSpearMissile extends array
group g
integer c
private static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = thistype[missile]
local real sd
local real d
local real t
local real s
local Ability a
if FILT_UNIT_ENEMY(hit,missile.owner) and not IsUnitMagicImmune(hit) then
if not IsUnitInGroup(hit,g) then
call GroupAddUnit(g,hit)
if IsUnitType(hit,UNIT_TYPE_HERO) then
if GetHeroMasteryType(missile.source) == 3 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,missile.source)
call a.addCooldownRemaining(-MA_COOLDOWN)
endif
set c = c + 1
set d = Distance(GetUnitX(hit),GetUnitY(hit),missile.impact.x,missile.impact.y)
set t = (d/missile.speed) * 0.03125
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypePhysicalAoe,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,hit,"chest"))
set s = 2.0 + t
set sd = Status.Add(STATUS_STUN,hit,s,Status_EFFECT[STATUS_STUN])
if sd != 0 then
call KPJUnit.create(hit,d,missile.angle,t,0,PS_K,KPJ_TYPE_KNOCKBACK)
endif
if c == missile.data then
call ReleaseGroup(g)
set g = null
return true
endif
else
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypePhysicalAoe,"",0,0)
endif
endif
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real a returns Missile
local real xu = GetUnitX(source)
local real yu = GetUnitY(source)
local real d = DISTANCE + (UP_DIST * GetUpgradeSkillLevel(source,UPGRADE_ID))
local real x = xu + d * Cos(a)
local real y = yu + d * Sin(a)
local Missile missile = Missile.createXYZ(xu,yu,50.00,x,y,50.00)
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local integer ulvl
set missile.source = source
set missile.level = lvl
set missile.damage = GetDamage(lvl)
set missile.collision = AREA_OF_EFFECT
set missile.owner = GetOwningPlayer(source)
set missile.speed = 28.00
set missile.model = MISSILE_SFX
set missile.scale = 1.5
if IsUpgradeSuperior(source,UPGRADE_ID) then
set missile.data = 2
else
set missile.data = 1
endif
call PiercingSpearMissile.launch(missile)
set PiercingSpearMissile[missile].g = NewGroup()
set PiercingSpearMissile[missile].c = 0
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real a = Angle(GetUnitX(u),GetUnitY(u),x,y)
call SetupMissile(u,a)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
local AbilityTag t
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
set PS_K = KPJConfig.create()
set PS_K.friction = 0
set PS_K.gravity = 0.0
set PS_K.disable = false
set PS_K.hardDisable = false
set PS_K.killTrees = true
set PS_K.ignorePath = false
set PS_K.sfxModel = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl"
set PS_K.sfxTime = 0.08
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Headhunter_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope Frenzy initializer init
globals
private constant integer SPELL_ID = 'HHA2'
private constant integer UPGRADE_ID = 'HHI2'
private constant integer SPEED_BASE = 90
private constant integer SPEED_LEVEL = 20
private constant integer ATTACK_RANGE = 300
private constant real HP_COST_BASE = 20.00
private constant real HP_COST_LVL = 5.00
private constant real BUFF_DURATION = 4.00
private constant real UP_ASTR = 10.00
private constant real MA_DURATION = 1.0
private constant string TARGET_SFX = "Abilities\\Spells\\Orc\\Bloodlust\\BloodlustTarget.mdl"
endglobals
private function GetSpeed takes integer lvl returns integer
return SPEED_BASE + SPEED_LEVEL * lvl
endfunction
struct Exhaust extends array
real life
boolean mast
integer as
real astr
integer ar
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if mast then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call AddHeroAttackRange(b.target,-ar)
if astr != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,-astr,0)
set astr = 0
endif
endif
set mast = false
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if life != 0 then
call UnitRemoveHp(b.target,life)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Frenzy f = b.int
if f.ac != 0 then
set life = ((HP_COST_BASE + HP_COST_LVL) * b.int) / 2
else
set life = 0
endif
if GetHeroMasteryType(b.target) == 2 then
set mast = true
set as = f.as / 2
set ar = f.ar / 2
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call AddHeroAttackRange(b.target,ar)
set astr = f.astr/2
if astr != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,astr,0)
endif
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01P'
set BUFF_DATA.BuffID = 'B00Q'
set BUFF_DATA.Name = "Exhaust"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Frenzy extends array
integer ac
integer as
real astr
integer ar
private static method onFinish takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\DispelMagic\\DispelMagicTarget.mdl",b.target,"overhead"))
call UnitDispelAllBuffs(b.target,BUFF_TYPE_NEGATIVE)
endif
call UnitAddBuff(b.target,b.target,3.0,Exhaust.buff,b.level,this)
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call AddHeroAttackRange(b.target,-ar)
if astr != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,-astr,0)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set ac = 0
set as = GetSpeed(b.level)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
set ar = 14
call AddHeroAttackRange(b.target,ar)
if ulvl != 0 then
set astr = UP_ASTR + UP_ASTR * ulvl
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,astr,0)
else
set astr = 0
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08J'
set BUFF_DATA.BuffID = 'B031'
set BUFF_DATA.Name = "Frenzy"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real d = BUFF_DURATION
if GetHeroMasteryType(u) == 2 then
set d = d + MA_DURATION
endif
call UnitAddBuff(u,u,d,Frenzy.buff,lvl,0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
local AbilityTag t
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call Frenzy.Initialize()
call Exhaust.Initialize()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Headhunter_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope StackHeads initializer init
globals
private constant integer SPELL_ID = 'HHA3'
private constant integer UPGRADE_ID = 'HHI3'
private constant integer EXTRA_ID = 'A02R'
public integer MAX_HEADS = 10
private constant real LIFESTEAL_BASE = 0.03
private constant real LIFESTEAL_LEVEL = 0.01
private constant real STUN_DURATION = 0.40
private constant real UP_RES = 5.00
private constant real SUP_DMG = 50.00
private constant string HIT_SFX = "Abilities\\Spells\\Orc\\Bloodlust\\BloodlustTarget.mdl"
endglobals
private function GetLifesteal takes integer lvl returns real
return LIFESTEAL_BASE + LIFESTEAL_LEVEL * lvl
endfunction
struct StackHeads extends array
integer heads
real res
real reslvl
real ls
real lslvl
Ability a
boolean missileLaunched
public method update takes nothing returns nothing
local integer ulvl = GetUpgradeSkillLevel(thisBuff.target,UPGRADE_ID)
set lslvl = GetLifesteal(thisBuff.level)
if ls != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,thisBuff.target,-ls,0)
endif
set ls = lslvl * heads
if ls != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,thisBuff.target,ls,0)
endif
if ulvl != 0 then
set reslvl = UP_RES * ulvl
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,thisBuff.target,-res,0)
endif
set res = reslvl * heads
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,thisBuff.target,res,0)
endif
endif
call a.abilityNumber.setValue(heads)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set heads = 0
set ls = 0
set res = 0
set a = GetHeroAbilityById(b.target,SPELL_ID)
set a.abilityNumber = AbilityNumber.create(a.objectID,b.target)
call a.abilityNumber.setValue(0)
set missileLaunched = false
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "StackHeads"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onStartAttack takes nothing returns nothing
local unit u = GetAttacker()
local unit t = GetTriggerUnit()
local Buff b
if GetUnitAbilityLevel(u,SPELL_ID) != 0 then
set b = GetUnitBuff(u,StackHeads.buff)
if BlzGetUnitAbilityCooldownRemaining(u,SPELL_ID) == 0 and StackHeads[b.buffAllocIndex].heads != 0 and not StackHeads[b.buffAllocIndex].missileLaunched then
if IsUnitType(t,UNIT_TYPE_HERO) then
call BlzSetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_PROJECTILE_SPEED,0,999999)
call BlzSetUnitWeaponIntegerField(u,UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE,0,0)
else
call BlzSetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_PROJECTILE_SPEED,0,1000)
call BlzSetUnitWeaponIntegerField(u,UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE,0,6)
endif
else
call BlzSetUnitWeaponRealField(u,UNIT_WEAPON_RF_ATTACK_PROJECTILE_SPEED,0,1000)
call BlzSetUnitWeaponIntegerField(u,UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE,0,6)
endif
endif
set u = null
set t = null
endfunction
private function AttackFix takes nothing returns nothing
if GetSpellAbilityId() == 'AHfa' then
call UnitRemoveAbility(GetTriggerUnit(), 'AHfa')
call BlzUnitDisableAbility(GetTriggerUnit(),'Aatk',true,false)
endif
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local integer lvl = GetLearnedSkillLevel()
local Buff b = GetUnitBuff(u,StackHeads.buff)
local StackHeads sb
local Ability a
local trigger t
if b != 0 then
set sb = b.buffAllocIndex
set b.level = lvl
call sb.update()
else
call UnitAddBuff(u,u,9999.00,StackHeads.buff,1,0)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED,function onStartAttack)
endif
if lvl == 1 then
set t = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t,GetOwningPlayer(u),EVENT_PLAYER_UNIT_SPELL_CHANNEL,null)
call TriggerAddCondition(t,function AttackFix)
set t = null
endif
set u = null
endfunction
struct HeadMissile extends array
implement Alloc
unit u
unit t
real d
Buff b
trigger tr
public static method create takes unit source, unit target, real damage, Buff buf returns thistype
local thistype this = thistype.allocate()
set u = source
set t = target
set d = damage
set b = buf
return this
endmethod
method destroy takes nothing returns nothing
set u = null
set t = null
call this.deallocate()
endmethod
endstruct
private function PeriodicHead takes nothing returns nothing
local Buff b = GetTimerData(GetExpiredTimer())
local StackHeads sb = b.buffAllocIndex
if sb.heads < MAX_HEADS then
set sb.heads = sb.heads + 1
if sb.heads > MAX_HEADS then
set sb.heads = MAX_HEADS
endif
call sb.update()
endif
endfunction
public function MasteryEffect takes unit source returns nothing
local Buff b = GetUnitBuff(source,StackHeads.buff)
local timer t
if b != 0 then
set t = NewTimerEx(b)
call TimerStart(t,10.0,true,function PeriodicHead)
set t = null
endif
endfunction
private function OnDummyDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer id = GetUnitTypeId(data.source)
local unit u
local HeadMissile m
local DamageOptions op
local Buff b
if id == 'HHH1' then
set b = GetUnitBuff(data.source,StackHeads.buff)
set StackHeads[b.buffAllocIndex].missileLaunched = true
set m = HeadMissile.create(data.source,data.target,data.damageMod,b)
if UnitAlive(data.target) then
set u = CreateUnit(GetOwningPlayer(data.target),'u002',GetUnitX(data.source),GetUnitY(data.source),0)
call RemoveGuardPosition(u)
call SetUnitUserData(u,m)
call IssueTargetOrderById(u, 852173,data.target)
call UnitApplyTimedLife(u,'BTLF',2.0)
else
call m.destroy()
endif
set u = null
endif
if id == 'u002' then
set m = GetUnitUserData(data.source)
set op = DamageOptions.create()
set b = m.b
set op.mainAttack = true
call CodeDamage.Damage(m.u,m.t,m.d,udg_DamageTypeAttack,"",0,op)
set StackHeads[b.buffAllocIndex].missileLaunched = false
call RemoveUnit(data.source)
call m.destroy()
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local Frenzy f
local Ability a
local real sd
if data.dmgType == udg_DamageTypeAttack and data.mainAttack and not data.isMiss then
set f = GetUnitBuff(data.source,Frenzy.buff).buffAllocIndex
if f != 0 then
set f.ac = f.ac + 1
endif
if GetUnitAbilityLevel(data.source,SPELL_ID) != 0 then
set b = GetUnitBuff(data.source,StackHeads.buff)
if b != 0 and IsUnitType(data.target,UNIT_TYPE_HERO) then
if StackHeads[b.buffAllocIndex].heads != 0 and StackHeads[b.buffAllocIndex].missileLaunched then
if BlzGetUnitAbilityCooldownRemaining(data.source,SPELL_ID) == 0 then
call BlzStartUnitAbilityCooldown(data.source,SPELL_ID,6 - b.level)
call UnitRemoveAbility(data.source,'A046')
set data.add = data.add + 30.00 + 10.00 * b.level
set sd = STUN_DURATION
if GetHeroMasteryType(data.source) == 1 then
set sd = sd + 0.50
endif
if IsUpgradeSuperior(data.source,UPGRADE_ID) then
set data.add = data.add + SUP_DMG
endif
call Status.Add(STATUS_STUN,data.target,sd,Status_EFFECT[STATUS_STUN])
set StackHeads[b.buffAllocIndex].heads = StackHeads[b.buffAllocIndex].heads - 1
call StackHeads[b.buffAllocIndex].update()
endif
endif
endif
endif
endif
endfunction
private function onDeath takes nothing returns nothing
local unit u = GetKillingUnit()
local Hero h = GetPlayerHero(GetOwningPlayer(u))
local Buff b
local StackHeads sb
local Ability a
if h != 0 then
set u = h.hero
if GetUnitAbilityLevel(u,SPELL_ID) != 0 then
set b = GetUnitBuff(u,StackHeads.buff)
set sb = b.buffAllocIndex
if sb.heads < MAX_HEADS then
if IsUnitType(GetDyingUnit(),UNIT_TYPE_HERO) then
set sb.heads = sb.heads + 3
endif
set sb.heads = sb.heads + 1
if sb.heads > MAX_HEADS then
set sb.heads = MAX_HEADS
endif
call sb.update()
endif
endif
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellLearn(SPELL_ID, function onLearn)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call DamageEvent.RegisterDummyDamage(Filter(function OnDummyDamage))
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function onDeath)
call StackHeads.Initialize()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Headhunter_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope EnvenomedSpears initializer init
globals
private constant integer SPELL_ID = 'HHA4'
private constant integer UPGRADE_ID = 'HHI4'
private constant real DAMAGE_BASE = 7.00
private constant real DAMAGE_LEVEL = 7.00
private constant real MOVE_BASE = 0.05
private constant real TIME_BASE = 1.00
private constant real TIME_LEVEL = 0.25
private constant real BUFF_DURATION = 4.00
private constant real UP_DURATION = 2.00
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetTime takes integer lvl returns real
return TIME_BASE + TIME_LEVEL * lvl
endfunction
struct EnvenomedSpears extends array
Movespeed ms
real dmg
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypePhysicalOverTime,"",0,0)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = GetDamage(b.level)
set ms = Movespeed.create(b.target,-(MOVE_BASE + MOVE_BASE * b.level),0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A087'
set BUFF_DATA.BuffID = 'B02V'
set BUFF_DATA.Name = "Envenomed Spears"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local real d
local Buff b
if data.dmgType == udg_DamageTypeAttack and not data.isMiss and data.allowOrbs then
set lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
if lvl != 0 and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) and not IsUnitType(data.target,UNIT_TYPE_MECHANICAL) then
set b = GetUnitBuff(data.target,EnvenomedSpears.buff)
if b == 0 then
set d = BUFF_DURATION
if GetUpgradeSkillLevel(data.source,UPGRADE_ID) != 0 then
set d = d + UP_DURATION
endif
call UnitAddBuff(data.target,data.source,d,EnvenomedSpears.buff,lvl,0)
else
set b.duration = b.duration + GetTime(lvl)
if b.level != lvl then
set EnvenomedSpears[b.buffAllocIndex].dmg = GetDamage(lvl)
set b.level = lvl
endif
endif
endif
endif
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local Buff b
if up.upID == UPGRADE_ID then
set EnvenomedSpears.BUFF_DATA.Dispelable = false
if GetHeroMasteryType(up.ownerHero.hero) == 1 then
call StackHeads_MasteryEffect(up.ownerHero.hero)
endif
endif
if up.upID == 'HHI3' then
set b = GetUnitBuff(up.ownerHero.hero,StackHeads.buff)
if b != 0 then
call StackHeads[b.buffAllocIndex].update()
endif
if IsUpgradeSuperior(up.ownerHero.hero,'HHI3') then
set StackHeads_MAX_HEADS = 20
endif
endif
if up.upID == 'HHI1' then
set a = Ability.GetUnitAbilityByID('HHA1',up.ownerHero.hero)
call a.addCastRange(50)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.hotkey = "Passive"
set d.objectID = SPELL_ID
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call EnvenomedSpears.Initialize()
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Headhunter_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library OgreSorcerer initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HOS1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'OSI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Smash"
set up.Text = "Increases |c00b4b4b4Crushing Rock|r Area of Effect."
set up.SupText = "Heroes affected by |c00b4b4b4Crushing Rock|r will be Shrinked, reducing the main attribute by 40 for 8s."
set up.LevelData1 = "+30 AoE"
set up.LevelData2 = "+60 AoE"
set up.LevelData3 = "+90 AoE"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'OSI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Sorcery"
set up.Text = "Reduce |c00b4b4b4Mage Skills|r abilities |c00ffff95Cooldown|r."
set up.SupText = "Increases the duration of |c00b4b4b4Fire Surge|r debuff by 6s."
set up.LevelData1 = "-1s Cooldown"
set up.LevelData2 = "-2s Cooldown"
set up.LevelData3 = "-3s Cooldown"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'OSI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Great Fortitude"
set up.Text = "|c00b4b4b4Battle Tendency|r add a bonus |c00ffff95Damage|r for the duration."
set up.SupText = "|c00b4b4b4Battle Tendency|r recovers 25% of the max Hp and Mp over the duration."
set up.LevelData1 = "+30 Damage"
set up.LevelData2 = "+50 Damage"
set up.LevelData3 = "+70 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'OSI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "United we Stand"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HOS1'
set d.Name = "Ogre Sorcerer"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNOgreMagi.blp"
set d.WinAni = "sleep"
set d.Block = 40
set d.Evasion = 0
set d.Resistance = 40
set d.LifeRegen = 1.0
set d.ManaRegen = 1.0
set d.Armor = 5
set d.AttackRange = 125
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'OSA1'
set d.HeroAbility2 = 'OSA2'
set d.HeroAbility3 = 'OSA3'
set d.HeroAbility4 = 'OSA4'
set d.ChooseIconID = 'c030'
set d.ChooseDummy = 'dh30'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 4
set d.healingLevel = 0
set d.survivavilityLevel = 4
set d.movementLevel = 3
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_ORC
set d.InfoID = 'HOSI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope CrushingRock initializer init
globals
private constant integer SPELL_ID = 'OSA1'
private constant integer UPGRADE_ID = 'OSI1'
private constant integer DUMMY_ID = 'h00C'
private constant real DAMAGE_BASE = 80.00
private constant real DAMAGE_LEVEL = 70.00
private constant real AREA_OF_EFFECT = 170.00
private constant real STUN_DURATION = 1.80
private constant real UP_AREA = 30.00
private constant real SUP_DURATION = 8.00
private constant integer SUP_ATT = 40
private constant string GROUND_SFX = "war3mapImported\\SandWaveDamage.mdx"
private constant string ROCK_SFX = "abilities\\weapons\\catapult\\catapultmissile.mdl"
private KPJConfig PS_K
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct Shrink extends array
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Hero h = GetUnitData(b.target,"HeroIndex")
if h != 0 then
if h.PrimaryAttribute == 1 then
call BonusStruct.Add(BONUS_TYPE_AGILITY,b.target,40,0,true)
elseif h.PrimaryAttribute == 2 then
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,b.target,40,0,true)
elseif h.PrimaryAttribute == 3 then
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,40,0,true)
endif
endif
call UnitRemoveAbility(b.target,'B01N')
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Hero h = GetUnitData(b.target,"HeroIndex")
if h != 0 then
if h.PrimaryAttribute == 1 then
call BonusStruct.Add(BONUS_TYPE_AGILITY,b.target,-40,0,true)
elseif h.PrimaryAttribute == 2 then
call BonusStruct.Add(BONUS_TYPE_INTELLIGENCE,b.target,-40,0,true)
elseif h.PrimaryAttribute == 3 then
call BonusStruct.Add(BONUS_TYPE_STRENGTH,b.target,-40,0,true)
endif
endif
call DummyCaster.castTarget('A009',GetOwningPlayer(b.owner),1,ORDER_bloodlust,b.target)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Shrink"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real x = tb.real[1]
local real y = tb.real[2]
local real a = tb.real[3]
local effect sfx = tb.effect[4]
local real d = tb.real[5]
local real h = tb.real[6]
local real s = tb.real[7]
local integer c = tb.integer[9]
local real xi = tb.real[10]
local real yi = tb.real[11]
local real z
local group g
local player p
local integer lvl
local real dmg
local unit temp
local AoE aoe
local boolean sup
set c = c + 1
set tb.integer[9] = c
call BlzSetSpecialEffectScale(sfx,0.5 + 0.09375 * c)
call BlzSetSpecialEffectTimeScale(sfx,0.5 + 0.02083 * c)
if s != 0 then
set x = x + s * Cos(a)
set y = y + s * Sin(a)
set tb.real[1] = x
set tb.real[2] = y
call BlzSetSpecialEffectX(sfx,x)
call BlzSetSpecialEffectY(sfx,y)
call BlzSetSpecialEffectZ(sfx,GetLocZ(x,y) + ParabolaZ(500.00,d,Distance(xi,yi,x,y)))
else
if c >= 16 then
set h = h - 16.66
else
set h = h + 16.66
endif
set tb.real[6] = h
call BlzSetSpecialEffectZ(sfx,GetLocZ(x,y) + h)
endif
if c == 32 then
set aoe = tb.integer[8]
set g = NewGroup()
set p = GetOwningPlayer(u)
set lvl = GetUnitAbilityLevel(u,SPELL_ID)
set dmg = GetDamage(lvl)
set sup = IsUpgradeSuperior(u,UPGRADE_ID)
call GroupEnumUnitsInRange(g,x,y,aoe.size * 2,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_STUN,temp,STUN_DURATION,Status_EFFECT[STATUS_STUN])
if sup then
if IsUnitType(temp,UNIT_TYPE_HERO) then
call UnitAddBuff(temp,u,6.0,Shrink.buff,0,0)
endif
endif
endif
endloop
call BlzSetSpecialEffectScale(sfx,0.2)
call DestroyEffect(sfx)
set sfx = AddSpecialEffect(ROCK_SFX,x,y)
call BlzSetSpecialEffectScale(sfx,2.0)
call DestroyEffect(sfx)
call aoe.destroy()
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
call ReleaseGroup(g)
set g = null
set p = null
endif
set u = null
set t = null
set sfx = null
endfunction
private function SpellTrigger takes unit u, real x, real y returns nothing
local real xu = GetUnitX(u)
local real yu = GetUnitY(u)
local real aoex = AREA_OF_EFFECT + UP_AREA * GetUpgradeSkillLevel(u,UPGRADE_ID)
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local AoE aoe = AoE.create(x,y,null,aoex)
local effect sfx
call BlzSetSpecialEffectColor(aoe.sfx,128,64,0)
set tb.unit[0] = u
set tb.real[1] = xu
set tb.real[2] = yu
set tb.real[3] = Angle(xu,yu,x,y)
set tb.real[5] = Distance(xu,yu,x,y)
set tb.real[6] = 0 //height
set tb.real[7] = tb.real[5] / 32 //speed
set tb.integer[8] = aoe
set tb.integer[9] = 0
set tb.real[10] = xu
set tb.real[11] = yu
set sfx = AddSpecialEffect(ROCK_SFX,xu,yu)
call BlzSetSpecialEffectColor(sfx,128,64,0)
call BlzSetSpecialEffectScale(sfx,0.5)
call BlzSetSpecialEffectTimeScale(sfx,0.5)
set tb.effect[4] = sfx
call TimerStart(t,0.03125,true,function callback)
set t = null
set sfx = null
endfunction
private function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Shrink.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,OgreSorcerer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(GROUND_SFX)
endfunction
endscope
scope MageSkills initializer init
globals
private constant integer SPELL_ID = 'OSA2'
private constant integer UPGRADE_ID = 'OSI2'
private constant integer EXTRA_ID = 'A0BX'
endglobals
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local integer lvl = GetLearnedSkillLevel()
local Hero h
local Ability a
if lvl == 1 then
set h = GetUnitData(u,"HeroIndex")
if h.heroAI != -1 then
call UnitAddAbility(u,'A0BU')
call UnitAddAbility(u,'A0BV')
call UnitAddAbility(u,'A0BW')
else
call UnitAddAbility(u,EXTRA_ID)
endif
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,'A0BU')
call UnitMakeAbilityPermanent(u,true,'A0BV')
call UnitMakeAbilityPermanent(u,true,'A0BW')
else
set h = GetPlayerHero(GetOwningPlayer(u))
endif
call SetUnitAbilityLevel(u,'A0BU',lvl)
call SetUnitAbilityLevel(u,'A0BV',lvl)
call SetUnitAbilityLevel(u,'A0BW',lvl)
if h != 0 then
set a = h.Abilities.integer[5]
call a.updateTooltip(true)
set a = h.Abilities.integer[6]
call a.updateTooltip(true)
set a = h.Abilities.integer[7]
call a.updateTooltip(true)
endif
set u = null
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if GetUnitAbilityLevel(data.target,'OSA3') != 0 and GetHeroMasteryType(data.target) == 1 then
set b = GetUnitBuff(data.target,BattleTendency.buff)
if b != 0 then
set data.mult = data.mult - 0.40
endif
endif
endif
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID then
set a = up.ownerHero.Abilities.integer[5]
call a.addFlatCooldown(-1.0)
set a = up.ownerHero.Abilities.integer[6]
call a.addFlatCooldown(-1.0)
set a = up.ownerHero.Abilities.integer[7]
call a.addFlatCooldown(-1.0)
endif
if up.upID == 'OSI1' then
set a = up.ownerHero.Abilities.integer[1]
call a.addAreaOfEffect(30.00)
endif
if up.upID == 'OSI4' and GetHeroMasteryType(up.ownerHero.hero) == 3 then
set a = up.ownerHero.Abilities.integer[7]
call a.addAreaOfEffect(100.00)
endif
if up.upID == 'OSI4' and GetHeroMasteryType(up.ownerHero.hero) == 1 then
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d = AbilityData.create()
set d.objectID = 'A0BU'
set d.hotkey = "Q"
set d = AbilityData.create()
set d.objectID = 'A0BV'
set d.hotkey = "W"
set d = AbilityData.create()
set d.objectID = 'A0BW'
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
call HERO_AI.HeroAddAbility('A0BU',5)
call HERO_AI.HeroAddAbility('A0BV',6)
call HERO_AI.HeroAddAbility('A0BW',7)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,OgreSorcerer_HERO_ID)
call PreloadGen.Add(EXTRA_ID,PRELOAD_SECOND)
endfunction
endscope
scope FireSurge initializer init
globals
private constant integer SPELL_ID = 'A0BU'
private constant integer UPGRADE_ID = 'OSI2'
private constant real DMG_BASE = 90.00
private constant real DMG_LEVEL = 30.00
private constant real DPS_BASE = 5.00
private constant real DPS_LEVEL = 10.00
private constant real AREA_OF_EFFECT = 150.00
private constant real DISTANCE = 1000.00
private constant real RES_LEVEL = 30.00
private constant real DURATION = 4.00
private constant real SUP_DURATION = 6.00
private constant string DPS_SFX = "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
private constant string MISSILE_SFX = "war3mapImported\\Firebolt Rough Major.mdx"
endglobals
private function GetResistance takes integer lvl returns real
return RES_LEVEL * lvl
endfunction
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private function GetDps takes integer lvl returns real
return DPS_BASE + DPS_LEVEL * lvl
endfunction
struct FireSurgeDps extends array
real resistance
real dps
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,resistance,0)
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dps,udg_DamageTypeMagicOverTime,"",0,0)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set resistance = GetResistance(b.level)
set dps = GetDps(b.level)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-resistance,0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0BZ'
set BUFF_DATA.BuffID = 'B04G'
set BUFF_DATA.Name = "Fire Surge"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Period = 1.00
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct FireSurgeMissile extends array
private static method onCollide takes Missile missile, unit hit returns boolean
local thistype this = thistype[missile]
if FILT_UNIT_ENEMY(hit,missile.owner) then
if missile.data == 1 then
call UnitAddBuff(hit,missile.source,DURATION + SUP_DURATION,FireSurgeDps.buff,missile.level,0)
else
call UnitAddBuff(hit,missile.source,DURATION,FireSurgeDps.buff,missile.level,0)
endif
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypeMagicAoe,"",0,0)
//call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,hit,"chest"))
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real x, real y returns Missile
local real xu = GetUnitX(source)
local real yu = GetUnitY(source)
local real a = Angle(xu,yu,x,y)
local integer ulvl
local integer lvl
local Missile missile
set ulvl = GetUpgradeSkillLevel(source,UPGRADE_ID)
set lvl = GetUnitAbilityLevel(source,SPELL_ID)
set x = xu + DISTANCE * Cos(a)
set y = yu + DISTANCE * Sin(a)
set missile = Missile.createXYZ(xu,yu,50.00,x,y,50.00)
set missile.source = source
set missile.level = lvl
set missile.collision = AREA_OF_EFFECT
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl)
set missile.speed = 25.00
set missile.model = MISSILE_SFX
set missile.scale = 1.0
if IsUpgradeSuperior(source,UPGRADE_ID) then
set missile.data = 1
endif
call FireSurgeMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
call SetupMissile(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function SPELL_INIT takes nothing returns nothing
call FireSurgeDps.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,OgreSorcerer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Empower initializer init
globals
private constant integer SPELL_ID = 'A0BV'
private constant integer UPGRADE_ID = 'OSI2'
private constant real DMG_BASE = 60.00
private constant real DMG_LEVEL = 20.00
private constant real DURATION = 10.00
private constant string TARGET_SFX = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
struct Empower extends array
integer count
real bonus
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set count = 0
set bonus = 60 + 40.00 * b.level
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01J'
set BUFF_DATA.BuffID = 'B00N'
set BUFF_DATA.Name = "Empower"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Empower b
if data.dmgType == udg_DamageTypeAttack then
set b = GetUnitBuff(data.source,Empower.buff).buffAllocIndex
if b != 0 then
set b.count = b.count + 1
if b.count == 4 then
set b.count = 0
call CodeDamage.Damage(data.source,data.target,b.bonus,udg_DamageTypeMagic,"",0,0)
call KPJUnit.create(data.target,0,0,1.0,500.00,KPJDefaultConfig3,KPJ_TYPE_JUMP)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl",data.target,"origin"))
endif
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
call UnitAddBuff(u,u,DURATION,Empower.buff,lvl,0)
set u = null
endfunction
private function SPELL_INIT takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call Empower.Initialize()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,OgreSorcerer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Earthquake initializer init
globals
private constant integer SPELL_ID = 'A0BW'
private constant integer UPGRADE_ID = 'OSI2'
private constant integer AS_BASE = 40
private constant integer AS_LEVEL = 10
private constant real MS_BASE = 0.40
private constant real MS_LEVEL = 0.10
private constant real AREA_OF_EFFECT = 320.00
private constant real DURATION = 6.00
private constant real MA_AOE = 100.00
private constant real MA_HPDMG = 0.04
private constant string AREA_SFX = "Abilities\\Spells\\Orc\\EarthQuake\\EarthQuakeTarget.mdl"
endglobals
private function GetAttackSpeedSlow takes integer lvl returns integer
return AS_BASE + AS_LEVEL * lvl
endfunction
private function GetSlow takes integer lvl returns real
return MS_BASE + MS_LEVEL * lvl
endfunction
struct EarthquakeDebuff extends array
Movespeed ms
integer as
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-GetSlow(b.level),0)
set as = GetAttackSpeedSlow(b.level)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0C1'
set BUFF_DATA.BuffID = 'B04I'
set BUFF_DATA.Name = "Earthquake"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real x = tb.real[1]
local real y = tb.real[2]
local integer lvl = tb.integer[3]
local group g = tb.group[4]
local player p = GetOwningPlayer(u)
local real time = tb.real[6]
local integer ma = tb.integer[7]
local real aoe = tb.real[8]
local unit temp
call GroupEnumUnitsInRange(g,x,y,aoe,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
if ma == 3 then
call CodeDamage.Damage(u,temp,BlzGetUnitMaxHP(temp) * MA_HPDMG,udg_DamageTypeMagicAoe,"",0,0)
endif
call UnitAddBuff(temp,u,1.0,EarthquakeDebuff.buff,lvl,0)
endif
endloop
call GroupClear(g)
set time = time + 0.50
set tb.real[6] = time
if time >= DURATION then
call DestroyEffect(tb.effect[5])
call tb.flush()
call tb.destroy()
call ReleaseGroup(g)
call ReleaseTimer(t)
endif
set t = null
set u = null
set g = null
set p = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local Table tb = Table.create()
local effect sfx
set tb.unit[0] = u
set tb.real[1] = GetSpellTargetX()
set tb.real[2] = GetSpellTargetY()
set tb.integer[3] = GetUnitAbilityLevel(u,SPELL_ID)
set tb.group[4] = NewGroup()
set sfx = AddSpecialEffect(AREA_SFX,tb.real[1],tb.real[2])
call BlzSetSpecialEffectTimeScale(sfx,1.3)
set tb.effect[5] = sfx
set tb.real[6] = 0.0
set tb.integer[7] = GetHeroMasteryType(u)
if GetHeroMasteryType(u) == 3 then
set tb.real[8] = AREA_OF_EFFECT + MA_AOE
else
set tb.real[8] = AREA_OF_EFFECT
endif
call TimerStart(NewTimerEx(tb),0.50,true,function Callback)
set u = null
set sfx = null
endfunction
private function SPELL_INIT takes nothing returns nothing
call EarthquakeDebuff.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,OgreSorcerer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope BattleTendency initializer init
globals
private constant integer SPELL_ID = 'OSA3'
private constant integer UPGRADE_ID = 'OSI3'
private constant integer MANA_REGEN_LVL = 2
private constant integer STRENGTH_LVL = 4
private constant real BUFF_DURATION = 4.00
private constant integer UP_DAMAGE = 20
private constant real MA_DURATION = 3.00
private constant real MA_DMG_RED = 0.40
endglobals
struct BattleTendency extends array
integer dmg
real lifeGain
real manaGain
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call SetUnitVertexColor(b.target,255,255,255,255)
call AddUnitNegativeStatusReduction(b.target,0,false)
if dmg != 0 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
set dmg = 0
endif
set lifeGain = 0.0
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if lifeGain != 0 then
call UnitAddHp(b.target,lifeGain)
call UnitAddMp(b.target,manaGain)
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
local real x
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set x = GetUnitState(b.target,UNIT_STATE_MAX_LIFE) * 0.25
set lifeGain = x / 8
set x = GetUnitState(b.target,UNIT_STATE_MAX_MANA) * 0.25
set manaGain = x / 8
endif
if ulvl != 0 then
set dmg = 10 + UP_DAMAGE * ulvl
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endif
call SetUnitVertexColor(b.target,200,75,200,255)
call AddUnitNegativeStatusReduction(b.target,0,true)
call DispelNegativeStatus(b.target)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Battle Tendency"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d
if GetHeroMasteryType(u) == 1 then
set d = BUFF_DURATION + MA_DURATION
else
set d = BUFF_DURATION
endif
call UnitAddBuff(u,u,d,BattleTendency.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
public function BT_KeyPress takes nothing returns nothing
local player p = GetTriggerPlayer()
local Hero h = GetPlayerHero(p)
local unit u = h.hero
local real d
local Ability a
call SyncSelections()
if IsUnitSelected(u,p) then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
if not a.isOnCooldown() then
if IsUnitDisabled(u) then
call a.forceCooldown()
if GetHeroMasteryType(u) == 1 then
set d = BUFF_DURATION + MA_DURATION
else
set d = BUFF_DURATION
endif
call UnitAddBuff(u,u,d,BattleTendency.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
//call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\BattleRoar\\RoarCaster.mdl",h.hero,"origin"))
endif
endif
endif
set p = null
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local trigger t
if GetLearnedSkillLevel() == 1 then
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,u,MANA_REGEN_LVL,0)
set t = CreateTrigger()
call BlzTriggerRegisterPlayerKeyEvent(t,GetOwningPlayer(u),OSKEY_E,0,true)
call TriggerAddAction(t,function BT_KeyPress)
set t = null
endif
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,u,MANA_REGEN_LVL,0)
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,STRENGTH_LVL,0,false)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call BattleTendency.Initialize()
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,OgreSorcerer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Bloodlust initializer init
globals
private constant integer SPELL_ID = 'OSA4'
private constant integer UPGRADE_ID = 'OSI4'
private constant integer DUMMY_ID = 'A0C3'
private constant integer AS_BASE = 10
private constant integer AS_LEVEL = 20
private constant integer SSTR_BASE = 20
private constant integer SSTR_LEVEL = 20
private constant real BUFF_DURATION = 18.00
private constant real UP_DURATION = 8.00
endglobals
private function GetAs takes integer lvl returns integer
return AS_BASE + AS_LEVEL * lvl
endfunction
private function GetSpellStr takes integer lvl returns integer
return SSTR_BASE + SSTR_LEVEL * lvl
endfunction
struct Bloodlust extends array
Movespeed ms
integer sstr
integer as
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call UnitRemoveAbility(b.target,'B04J')
call ms.destroy()
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,-sstr,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set sstr = GetSpellStr(b.level)
set as = GetAs(b.level)
set ms = Movespeed.create(b.target,0.07 + 0.03 * b.level,0)
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,sstr,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call DummyCaster.castTarget(DUMMY_ID,GetOwningPlayer(b.owner),1,ORDER_bloodlust,b.target)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Bloodlust"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real d = BUFF_DURATION
local group g
local player p
local unit temp
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 and (u == t) then
set d = d + UP_DURATION
endif
call UnitAddBuff(t,u,d,Bloodlust.buff,lvl,0)
if GetHeroMasteryType(u) == 2 then
set g = NewGroup()
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,GetUnitX(t),GetUnitY(t),400.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ALLIED(temp,p) and temp != t then
if temp == u then
call UnitAddBuff(temp,u,8.0 + UP_DURATION,Bloodlust.buff,0,0)
else
call UnitAddBuff(temp,u,8.0,Bloodlust.buff,0,0)
endif
endif
endloop
call ReleaseGroup(g)
set p = null
set g = null
endif
set t = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Bloodlust.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,OgreSorcerer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library VoodooPriest initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HVP1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'VPI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Shadow Sting"
set up.Text = "Increases |c00b4b4b4Shadow Ray|r base damage/heal."
set up.SupText = "|c00b4b4b4Shadow Ray|r deals 125% of the damage/heal to |c0000ced1Hexed|r units."
set up.LevelData1 = "+25 Damage/Heal"
set up.LevelData2 = "+50 Damage/Heal"
set up.LevelData3 = "+75 Damage/Heal"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'VPI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Strong Malefice"
set up.Text = "The |c00b4b4b4Cursed Totem|r emits an aura that slows the enemies movement speed."
set up.SupText = "Increases |c00b4b4b4Cursed Totem|r attack count by 2."
set up.LevelData1 = "20% Slow"
set up.LevelData2 = "30% Slow"
set up.LevelData3 = "40% Slow"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'VPI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Mask of Brutality"
set up.Text = "|c0099b4d1Voodoo Mask|r Gives/Steals |c00ffff95Damage|r."
set up.SupText = "|c00b4b4b4Voodoo Mask|r increases/decreases 20% damage output from target."
set up.LevelData1 = "+10 Damage"
set up.LevelData2 = "+20 Damage"
set up.LevelData3 = "+30 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'VPI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Oblivious Soul"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HVP1'
set d.Name = "Voodoo Priest"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNShadowHunterBeta.blp"
set d.WinAni = "stand victory"
set d.Block = 10
set d.Evasion = 20
set d.Resistance = 50
set d.LifeRegen = 0.5
set d.ManaRegen = 0.5
set d.Armor = 2
set d.AttackRange = 600
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'VPA1'
set d.HeroAbility2 = 'VPA2'
set d.HeroAbility3 = 'VPA3'
set d.HeroAbility4 = 'VPA4'
set d.ChooseIconID = 'c018'
set d.ChooseDummy = 'dh18'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 4
set d.healingLevel = 6
set d.survivavilityLevel = 5
set d.movementLevel = 2
set d.crowdControlLevel = 5
set d.HeroFaction = Game.FACTION_ORC
set d.InfoID = 'HVPI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ShadowRay initializer init
globals
private constant integer SPELL_ID = 'VPA1'
private constant integer UPGRADE_ID = 'VPI1'
private constant real DAMAGE_BASE = 70.00
private constant real DAMAGE_LEVEL = 20.00
private constant real UP_DMG = 25.00
private constant string TARGET_SFX = "Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayTarget.mdl"
private constant string MISSILE_SFX = "war3mapImported\\ShadowWaveMissile.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct ShadowRayChain extends array
private static method FilterUnits takes unit u, player p, Chain c returns boolean
return FILT_VALID_UNIT(u) and not IsUnitMagicImmune(u)
endmethod
private static method onHit takes Chain c returns nothing
local real d = c.damage
if IsUpgradeSuperior(c.caster,UPGRADE_ID) then
if Status.UnitHasStatus(STATUS_HEX,c.target) then
set d = d * 1.25
endif
endif
if IsUnitAlly(c.target,GetOwningPlayer(c.caster)) then
call CodeDamage.Damage(c.caster,c.target,d,udg_DamageTypeHeal,"",0,0)
else
call CodeDamage.Damage(c.caster,c.target,d,udg_DamageTypeMagicAoe,"",0,0)
endif
set c.damage = c.damage - (c.damage * 0.25)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,c.target,"overhead"))
if GetHeroMasteryType(c.caster) == 3 and c.caster != c.target then
call CodeDamage.Damage(c.caster,c.caster,d * 0.25,udg_DamageTypeHeal,"",0,0)
endif
endmethod
private static method onEnd takes Chain c returns nothing
endmethod
private static method ConfigLightning takes Chain c, unit origin returns nothing
local Lightning l = Lightning.create("SPLK",origin,c.target,-1,0,75.00,75.00)
call l.setLightColor(255,25,255,255)
call c.lightnings.add(l)
endmethod
implement ChainManager
endstruct
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
local Chain c = Chain.create()
set c.caster = u
set c.target = t
set c.damage = GetDamage(lvl) + UP_DMG * GetUpgradeSkillLevel(u,UPGRADE_ID)
set c.data = R2I(c.damage)
set c.delay = 0.25
set c.isLight = true
set c.area = 600.00
set c.maxBounces = 3
set c.lightnings = LinkedList.create()
set c.lightDuration = 0.35
set c.lightFadeTime = 0.15
set c.jumpOnce = true
call ShadowRayChain.Fire(c)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Buff b = GetUnitData(u,"VMaskBuff")
if IsUnitEnemy(t,GetOwningPlayer(u)) then
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
else
call SpellTrigger(u,t,lvl)
endif
if b != 0 then
if IsUnitEnemy(b.target,GetOwningPlayer(u)) then
if not TriggerSpellNegation(b.target) then
call SpellTrigger(u,b.target,lvl)
endif
if TriggerSpellReflection(b.target) and not IsUnitMagicImmune(u) then
call SpellTrigger(b.target,u,lvl)
endif
else
call SpellTrigger(u,b.target,lvl)
endif
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,VoodooPriest_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
scope CursedShock initializer init
globals
private constant integer SPELL_ID = 'VPA2'
private constant integer UPGRADE_ID = 'VPI2'
private constant integer TOTEM_ID = 'n016'
private constant real DELAY = 3.00
private constant real AREA_EFFECT = 220
private constant real HEX_DUR_BASE = 0.50
private constant real HEX_DUR_LVL = 0.50
private constant real DURATION = 7.00
private constant integer BASE_ATTACK_COUNT = 2
private constant integer SUP_COUNT = 2
private constant string TARGET_SFX = "Abilities\\Spells\\Human\\Polymorph\\PolyMorphDoneGround.mdl"
private constant string AREA_SFX = "war3mapImported\\EmpathicBond.mdx"
endglobals
private function GetDuration takes integer lvl returns real
return HEX_DUR_BASE + HEX_DUR_LVL * lvl
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local unit totem = tb.unit[1]
local real area = tb.real[2]
local AoE aoe = tb.integer[3]
local real dur = tb.real[4]
local effect sfx = tb.effect[5]
local player p = GetOwningPlayer(u)
local group g
local real x
local real y
local unit temp
if UnitAlive(totem) then
set x = GetUnitX(totem)
set y = GetUnitY(totem)
set g = NewGroup()
call GroupEnumUnitsInRange(g,x,y,area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,temp,"overhead"))
call Status.Add(STATUS_HEX,temp,dur,0)
call Lightning.createEx("WHSB",x,y,150,GetUnitX(temp),GetUnitY(temp),0,0.3,0.10).setLightColor(255,25,255,255)
endif
endloop
call ReleaseGroup(g)
set g = null
call KillUnit(totem)
else
call RemoveUnit(totem)
endif
set AIVP.totem = null
call DestroyEffect(sfx)
call aoe.destroy()
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set sfx = null
set t = null
set p = null
set u = null
set totem = null
endfunction
struct CursedShockMissile extends array
private static method onFinish takes Missile missile returns boolean
local group g
local real dur
local unit temp
local real x
local real y
local effect sfx
local real a = 0
if missile.data == 2 then
call TriggerTotem.evaluate(missile.source,missile.x,missile.y,missile.level)
return true
endif
set g = NewGroup()
set dur = GetDuration(missile.level)
loop
set x = missile.x + 120 * Cos(a * bj_DEGTORAD)
set y = missile.y + 120 * Sin(a * bj_DEGTORAD)
set sfx = AddSpecialEffect("Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayTarget.mdl",x,y)
call BlzSetSpecialEffectScale(sfx,1.5)
call DestroyEffect(sfx)
set a = a + 20
exitwhen a == 360
endloop
call GroupEnumUnitsInRange(g,missile.x,missile.y,AREA_EFFECT,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) then
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,temp,"overhead"))
call Status.Add(STATUS_HEX,temp,dur,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set sfx = null
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real xt, real yt, integer lvl, integer op returns Missile
local real x = GetUnitX(source)
local real y = GetUnitY(source)
local real angle = Angle(x,y,xt,yt)
local real dist = Distance(x,y,xt,yt)
local Missile missile = Missile.create(x, y,60.0, angle, dist,0.0)
set missile.source = source
set missile.level = lvl
set missile.owner = GetOwningPlayer(source)
set missile.speed = 25.00
set missile.arc = 30.*bj_DEGTORAD + RMinBJ(20., dist*.1)*bj_DEGTORAD
set missile.model = "Abilities\\Weapons\\VoidWalkerMissile\\VoidWalkerMissile.mdl"
set missile.scale = 1.7
set missile.data = op
call CursedShockMissile.launch(missile)
return missile
endfunction
function TriggerTotem takes unit u, real x, real y, integer lvl returns nothing
local player p = GetOwningPlayer(u)
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local real dur = GetDuration(lvl)
local AoE aoe
local unit dummy
local effect sfx
set tb.unit[0] = u
set dummy = CreateUnit(p,TOTEM_ID,x,y,0)
if IsUpgradeSuperior(u,UPGRADE_ID) then
call BlzSetUnitMaxHP(dummy,(BASE_ATTACK_COUNT + SUP_COUNT) * 2)
else
call BlzSetUnitMaxHP(dummy,BASE_ATTACK_COUNT * 2)
endif
call SetUnitUserData(dummy,tb)
set sfx = AddSpecialEffect(AREA_SFX,x,y)
call BlzSetSpecialEffectScale(sfx,AREA_EFFECT/64)
call BlzPlaySpecialEffect(sfx,ANIM_TYPE_STAND)
if ulvl != 0 then
call UnitAddAbility(dummy,'A0B3')
call SetUnitAbilityLevel(dummy,'A0B3',ulvl)
call UnitMakeAbilityPermanent(dummy,true,'A0B3')
endif
set AIVP.totem = dummy
set aoe = AoE.create(x,y,null,AREA_EFFECT)
call BlzSetSpecialEffectColor(aoe.sfx,128,0,128)
set tb.effect[5] = sfx
set tb.unit[1] = dummy
set tb.real[2] = AREA_EFFECT
set tb.integer[3] = aoe
set tb.real[4] = dur
call TimerStart(t,DELAY,true,function Callback)
set p = null
set t = null
set dummy = null
set sfx = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Buff b = GetUnitData(u,"VMaskBuff")
call SetupMissile(u,x,y,lvl,1)
if b != 0 then
call SetupMissile(u,GetUnitX(b.target),GetUnitY(b.target),lvl,2)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,VoodooPriest_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
scope VoodooMask initializer init
globals
private constant integer SPELL_ID = 'VPA3'
private constant integer UPGRADE_ID = 'VPI3'
private constant integer ATT_BASE = 20
private constant integer ATT_LEVEL = 10
private constant real DISTANCE = 1000
private constant integer UP_DMG = 10
private constant real MA_MS = 0.25
private constant real MA_DMGR = 0.20
private constant string MISSILE_SFX = "war3mapImported\\TikiMissile.mdx"
endglobals
public function GetAttackSpeed takes integer lvl returns integer
return ATT_BASE + ATT_LEVEL * lvl
endfunction
struct VoodooMask extends array
boolean cmast
boolean ally
boolean dmg
boolean sup
real supmult
integer as
integer udmg
real range
effect sfx
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if DistanceBetweenUnits(b.owner,b.target) > range or not UnitAlive(b.owner) then
set b.removeInside = true
endif
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call SetUnitData(b.owner,"VMaskBuff",0)
if ally then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.owner,as,0,true)
if dmg then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-udmg,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.owner,udmg,0,true)
endif
else
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.owner,-as,0,true)
if dmg then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,udmg,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-udmg,0,true)
endif
endif
set dmg = false
set cmast = false
set sup = false
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set range = DISTANCE
set as = GetAttackSpeed(b.level)
set ally = IsUnitAlly(b.target,GetOwningPlayer(b.owner))
call SetUnitData(b.owner,"VMaskBuff",b)
if ulvl != 0 then
set dmg = true
set udmg = UP_DMG * ulvl
endif
if ally then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.owner,-as,0,true)
if dmg then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,udmg,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.owner,-udmg,0,true)
endif
else
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.owner,as,0,true)
if dmg then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-udmg,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,udmg,0,true)
endif
endif
if GetHeroMasteryType(b.owner) == 1 then
set cmast = true
endif
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
set sup = true
if ally then
set supmult = 0.20
else
set supmult = -0.20
endif
endif
set sfx = AddSpecialEffectTarget("war3mapImported\\TikiMissile.mdx",b.owner,"overhead")
call BlzSetSpecialEffectColorByPlayer(sfx,GetOwningPlayer(b.owner))
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A096'
set BUFF_DATA.BuffID = 'B03C'
set BUFF_DATA.Name = "Voodoo Mask"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.10
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct VoodooMaskMissile extends array
private static method onFinish takes Missile missile returns boolean
local Buff b = GetUnitData(missile.source,"VMaskBuff")
call SetUnitData(missile.source,"VMaskMissile",0)
if b != 0 then
call UnitRemoveBuff(b.target,VoodooMask.buff)
endif
if IsUnitEnemy(missile.target,missile.owner) then
if not TriggerSpellNegation(missile.target) then
call UnitAddBuff(missile.target,missile.source,2500,VoodooMask.buff,missile.level,0)
endif
else
call UnitAddBuff(missile.target,missile.source,2500,VoodooMask.buff,missile.level,0)
endif
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, unit target, integer lvl returns Missile
local Missile missile = GetUnitData(source,"VMaskMissile")
if missile == 0 then
set missile = Missile.create(GetUnitX(source),GetUnitY(source),75.00,AngleBetweenUnits(source,target),0,75.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 40.00
set missile.model = MISSILE_SFX
set missile.scale = 0.9
set missile.level = lvl
else
set missile.target = target
endif
call VoodooMaskMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
call SetupMissile(u,t,lvl)
set u = null
set t = null
endfunction
private function onPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b = GetUnitBuff(data.source,VoodooMask.buff)
if b != 0 then
if VoodooMask[b.buffAllocIndex].sup then
set data.mult = data.mult + VoodooMask[b.buffAllocIndex].supmult
endif
endif
if data.dmgType == udg_DamageTypeAttack then
if GetUnitTypeId(data.source) == 'HVP1' and GetHeroMasteryType(data.source) == 2 then
if Status.UnitHasStatus(STATUS_HEX,data.target) then
set data.trueCritical = true
endif
endif
endif
endfunction
private function onPostDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local real p
local Table tb
local integer c
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime and data.damageMod > 0 and not data.isAbsorbed then
set b = GetUnitData(data.target,"VMaskBuff")
if b != 0 and VoodooMask[b.buffAllocIndex].cmast then
set p = data.damageMod * MA_DMGR
call UnitRemoveHp(b.target,p)
set data.damageMod = data.damageMod - p
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call VoodooMask.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPostCalculation(Filter(function onPostDamage))
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,VoodooPriest_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope DarkSpirits initializer init
globals
private constant integer SPELL_ID = 'VPA4'
private constant integer UPGRADE_ID = 'VPI4'
private constant real REGEN_BASE = 1
private constant real REGEN_LEVEL = 1
private constant real CD_BASE = 2.00
private constant real CD_LEVEL = 1.00
private constant real AOE_BASE = 50.00
private constant real RANGE_BASE = 200.00
private constant real RANGE_LEVEL = 100.00
private constant integer MAX_SPIRITS = 4
private constant real SCD_BASE = 45.00
private constant real SCD_LVL = 5.00
private constant real UP_CD = 5.00
private constant string EFFECT_SFX = "Abilities\\Spells\\Undead\\UnholyFrenzyAOE\\UnholyFrenzyAOETarget.mdl"
private constant string SPIRIT_SFX = "Abilities\\Weapons\\VoidWalkerMissile\\VoidWalkerMissile.mdl"
endglobals
private function GetSpiritCd takes integer lvl returns real
return SCD_BASE - SCD_LVL * lvl
endfunction
public function GetRegen takes integer lvl returns real
return REGEN_BASE + REGEN_LEVEL * lvl
endfunction
private function GetCooldown takes integer lvl returns real
return CD_BASE + CD_LEVEL * lvl
endfunction
private function GetAoeBonus takes integer lvl returns real
return AOE_BASE + AOE_BASE * lvl
endfunction
private function GetRange takes integer lvl returns real
return RANGE_BASE + RANGE_LEVEL * lvl
endfunction
private function DarkSpiritRenew takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetUnitByIndex(GetTimerData(t))
local Table tb = GetUnitData(u,"DS_Ability")
local DarkSpirit lds
local DarkSpirit ds
local LinkedList list
local real xc
local real yc
local real a
if tb != 0 then
set list = tb.integer[1]
if list.size < MAX_SPIRITS then
if list.size == 0 then
set a = 0
else
set lds = list.last.data
set a = lds.angle + 1.5707
if a > bj_PI * 2 then
set a = a - bj_PI * 2
endif
endif
set xc = GetUnitX(u) + 110 * Cos(a)
set yc = GetUnitY(u) + 110 * Sin(a)
set ds = DarkSpirit.create(u,xc,yc,GetLocZ(GetUnitX(u),GetUnitY(u)),a,GetUnitAbilityLevel(u,SPELL_ID))
set ds.index = list.addLast(ds)
endif
endif
call ReleaseTimer(t)
set u = null
set t = null
endfunction
public function InstantDarkSpirit takes unit u returns nothing
call TimerStart(NewTimerEx(GetUnitUserData(u)),0,false,function DarkSpiritRenew)
endfunction
struct DarkSpiritsMissile extends array
private static method onPeriod takes Missile missile returns boolean
local DarkSpirit ds = missile.data
call BlzSetSpecialEffectX(ds.sfx,missile.x)
call BlzSetSpecialEffectY(ds.sfx,missile.y)
call BlzSetSpecialEffectYaw(ds.sfx,missile.angle)
call BlzSetSpecialEffectHeight(ds.sfx,GetLocZ(missile.x,missile.y) + 75.00)
return false
endmethod
private static method onFinish takes Missile missile returns boolean
local DarkSpirit ds = missile.data
local Ability a
local VoodooMask b
local Table tb
local real cd
local effect sfx
local real ar
local AoE aoe
if UnitAlive(missile.target) then
if missile.target == missile.source then
set a = Ability.GetUnitAbilityByID('VPA1',missile.source)
if a.isOnCooldown() then
call a.addCooldownRemaining(-GetCooldown(missile.level))
else
call a.addTempFlatCooldown(-GetCooldown(missile.level))
endif
set sfx = AddSpecialEffectTarget(EFFECT_SFX,missile.target,"origin")
call BlzSetSpecialEffectColor(sfx,255,0,255)
call DestroyEffect(sfx)
set sfx = null
elseif GetUnitTypeId(missile.target) == 'n016' then
set tb = GetUnitUserData(missile.target)
set ar = tb.real[2]
set ar = ar + GetAoeBonus(missile.level)
set aoe = tb.integer[3]
call aoe.setSize(ar)
call BlzSetAbilityRealLevelField(BlzGetUnitAbility(missile.target,'A0B3'),ABILITY_RLF_AREA_OF_EFFECT,GetUnitAbilityLevel(missile.target,'A0B3') - 1,ar)
call BlzSetSpecialEffectScale(tb.effect[5],ar/64)
set sfx = AddSpecialEffect(EFFECT_SFX,missile.x,missile.y)
call BlzSetSpecialEffectColor(sfx,255,0,255)
call DestroyEffect(sfx)
set tb.real[2] = ar
set sfx = null
else
set b = GetUnitBuff(missile.target,VoodooMask.buff).buffAllocIndex
if b != 0 then
set b.range = b.range + GetRange(missile.level)
set sfx = AddSpecialEffectTarget(EFFECT_SFX,missile.target,"origin")
call BlzSetSpecialEffectColor(sfx,255,0,255)
call DestroyEffect(sfx)
set sfx = null
endif
endif
endif
set cd = GetSpiritCd(missile.level)
if GetUpgradeSkillLevel(missile.source,UPGRADE_ID) != 0 then
set cd = cd - UP_CD
endif
call TimerStart(NewTimerEx(GetUnitUserData(missile.source)),cd,false,function DarkSpiritRenew)
call ds.destroy()
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, unit target, DarkSpirit ds returns Missile
local real xt = GetUnitX(target)
local real yt = GetUnitY(target)
local real xs = BlzGetLocalSpecialEffectX(ds.sfx)
local real ys = BlzGetLocalSpecialEffectY(ds.sfx)
local real a = Angle(xs,ys,xt,yt)
local Missile missile = Missile.create(xs,ys,75.00,a,0,75.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 45.00
set missile.scale = 0.0
set missile.data = ds
set missile.level = GetUnitAbilityLevel(source,SPELL_ID)
call DarkSpiritsMissile.launch(missile)
return missile
endfunction
struct DarkSpirit extends array
implement Alloc
unit owner
effect sfx
real angle
real regen
Link index
public method removeBonus takes nothing returns nothing
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,owner,-regen,0)
set regen = 0
endmethod
public method updateBonus takes integer lvl returns nothing
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,owner,-regen,0)
set regen = GetRegen(lvl)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,owner,regen,0)
endmethod
public method destroy takes nothing returns nothing
call DestroyEffect(sfx)
set owner = null
set sfx = null
if regen != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,owner,-regen,0)
endif
call this.deallocate()
endmethod
public static method create takes unit u, real x, real y, real z, real a, integer lvl returns thistype
local thistype this = thistype.allocate()
local real h = GetUnitFlyHeight(u)
set owner = u
set angle = a
set sfx = AddSpecialEffect(SPIRIT_SFX,x,y)
call BlzSetSpecialEffectYaw(sfx,a + 1.5708)
call BlzSetSpecialEffectHeight(sfx,z + h + 100.00)
call BlzSetSpecialEffectScale(sfx,1.4)
set regen = GetRegen(lvl)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,u,regen,0)
return this
endmethod
endstruct
private function DarkSpiritUpdateLevel takes unit u, integer lvl returns nothing
local Table tb = GetUnitData(u,"DS_Ability")
local LinkedList list
local Link h
local DarkSpirit ds
if tb != 0 then
set list = tb.integer[1]
set h = list.head
loop
exitwhen h == 0
set ds = h.data
call ds.updateBonus(lvl)
set h = h.next
endloop
endif
endfunction
private function DarkSpiritThrow takes unit u, unit t returns nothing
local Table tb = GetUnitData(u,"DS_Ability")
local LinkedList list
local DarkSpirit ds
if tb != 0 then
set list = tb.integer[1]
if list.size != 0 then
set ds = list.last.data
call list.remove(ds.index)
call ds.removeBonus()
call SetupMissile(u,t,ds)
endif
endif
endfunction
private function DarkSpiritsLoop takes nothing returns nothing
local Table tb = GetTimerData(GetExpiredTimer())
local unit u = tb.unit[0]
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real z = GetLocZ(x,y)
local real f = GetUnitFlyHeight(u)
local LinkedList list = tb.integer[1]
local boolean b = UnitAlive(u)
local DarkSpirit ds
local Link h = list.head
loop
exitwhen h == 0
set ds = h.data
set ds.angle = ds.angle + 0.10472
call BlzSetSpecialEffectX(ds.sfx,x + 110 * Cos(ds.angle))
call BlzSetSpecialEffectY(ds.sfx,y + 110 * Sin(ds.angle))
call BlzSetSpecialEffectYaw(ds.sfx,ds.angle + 1.5708)
call BlzSetSpecialEffectHeight(ds.sfx,z + f + 100.00)
if ds.angle >= bj_PI * 2 then
set ds.angle = 0.00
endif
if not b then
call BlzSetSpecialEffectHeight(ds.sfx,9999999)
else
//call BlzSetSpecialEffectScale(ds.sfx,1.4)
endif
set h = h.next
endloop
set u = null
endfunction
private function DarkSpiritsSetup takes unit u returns nothing
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real z = GetLocZ(x,y)
local real xc
local real yc
local DarkSpirit ds
local LinkedList list = LinkedList.create()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
set tb.unit[0] = u
set tb.integer[1] = list
set xc = x + 110 * Cos(0)
set yc = y + 110 * Sin(0)
set ds = DarkSpirit.create(u,xc,yc,z,0,lvl)
set ds.index = list.add(ds)
set xc = x + 110 * Cos(1.5708)
set yc = y + 110 * Sin(1.5708)
set ds = DarkSpirit.create(u,xc,yc,z,1.5708,lvl)
set ds.index = list.addLast(ds)
set xc = x + 110 * Cos(3.1415)
set yc = y + 110 * Sin(3.1415)
set ds = DarkSpirit.create(u,xc,yc,z,3.1415,lvl)
set ds.index = list.addLast(ds)
set xc = x + 110 * Cos(4.7123)
set yc = y + 110 * Sin(4.7123)
set ds = DarkSpirit.create(u,xc,yc,z,4.7123,lvl)
set ds.index = list.addLast(ds)
call SetUnitData(u,"DS_Ability",tb)
call TimerStart(t,0.03125,true,function DarkSpiritsLoop)
set t = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
if GetLearnedSkillLevel() == 1 then
call DarkSpiritsSetup(u)
else
call DarkSpiritUpdateLevel(u,GetLearnedSkillLevel())
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local Table tb = GetUnitData(u,"DS_Ability")
if tb != 0 then
call DarkSpiritThrow(u,t)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,VoodooPriest_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(EFFECT_SFX)
endfunction
endscope
library AxeMaster initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HAM1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'AMI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Shatter Earth"
set up.Text = "Reduces |c00b4b4b4Earth Shock|r |c00ffff95Cooldown|r."
set up.SupText = "Doubles |c00b4b4b4Earth Shock|r speed and adds 300 cast range."
set up.LevelData1 = "-2s Cooldown"
set up.LevelData2 = "-4s Cooldown"
set up.LevelData3 = "-6s Cooldown"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'AMI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Cutting Tornado"
set up.Text = "Increases |c00b4b4b4Destructive Swirl|r buff duration."
set up.SupText = "Adds one twist to |c00ffff95Destructive Swirl|r."
set up.LevelData1 = "+2s Duration"
set up.LevelData2 = "+3s Duration"
set up.LevelData3 = "+4s Duration"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'AMI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Break Defences"
set up.Text = "|c00b4b4b4Split Armor|r also reduces the enemy |c00ffff95Block|r and |c00ffff95Evasion|r rating."
set up.SupText = "Increases |c00b4b4b4Split Armor|r debuff duration by 2s."
set up.LevelData1 = "30(4.6%) Reduction"
set up.LevelData2 = "60(9.2%) Reduction"
set up.LevelData3 = "90(13.8%) Reduction"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'AMI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Furious Charge"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HAM1'
set d.Name = "Axe Master"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNAxeMaster.blp"
set d.WinAni = "attack"
set d.Block = 30
set d.Evasion = 10
set d.Resistance = 30
set d.LifeRegen = 1.5
set d.ManaRegen = 1.5
set d.Armor = 5
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'AMA1'
set d.HeroAbility2 = 'AMA2'
set d.HeroAbility3 = 'AMA3'
set d.HeroAbility4 = 'AMA4'
set d.ChooseIconID = 'c032'
set d.ChooseDummy = 'dh32'
set d.spellDamageLevel = 3
set d.attackDamageLevel = 8
set d.healingLevel = 0
set d.survivavilityLevel = 4
set d.movementLevel = 3
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_ORC
set d.InfoID = 'HAMI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope EarthShock initializer init
globals
private constant integer SPELL_ID = 'AMA1'
private constant integer UPGRADE_ID = 'AMI1'
private constant real DAMAGE_BASE = 90.00
private constant real DAMAGE_LEVEL = 30.00
private constant real AREA_OF_EFFECT = 180.00
private constant real AIR_DURATION = 1.00
private constant real HEIGHT = 400.00
private constant real UP_DIST = 100.00
private constant string LOOP_SFX = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
private constant string SHOCK_SFX = "abilities\\weapons\\catapult\\catapultmissile.mdl"
private KPJConfig KPJCONFIG
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetStun takes integer lvl returns real
return 1.0 + 0.50 * lvl
endfunction
struct EarthShockMissile extends array
private static method onPeriod takes Missile missile returns boolean
local effect sfx = AddSpecialEffect(LOOP_SFX,missile.x,missile.y)
call BlzSetSpecialEffectScale(sfx,0.50)
call DestroyEffect(sfx)
set sfx = null
return false
endmethod
private static method onFinish takes Missile missile returns boolean
local group g = NewGroup()
local unit temp
local real st = GetStun(missile.level) + AIR_DURATION
local real sd
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl",missile.x,missile.y))
call GroupEnumUnitsInRange(g,missile.x,missile.y,AREA_OF_EFFECT,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) then
set sd = Status.Add(STATUS_STUN,temp,st,Status_EFFECT[STATUS_STUN])
if sd != 0 then
call KPJUnit.create(temp,0,0,AIR_DURATION,HEIGHT,KPJCONFIG,KPJ_TYPE_JUMP)
endif
call CodeDamage.Damage(missile.source,temp,missile.damage,udg_DamageTypePhysicalAoe,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real xs, real ys, real xt, real yt returns Missile
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local Missile missile = Missile.createXYZ(xs,ys,10.0,xt,yt,10.0)
set missile.source = source
set missile.level = lvl
set missile.damage = GetDamage(lvl)
set missile.owner = GetOwningPlayer(source)
if IsUpgradeSuperior(source,UPGRADE_ID) then
set missile.speed = 40.00
else
set missile.speed = 20.00
endif
call EarthShockMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
call SetupMissile(u,GetUnitX(u),GetUnitY(u),x,y)
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(-2.0)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set KPJCONFIG = KPJConfig.create()
set KPJCONFIG.friction = 0
set KPJCONFIG.gravity = 0.5
set KPJCONFIG.disable = false
set KPJCONFIG.hardDisable = false
set KPJCONFIG.killTrees = false
set KPJCONFIG.sfxModel = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,AxeMaster_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope DestructiveSwirl initializer init
globals
private constant integer SPELL_ID = 'AMA2'
private constant integer UPGRADE_ID = 'AMI2'
private constant real DAMAGE_BASE = 25.00
private constant real DAMAGE_LEVEL = 50.00
private constant real AREA_OF_EFFECT = 260.00
private constant real AXE_DURATION = 1.25
private constant real STEAL_DURATION = 5.00
private constant integer DMG_STEAL_U = 5
private constant integer DMG_STEAL_H = 10
private constant real UP_DURATION_B = 1.00
private constant string AXE_SFX = "war3mapImported\\ChainAxe.mdx"
private constant string END_SFX = "Abilities\\Spells\\NightElf\\Taunt\\TauntCaster.mdl"
private constant string HIT_SFX = "Abilities\\Weapons\\BloodElfSpellThiefMISSILE\\BloodElfSpellThiefMISSILE.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetSteal takes integer lvl returns integer
return DMG_STEAL_H * lvl
endfunction
struct DestructiveSwirlSteal extends array
integer dmg
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = b.int
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CA'
set BUFF_DATA.BuffID = 'B04Q'
set BUFF_DATA.Name = "Destructive Swirl Steal"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct DestructiveSwirlDmg extends array
integer dmg
integer as
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer lvl = GetUnitAbilityLevel(b.target,SPELL_ID)
local integer st = GetSteal(lvl)
set dmg = (b.level * st) + (b.int * DMG_STEAL_U)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
if GetHeroMasteryType(b.target) == 2 then
set as = (20 * b.level) + (2 * b.int)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CB'
set BUFF_DATA.BuffID = 'B04R'
set BUFF_DATA.Name = "Destructive Swirl Dmg"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local effect sfx = tb.effect[1]
local group g = tb.group[2]
local integer i = tb.integer[3]
local real a = tb.real[4]
local player p = tb.player[5]
local integer c = tb.integer[6]
local integer c2 = tb.integer[7]
local real dmg = tb.real[8]
local integer st = tb.integer[9]
local integer ac = tb.integer[10]
local real dur = tb.real[11]
local group g2 = NewGroup()
local group g3 = tb.group[12]
local real z
local unit temp
local real a2
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local DamageOptions op
if ac < 30 then
set z = GetUnitFlyHeight(u) + GetLocZ(x,y) + 50.00
set a2 = a * bj_DEGTORAD
call BlzSetSpecialEffectX(sfx,x)
call BlzSetSpecialEffectY(sfx,y)
call BlzSetSpecialEffectZ(sfx,z)
call BlzSetSpecialEffectYaw(sfx,a2)
call LineSegment.EnumUnits(g2,x,y,x+AREA_OF_EFFECT*Cos(a2),y+AREA_OF_EFFECT*Sin(a2),40)
loop
set temp = FirstOfGroup(g2)
exitwhen temp == null
call GroupRemoveUnit(g2,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitInGroup(temp,g3) then
call GroupAddUnit(g3,temp)
set op = DamageOptions.create()
set op.allowOrbs = true
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeAttack,"",0,op)
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"overhead"))
if not IsUnitInGroup(temp,g) then
call GroupAddUnit(g,temp)
if IsUnitType(temp,UNIT_TYPE_HERO) then
set c = c + 1
call UnitAddBuff(temp,u,dur + (30 * i - ac) * 0.03125,DestructiveSwirlSteal.buff,0,st)
else
set c2 = c2 + 1
call UnitAddBuff(temp,u,dur + (30 * i - ac) * 0.03125,DestructiveSwirlSteal.buff,0,DMG_STEAL_U)
endif
endif
endif
endloop
set tb.integer[6] = c
set tb.integer[7] = c2
set tb.real[4] = a + 12.0
set tb.integer[10] = ac + 1
call ReleaseGroup(g2)
else
set i = i - 1
set tb.integer[3] = i
set tb.integer[10] = 0
call GroupClear(g3)
if i == 0 then
if tb.boolean[13] then
call Status.Remove(STATUS_SPELL_IMMUNITY,u)
endif
if c + c2 != 0 then
call DestroyEffect(AddSpecialEffectTarget(END_SFX,u,"origin"))
call UnitAddBuff(u,u,dur,DestructiveSwirlDmg.buff,c,c2)
endif
//call BlzSetSpecialEffectAlpha(sfx,0)
call DestroyEffect(sfx)
call ReleaseTimer(t)
call ReleaseGroup(g3)
call ReleaseGroup(g)
call tb.flush()
call tb.destroy()
endif
endif
set t = null
set u = null
set p = null
set sfx = null
set g = null
set g2 = null
set g3 = null
endfunction
private function SpellTrigger takes unit u returns nothing
local Table tb = Table.create()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local effect sfx = AddSpecialEffect(AXE_SFX,GetUnitX(u),GetUnitY(u))
local real a = GetUnitFacing(u) - 90
local real d = STEAL_DURATION
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
if ulvl != 0 then
set d = d + UP_DURATION_B + UP_DURATION_B * ulvl
endif
call BlzSetSpecialEffectScale(sfx,1.0)
call BlzSetSpecialEffectColor(sfx,200,200,200)
call BlzSetSpecialEffectYaw(sfx,a * bj_DEGTORAD)
set tb.unit[0] = u
set tb.effect[1] = sfx
set tb.group[2] = NewGroup()
if IsUpgradeSuperior(u,UPGRADE_ID) then
set tb.integer[3] = 3
else
set tb.integer[3] = 2
endif
set tb.real[4] = a
set tb.player[5] = GetOwningPlayer(u)
set tb.integer[6] = 0
set tb.integer[7] = 0
set tb.real[8] = GetDamage(lvl)
set tb.integer[9] = GetSteal(lvl)
set tb.integer[10] = 0
set tb.real[11] = d
set tb.group[12] = NewGroup()
if GetHeroMasteryType(u) == 3 then
set tb.boolean[13] = true
call Status.Add(STATUS_SPELL_IMMUNITY,u,0,Status_EFFECT[STATUS_SPELL_IMMUNITY])
endif
call TimerStart(NewTimerEx(tb),0.03125,true,function Callback)
set sfx = null
endfunction
private function onOrder takes nothing returns nothing
local unit u = GetOrderedUnit()
local integer i
local integer ulvl
if GetIssuedOrderId() == ORDER_manashieldon then
call UnitRemoveAbility(u,'B03K')
if not Status.UnitHasStatus(STATUS_STUN,u) then
call SpellTrigger(u)
endif
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local trigger t
if GetLearnedSkillLevel() == 1 then
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t,function onOrder)
set t = null
if GetPlayerController(GetTriggerPlayer()) == MAP_CONTROL_COMPUTER then
call BlzUnitDisableAbility(u,SPELL_ID,true,false)
endif
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DestructiveSwirlDmg.Initialize()
call DestructiveSwirlSteal.Initialize()
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,AxeMaster_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope SplitArmor initializer init
globals
private constant integer SPELL_ID = 'AMA3'
private constant integer UPGRADE_ID = 'AMI3'
private constant integer ARMOR_BASE = 2
private constant real HP_BASE = 0.30
private constant real HP_LEVEL = 0.05
private constant real DURATION = 1.50
private constant real UP_BLOCK = 30
endglobals
private function GetHpFactor takes integer lvl returns real
return HP_BASE - HP_LEVEL * lvl
endfunction
struct SplitArmor extends array
integer armor
real block
public method update takes nothing returns nothing
local real hp = GetHpFactor(thisBuff.level)
local real life = GetUnitMissingLife(thisBuff.target)
local real perc = GetUnitState(thisBuff.target,UNIT_STATE_MAX_LIFE) * hp
if armor != 0 then
call BonusStruct.Add(BONUS_TYPE_ARMOR,thisBuff.target,armor,0,true)
endif
set armor = ARMOR_BASE + (1 * R2I(life / perc))
call BonusStruct.Add(BONUS_TYPE_ARMOR,thisBuff.target,-armor,0,true)
set thisBuff.elapsedTime = 0.0
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
if block != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,b.target,block,0)
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,block,0)
set block = 0
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set armor = 0
call update()
if ulvl != 0 then
set block = UP_BLOCK * ulvl
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,b.target,-block,0)
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,-block,0)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CC'
set BUFF_DATA.BuffID = 'B04S'
set BUFF_DATA.Name = "Destructive Swirl Steal"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local real d
local SplitArmor b
if data.dmgType == udg_DamageTypeAttack and data.allowOrbs then
set lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
if lvl != 0 and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) then
set b = GetUnitBuff(data.target,SplitArmor.buff).buffAllocIndex
if b == 0 then
if IsUpgradeSuperior(data.source,UPGRADE_ID) then
set d = DURATION + 2.0
else
set d = DURATION
endif
call UnitAddBuff(data.target,data.source,d,SplitArmor.buff,lvl,0)
else
call b.update()
endif
endif
endif
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if GetHeroMasteryType(data.target) == 1 then
if UnitHasBuff(data.target,AnnihilatingSprint.buff) then
set data.mult = data.mult - 0.40
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SplitArmor.Initialize()
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,AxeMaster_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope AnnihilatingSprint initializer init
globals
private constant integer SPELL_ID = 'AMA4'
private constant integer UPGRADE_ID = 'AMI4'
private constant real DAMAGE_BASE = 75.00
private constant real STR_BASE = 0.75
private constant real STR_LVL = 0.25
private constant real MS_BASE = 0.40
private constant real MS_LVL = 0.10
private constant real AREA_OF_EFFECT = 200.00
private constant real KNB_DURATION = 1.30
private constant real KNB_DISTANCE = 200.00
private constant real BUFF_DURATION = 3.00
private constant real STR_UP = 0.25
private constant string LOOP_SFX = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
private constant string SHOCK_SFX = "abilities\\weapons\\catapult\\catapultmissile.mdl"
private RSound ABILITY_SOUND
endglobals
private function GetDamageStr takes integer lvl returns real
return STR_BASE + STR_LVL * lvl
endfunction
private function GetMs takes integer lvl returns real
return MS_BASE + MS_LVL * lvl
endfunction
struct AnnihilatingSprint extends array
real str
Movespeed ms
group g
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ReleaseGroup(g)
call ms.destroy()
call AddUnitAnimationProperties(b.target,"Fast",false)
call Status.Remove(STATUS_PHASE,b.target)
set g = null
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g2 = NewGroup()
local player p = GetOwningPlayer(b.target)
local real ang = 90
local real d = GetHeroStr(b.target,true) * str
local unit temp
local real a = GetUnitFacing(b.target)
call GroupEnumUnitsInRange(g2,GetUnitX(b.target),GetUnitY(b.target),AREA_OF_EFFECT,null)
loop
set temp = FirstOfGroup(g2)
exitwhen temp == null
call GroupRemoveUnit(g2,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitInGroup(temp,g) then
set ang = ang * -1
call KPJUnit.create(temp,KNB_DISTANCE,(a + ang) * bj_DEGTORAD,KNB_DURATION,0,KPJDefaultConfig3,KPJ_TYPE_KNOCKBACK)
call CodeDamage.Damage(b.target,temp,DAMAGE_BASE + d,udg_DamageTypePhysicalAoe,"",0,0)
call GroupAddUnit(g,temp)
endif
endloop
call ReleaseGroup(g2)
set g2 = null
set p = null
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set g = NewGroup()
set str = GetDamageStr(b.level)
set ms = Movespeed.create(b.target,GetMs(b.level),0)
call AddUnitAnimationProperties(b.target,"Fast",true)
call Status.Add(STATUS_PHASE,b.target,0,0)
if GetUpgradeSkillLevel(b.target,UPGRADE_ID) != 0 then
set str = str + STR_UP
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CD'
set BUFF_DATA.BuffID = 'B04T'
set BUFF_DATA.Name = "AnnihilatingSprint"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
if GetLearnedSkillLevel() == 1 then
if GetPlayerController(GetTriggerPlayer()) == MAP_CONTROL_COMPUTER then
call BlzUnitDisableAbility(u,SPELL_ID,true,false)
endif
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = BUFF_DURATION
if GetHeroMasteryType(u) == 1 then
set d = d + 2.0
endif
call ABILITY_SOUND.play(GetUnitX(u),GetUnitY(u),0,100)
call UnitAddBuff(u,u,d,AnnihilatingSprint.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call AnnihilatingSprint.Initialize()
call RegisterSpellLearn(SPELL_ID,function onLearn)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
set ABILITY_SOUND = RSound.create("war3mapImported\\Charge.mp3", true, false, 12700, 12700)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,AxeMaster_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library SoulHarvester initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HSB1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'SHI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Preservation"
set up.Text = "A percentage of the |c0000ff00Heal|r made by |c00b4b4b4Soul Absorption|r to the hero recovers mana points."
set up.SupText = "Increases |c00b4b4b4Soul Absorption|r max Hp % stolen from heores by 2%."
set up.LevelData1 = "20% to Mana"
set up.LevelData2 = "30% to Mana"
set up.LevelData3 = "40% to Mana"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNUnsummonBuilding.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'SHI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Shadow Burn"
set up.Text = "Enemies under the effects of |c0099b4d1Shadow Embrace|r receive more damage from periodic spell damage."
set up.SupText = "Increases the Area of effect of |c00b4b4b4Shadow Embrace|r by 200."
set up.LevelData1 = "+10% Periodic Damage"
set up.LevelData2 = "+20% Periodic Damage"
set up.LevelData3 = "+30% Periodic Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNBanish.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'SHI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Void"
set up.Text = "Increases the damage/heal done by |c00b4b4b4Haunt|r."
set up.SupText = "|c00b4b4b4Haunt |ralso targets the last target of |c00b4b4b4Shadow Embrace|r but with 30% effectiveness.|n(Don't work if the target is the same)"
set up.LevelData1 = "+10 Damage/Heal"
set up.LevelData2 = "+20 Damage/Heal"
set up.LevelData3 = "+30 Damage/Heal"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSacrificialSkull.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'SHI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Unexistence"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HSB1'
set d.Name = "Soul Harvester"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNSkeletonMage.blp"
set d.WinAni = "spell slam"
set d.Block = 10
set d.Evasion = 20
set d.Resistance = 50
set d.LifeRegen = 1.2
set d.ManaRegen = 1.2
set d.Armor = 2
set d.AttackRange = 400
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'SHA1'
set d.HeroAbility2 = 'SHA2'
set d.HeroAbility3 = 'SHA3'
set d.HeroAbility4 = 'SHA4'
set d.ChooseIconID = 'c008'
set d.ChooseDummy = 'dh08'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 1
set d.healingLevel = 6
set d.survivavilityLevel = 5
set d.movementLevel = 2
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_UNDEAD
set d.InfoID = 'HSBI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope SoulAbsorption initializer init
globals
private constant integer SPELL_ID = 'SHA1'
private constant integer UPGRADE_ID = 'SHI1'
private constant integer EXTRA_ID = 'SHA5'
private constant real DAMAGE_BASE = 20.00
private constant real DAMAGE_LEVEL = 10.00
private constant integer MAX_UNITS = 3
public constant integer MAX_SOULSHARDS = 10
private constant real AREA_OF_EFFECT = 180.00
private constant real UP_MANA_BASE = 0.10
private constant real UP_MANA_LEVEL = 0.10
private constant string MISSILE_SFX = "Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl"
private constant string AREA_SFX = "war3mapImported\\Soul Discharge Purple.mdx"
public constant string ICON_PATH = "ReplaceableTextures\\CommandButtons\\BTNSoulShard"
endglobals
public function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetMana takes integer lvl returns real
return UP_MANA_BASE + UP_MANA_LEVEL * lvl
endfunction
public function AddSoulShard takes unit u, integer c returns nothing
local integer ss = GetUnitData(u,"SoulShards")
if ss < MAX_SOULSHARDS then
set ss = ss + c
if ss > MAX_SOULSHARDS then
set ss = MAX_SOULSHARDS
endif
call BlzSetAbilityIcon(EXTRA_ID,ICON_PATH+I2S(ss)+".blp")
call SetUnitData(u,"SoulShards",ss)
endif
endfunction
public function RemoveSoulShard takes unit u, integer c returns nothing
local integer ss = GetUnitData(u,"SoulShards")
set ss = ss - c
if ss <= 0 then
set ss = 0
call BlzSetAbilityIcon(EXTRA_ID,"ReplaceableTextures\\CommandButtons\\BTNinv_misc_gem_amethyst_02.blp")
else
call BlzSetAbilityIcon(EXTRA_ID,ICON_PATH+I2S(ss)+".blp")
endif
call SetUnitData(u,"SoulShards",ss)
endfunction
struct SoulAbsorptionMissile extends array
private static method onFinish takes Missile missile returns boolean
local integer ulvl = GetUpgradeSkillLevel(missile.target,UPGRADE_ID)
local VoidShift b
call AddSoulShard(missile.target,missile.data)
set b = GetUnitBuff(missile.target,VoidShift.buff).buffAllocIndex
if b != 0 then
set b.addHeal = b.addHeal + missile.damage
else
call CodeDamage.Damage(missile.target,missile.target,missile.damage,udg_DamageTypeHeal,"",0,0)
endif
if ulvl != 0 then
call UnitAddMp(missile.target,missile.damage * GetMana(ulvl))
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, real dmg, player owner, boolean sup returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),50.00,AngleBetweenUnits(source,target),0,50.00)
local real hpp = 0.03
set dmg = dmg + BlzGetUnitMaxHP(source) * hpp
if sup and IsUnitType(source,UNIT_TYPE_HERO) then
set hpp = 0.05
endif
if IsUnitAlly(source,owner) then
call UnitRemoveHp(source,dmg)
else
if GetUnitStatePercent(source,UNIT_STATE_LIFE,UNIT_STATE_MAX_LIFE) < 40 then
set dmg = dmg * 2
endif
call CodeDamage.Damage(target,source,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
call DestroyEffect(AddSpecialEffectTarget(MISSILE_SFX,source,"chest"))
set missile.source = source
set missile.target = target
set missile.owner = owner
set missile.damage = dmg
set missile.speed = 20.00
set missile.model = MISSILE_SFX
if UnitHasBuff(source,ShadowEmbraceSecond.buff) then
set missile.scale = 1.0
set missile.data = 2
else
set missile.scale = 0.7
set missile.data = 1
endif
call SetUnitVertexColor(missile.dummy,255,0,75,255)
call SoulAbsorptionMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local player p = GetOwningPlayer(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real value = GetDamage(lvl)
local group g = NewGroup()
local boolean sup = IsUpgradeSuperior(u,UPGRADE_ID)
local unit array ge
local unit array ga
local integer ec = 0
local integer ac = 0
local integer c = 0
local integer i = 0
local unit temp
local effect sfx
set sfx = AddSpecialEffect(AREA_SFX,x,y)
call BlzSetSpecialEffectColor(sfx,255,200,200)
call BlzSetSpecialEffectScale(sfx,0.7)
call DestroyEffect(sfx)
set sfx = null
call GroupEnumUnitsInRange(g,x,y,AREA_OF_EFFECT,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_VALID_UNIT(temp) and temp != u then
if IsUnitEnemy(temp,p) then
set ge[ec] = temp
set ec = ec + 1
else
set ga[ac] = temp
set ac = ac + 1
endif
endif
endloop
loop
exitwhen i == ec
if c < MAX_UNITS then
set c = c + 1
call SetupMissile(ge[i],u,value,p,sup)
endif
set ge[i] = null
set i = i + 1
endloop
set i = 0
loop
exitwhen i == ac
if c < MAX_UNITS then
set c = c + 1
call SetupMissile(ga[i],u,value,p,sup)
endif
set ge[i] = null
set i = i + 1
endloop
call ReleaseGroup(g)
set temp = null
set g = null
set p = null
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
if GetLearnedSkillLevel() == 1 then
call UnitAddAbility(u,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,SoulHarvester_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A00P',PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
scope ShadowEmbrace initializer init
globals
private constant integer SPELL_ID = 'SHA2'
private constant integer UPGRADE_ID = 'SHI2'
private constant real DAMAGE_BASE = 80.00
private constant real DAMAGE_LEVEL = 40.00
private constant real EFFECT_DELAY = 2.00
private constant real ENTANGLE_DURATION = 2.50
private constant real BUFF_DURATION = 12.00
private constant real EFFECT_AREA = 300.00
private constant real UP_DMG_INC = 0.10
private constant real SUP_EFFECT_AREA = 200.00
private constant string TARGET_SFX = "war3mapImported\\OrbOfCorruption.mdx"
private Effect SFX
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct ShadowEmbraceSecond extends array
real increase
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set increase = UP_DMG_INC * GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00P'
set BUFF_DATA.BuffID = 'B00F'
set BUFF_DATA.Name = "Shadow Embrace Secondary"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct ShadowEmbrace extends array
effect sfx
real area
AoE aoe
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(sfx)
set sfx = null
call aoe.destroy()
endmethod
private static method onFinish takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g = NewGroup()
local player p = GetOwningPlayer(b.owner)
local real dmg = GetDamage(GetUnitAbilityLevel(b.owner,SPELL_ID))
local unit temp
local effect sfxe = AddSpecialEffect(TARGET_SFX,GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectScale(sfxe,3.0)
call DestroyEffect(sfxe)
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call CodeDamage.Damage(b.owner,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_ENTANGLE,temp,ENTANGLE_DURATION,SFX)
call UnitAddBuff(temp,b.owner,BUFF_DURATION,ShadowEmbraceSecond.buff,0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set sfxe = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set area = EFFECT_AREA
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
set area = area + SUP_EFFECT_AREA
endif
call SetUnitData(b.owner,"SELast",GetUnitUserData(b.target))
set sfx = AddSpecialEffectTarget(TARGET_SFX,b.target,"overhead")
set aoe = AoE.create(0,0,b.target,area)
call BlzSetSpecialEffectColor(aoe.sfx,255,0,255)
if IsUnitAlly(b.target,GetOwningPlayer(b.owner)) then
set b.buffType = BUFF_TYPE_POSITIVE
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00Y'
set BUFF_DATA.BuffID = 'B00A'
set BUFF_DATA.Name = "Shadow Embrace"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
call UnitAddBuff(t,u,EFFECT_DELAY,ShadowEmbrace.buff,lvl,0)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local player p = GetOwningPlayer(u)
if IsUnitAlly(t,p) then
call SpellTrigger(u,t,lvl)
else
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) then
call SpellTrigger(t,u,lvl)
endif
endif
set u = null
set t = null
set p = null
endfunction
private function onPreDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local ShadowEmbraceSecond b
if data.dmgType == udg_DamageTypeMagicOverTime or data.dmgType == udg_DamageTypePhysicalOverTime then
set b = GetUnitBuff(data.target,ShadowEmbraceSecond.buff).buffAllocIndex
if b != 0 then
set data.mult = data.mult + b.increase
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ShadowEmbrace.Initialize()
call ShadowEmbraceSecond.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDmg))
set SFX = Effect.create("war3mapImported\\EntanglingSpikes.mdx","origin")
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,SoulHarvester_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
scope Haunt initializer init
globals
private constant integer SPELL_ID = 'SHA3'
private constant integer UPGRADE_ID = 'SHI3'
private constant real DAMAGE_BASE = 50.00
private constant real DAMAGE_LEVEL = 10.00
private constant real MAX_DISTANCE = 1000.00
private constant real INTERVAL = 0.40
private constant real UP_INCREASE = 10.00
private constant real MA_MOVE_SPEED = 0.20
private constant string MISSILE_SFX = "Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl"
private constant integer UP_RESIST = 30
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct HauntMissile extends array
private static method onFinish takes Missile missile returns boolean
set missile.damage = missile.damage + (UP_INCREASE * missile.level)
if missile.data == 0 then
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeHealOverTime,"",0,0)
else
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeMagicOverTime,"",0,0)
endif
if GetHeroMasteryType(missile.source) == 3 then
if GetRandomInt(1,100) <= 10 then
call SoulAbsorption_AddSoulShard(missile.source,1)
endif
endif
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, unit target, real dmg, boolean ally returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),50.00,AngleBetweenUnits(source,target),0,50.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(target)
set missile.damage = dmg
set missile.speed = 35.00
set missile.model = MISSILE_SFX
set missile.scale = 0.7
if ally then
set missile.data = 0
call SetUnitVertexColor(missile.dummy,0,255,255,255)
else
set missile.data = 1
call SetUnitVertexColor(missile.dummy,255,0,75,255)
endif
set missile.level = GetUpgradeSkillLevel(source,UPGRADE_ID)
call HauntMissile.launch(missile)
return missile
endfunction
private function Callback takes nothing returns nothing
local timer tr = GetExpiredTimer()
local Table tb = GetTimerData(tr)
local unit u = tb.unit[0]
local unit t = tb.unit[1]
local boolean second = tb.boolean[4]
local integer shards = GetUnitData(u,"SoulShards")
local real d = DistanceBetweenUnits(u,t)
local VoidShift b
if GetUnitCurrentOrder(u) == ORDER_firebolt and shards > 0 and d <= MAX_DISTANCE and UnitAlive(t) then
if not second then
call SoulAbsorption_RemoveSoulShard(u,1)
endif
call SetupMissile(u,t,tb.real[2],tb.boolean[3])
else
if shards == 0 or d > MAX_DISTANCE or not UnitAlive(t) and not second then
call IssueImmediateOrderById(u,ORDER_stop)
endif
set b = GetUnitBuff(u,VoidShift.buff).buffAllocIndex
if b != 0 and not second then
if not b.pause then
set b.pause = true
call Status.Add(STATUS_DISABLE,u,0,0)
endif
endif
call tb.flush()
call tb.destroy()
call ReleaseTimer(tr)
endif
set tr = null
set t = null
set u = null
endfunction
private function SpellTrigger takes unit u, unit t, integer lvl, boolean ally, boolean second returns nothing
local Table tb = Table.create()
local timer tr = NewTimerEx(tb)
set tb.unit[0] = u
set tb.unit[1] = t
if second then
set tb.real[2] = GetDamage(lvl) * 0.30
else
set tb.real[2] = GetDamage(lvl)
endif
set tb.boolean[3] = ally
set tb.boolean[4] = second
call TimerStart(tr,INTERVAL,true,function Callback)
set tr = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local player p = GetTriggerPlayer()
local integer last
local unit t2
if not TriggerSpellNegation(t) and IsUnitEnemy(t,p) then
call SpellTrigger(u,t,lvl,false,false)
else
call SpellTrigger(u,t,lvl,true,false)
endif
if IsUpgradeSuperior(u,UPGRADE_ID) then
set last = GetUnitData(u,"SELast")
if last != 0 then
set t2 = GetUnitByIndex(last)
if t != t2 then
if not TriggerSpellNegation(t2) and IsUnitEnemy(t2,p) then
call SpellTrigger(u,t2,lvl,false,true)
else
call SpellTrigger(u,t2,lvl,true,true)
endif
endif
endif
endif
set u = null
set t = null
set t2 = null
set p = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,SoulHarvester_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope VoidShift initializer init
globals
private constant integer SPELL_ID = 'SHA4'
private constant integer UPGRADE_ID = 'SHI4'
private constant real DURATION_BASE = 1.50
private constant real DURATION_LEVEL = 0.50
private constant real HEAL_BASE = 50.00
private constant real HEAL_LEVEL = 50.00
private constant real AREA_BASE = 700.00
private constant real UP_CD_REDUCTION = 5.00
private constant string CASTER_SFX = "war3mapImported\\BlackHoleSpell.mdx"
private constant string HEAL_SFX = "war3mapImported\\GhostMissile.mdx"
private constant string END_SFX = "war3mapImported\\DarkNova.mdx"
endglobals
private function GetDuration takes integer lvl returns real
return DURATION_BASE + DURATION_LEVEL * lvl
endfunction
private function GetHeal takes integer lvl returns real
return HEAL_BASE + HEAL_LEVEL * lvl
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID and up.level == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
if a != 0 then
call a.addFlatCooldown(-UP_CD_REDUCTION)
endif
endif
endfunction
struct VoidShift extends array
real addHeal
effect sfx
fogmodifier fog
boolean pause
boolean canmove
real at
real dist
boolean move
public static method Move takes Buff b, real x, real y returns nothing
local thistype this = b.buffAllocIndex
set dist = Distance(GetUnitX(b.target),GetUnitY(b.target),x,y)
set at = Angle(GetUnitX(b.target),GetUnitY(b.target),x,y)
call BlzSetUnitFacingEx(b.target,at)
set move = true
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real xu
local real yu
local real xt
local real yt
if canmove and move then
set xu = GetUnitX(b.target)
set yu = GetUnitY(b.target)
set xt = xu + 7.8 * Cos(at)
set yt = yu + 7.8 * Sin(at)
call SetUnitX(b.target,xt)
call SetUnitY(b.target,yt)
set dist = dist - 7.8
if dist <= 0.00 then
set move = false
endif
call BlzSetSpecialEffectX(sfx,xt)
call BlzSetSpecialEffectY(sfx,yt)
endif
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g = NewGroup()
local player p = GetOwningPlayer(b.owner)
local real heal = GetHeal(b.level)
local unit temp
local boolean cmas = GetHeroMasteryType(b.owner) == 1
local effect sfx2
if pause then
call Status.Remove(STATUS_DISABLE,b.target)
endif
call Status.Remove(STATUS_INVULNERABLE,b.target)
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),AREA_BASE,null)
set sfx2 = AddSpecialEffect(END_SFX,GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectScale(sfx2,0.7)
call DestroyEffect(sfx2)
set sfx2 = null
set heal = heal + addHeal
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ALLIED(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(HEAL_SFX,temp,"overhead"))
call CodeDamage.Damage(b.target,temp,heal,udg_DamageTypeHeal,"",0,0)
elseif cmas then
if FILT_HERO_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call Status.Add(STATUS_FEAR,temp,1.5,Status_EFFECT[STATUS_FEAR])
endif
endif
endloop
call ReleaseGroup(g)
if b.target == b.owner then
call SelectUnitForPlayer(b.target,p,true)
endif
if canmove then
call UnitRemoveAbility(b.target,'A046')
set canmove = false
endif
set move = false
call BlzUnitDisableAbility(b.target,'Amov',false,false)
call SetUnitVertexColor(b.target,255,255,255,255)
call FogModifierStop(fog)
call DestroyFogModifier(fog)
call DestroyEffect(sfx)
set sfx = null
set g = null
set p = null
set fog = null
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g = NewGroup()
local player p = GetOwningPlayer(b.owner)
local integer qlvl = GetUnitAbilityLevel(b.owner,'SHA1')
local real dmg = SoulAbsorption_GetDamage(qlvl)
local boolean sup = IsUpgradeSuperior(b.owner,'SHI1')
local unit temp
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
call GroupEnumUnitsInRange(g,x,y,AREA_BASE,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ENEMY(temp,p) and temp != b.target then
if qlvl != 0 then
call SoulAbsorption_SetupMissile(temp,b.owner,dmg,p,sup)
endif
endif
endloop
call ReleaseGroup(g)
set addHeal = 0
set sfx = AddSpecialEffect(CASTER_SFX,x,y)
call BlzSetSpecialEffectScale(sfx,0.40)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 50)
call BlzSetSpecialEffectColor(sfx,255,0,255)
set fog = CreateFogModifierRadius(GetOwningPlayer(b.owner),FOG_OF_WAR_VISIBLE,x,y,800,true,false)
call FogModifierStart(fog)
call SetUnitVertexColor(b.target,0,0,0,0)
call Status.Add(STATUS_INVULNERABLE,b.target,0,0)
if GetUnitCurrentOrder(b.target) == ORDER_firebolt then
set pause = false
else
call Status.Add(STATUS_DISABLE,b.target,0,0)
set pause = true
endif
call BlzUnitDisableAbility(b.target,'Amov',true,true)
if GetHeroMasteryType(b.target) == 2 then
set canmove = true
call UnitAddAbility(b.target,'A046')
call UnitMakeAbilityPermanent(b.target,true,'A046')
call BlzUnitDisableAbility(b.target,'A046',false,false)
endif
set g = null
set p = null
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Void Shift"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.03125
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCastMove takes nothing returns nothing
local unit u = GetTriggerUnit()
local Buff b = GetUnitBuff(u,VoidShift.buff)
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
if b != 0 then
if VoidShift[b.buffAllocIndex].canmove then
call VoidShift.Move(b,x,y)
endif
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real duration = GetDuration(lvl)
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set duration = duration + 0.5
endif
call UnitAddBuff(u,u,duration,VoidShift.buff,lvl,0)
call UnitRemoveAbility(u,'Bbsk')
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call VoidShift.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent('A046', function onCastMove)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,SoulHarvester_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(CASTER_SFX)
call Preload(HEAL_SFX)
endfunction
endscope
library Frozenshell initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HFS1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'FSI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Cold Zone"
set up.Text = "Increases |c00b4b4b4Cold Swirl|r |c0000ced1Frost|r duration."
set up.SupText = "Increases the area of effect of |c00b4b4b4Cold Swirl|r by 120."
set up.LevelData1 = "+1s duration"
set up.LevelData2 = "+2s duration"
set up.LevelData3 = "+3s duration"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'FSI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Chill Heart"
set up.Text = "|c00b4b4b4Frostbitten Bulwark|r gives bonus |c00ffff95Armor|r periodically."
set up.SupText = "|c00b4b4b4Frostbitten Bulwark|r also gives the |c00ffff95Resistance|r bonus as |c00ffff95Block|r rating bonus."
set up.LevelData1 = "Up to 10 Armor"
set up.LevelData2 = "Up to 20 Armor"
set up.LevelData3 = "Up to 30 Armor"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'FSI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Cold Strikes"
set up.Text = "Reduces |c00b4b4b4Ice Shards|r cooldown."
set up.SupText = "Increases |c00b4b4b4Ice Shards|r knockback duration by 0.80s."
set up.LevelData1 = "-1s Cooldown"
set up.LevelData2 = "-2s Cooldown"
set up.LevelData3 = "-3s Cooldown"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'FSI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Sharp Spikes"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HFS1'
set d.Name = "Frozenshell"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNRevenant.blp"
set d.WinAni = "spell"
set d.Block = 30
set d.Evasion = 0
set d.Resistance = 30
set d.LifeRegen = 2.0
set d.ManaRegen = 1.0
set d.Armor = 5
set d.AttackRange = 135
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'FSA1'
set d.HeroAbility2 = 'FSA2'
set d.HeroAbility3 = 'FSA3'
set d.HeroAbility4 = 'FSA4'
set d.ChooseIconID = 'c016'
set d.ChooseDummy = 'dh16'
set d.spellDamageLevel = 7
set d.attackDamageLevel = 1
set d.healingLevel = 0
set d.survivavilityLevel = 6
set d.movementLevel = 1
set d.crowdControlLevel = 6
set d.HeroFaction = Game.FACTION_UNDEAD
set d.InfoID = 'HFSI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ColdSwirl initializer init
globals
private constant integer SPELL_ID = 'FSA1'
private constant integer UPGRADE_ID = 'FSI1'
private constant real DELAY = 1.6
private constant real DMG_BASE = 80.00
private constant real DMG_LEVEL = 40.00
private constant real SPELL_AREA = 400.00
private constant real FROST_DURATION = 3.00
private constant real UP_FROST_DUR = 1.00
private constant real SUP_AREA = 120.00
private constant string AREA_SFX = "war3mapImported\\FrostNova.mdx"
private constant string AREA_SFX2 = "Abilities\\Weapons\\LichMissile\\LichMissile.mdl"
private unit FS_HERO
integer FROST_ENEMIES = 0
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local effect sfx1 = tb.effect[1]
local effect sfx2 = tb.effect[2]
local effect sfx3 = tb.effect[3]
local effect sfx4 = tb.effect[4]
local real a1 = tb.real[5]
local real a2 = tb.real[6]
local real a3 = tb.real[7]
local real a4 = tb.real[8]
local real arf = tb.real[9]
local real ar = tb.real[10]
local real d = tb.real[11]
local real asfx
local real x1
local real y1
local unit temp
local effect sfxt
local real dmg
local integer ulvl
local group g
local player p
local real dur
set ar = ar + arf
set tb.real[10] = ar
set a1 = a1 + 6.75
set a2 = a2 + 6.75
set a3 = a3 + 6.75
set a4 = a4 + 6.75
set tb.real[5] = a1
set tb.real[6] = a2
set tb.real[7] = a3
set tb.real[8] = a4
set asfx = (a1 + 90.00) * bj_DEGTORAD
set x1 = x + ar * Cos(a1 * bj_DEGTORAD)
set y1 = y + ar * Sin(a1 * bj_DEGTORAD)
call BlzSetSpecialEffectX(sfx1,x1)
call BlzSetSpecialEffectY(sfx1,y1)
call BlzSetSpecialEffectYaw(sfx1,asfx)
call BlzSetSpecialEffectHeight(sfx1,GetLocZ(x1,y1) + 75)
set asfx = (a2 + 90.00) * bj_DEGTORAD
set x1 = x + ar * Cos(a2 * bj_DEGTORAD)
set y1 = y + ar * Sin(a2 * bj_DEGTORAD)
call BlzSetSpecialEffectX(sfx2,x1)
call BlzSetSpecialEffectY(sfx2,y1)
call BlzSetSpecialEffectYaw(sfx2,asfx)
call BlzSetSpecialEffectHeight(sfx2,GetLocZ(x1,y1) + 75)
set asfx = (a3 + 90.00) * bj_DEGTORAD
set x1 = x + ar * Cos(a3 * bj_DEGTORAD)
set y1 = y + ar * Sin(a3 * bj_DEGTORAD)
call BlzSetSpecialEffectX(sfx3,x1)
call BlzSetSpecialEffectY(sfx3,y1)
call BlzSetSpecialEffectYaw(sfx3,asfx)
call BlzSetSpecialEffectHeight(sfx3,GetLocZ(x1,y1) + 75)
set asfx = (a4 + 90.00) * bj_DEGTORAD
set x1 = x + ar * Cos(a4 * bj_DEGTORAD)
set y1 = y + ar * Sin(a4 * bj_DEGTORAD)
call BlzSetSpecialEffectX(sfx4,x1)
call BlzSetSpecialEffectY(sfx4,y1)
call BlzSetSpecialEffectYaw(sfx4,asfx)
call BlzSetSpecialEffectHeight(sfx4,GetLocZ(x1,y1) + 75)
set d = d - 0.03125
set tb.real[11] = d
if d <= 0 then
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
call DestroyEffect(sfx3)
call DestroyEffect(sfx4)
set dmg = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
set ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
set dur = FROST_DURATION + (UP_FROST_DUR * ulvl)
set g = NewGroup()
set p = GetOwningPlayer(u)
set sfxt = AddSpecialEffect(AREA_SFX,x,y)
if IsUpgradeSuperior(u,UPGRADE_ID) then
call BlzSetSpecialEffectScale(sfxt,0.7)
else
call BlzSetSpecialEffectScale(sfxt,0.6)
endif
call DestroyEffect(sfxt)
call GroupEnumUnitsInRange(g,x,y,ar,null)
set FROST_ENEMIES = 0
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
set FROST_ENEMIES = FROST_ENEMIES + 1
call Status.Add(STATUS_FROST,temp,dur,0)
endif
endloop
call ReleaseGroup(g)
set sfxt = null
set g = null
set p = null
endif
set u = null
set t = null
set sfx1 = null
set sfx2 = null
set sfx3 = null
set sfx4 = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = DELAY
local Table tb = Table.create()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real xc
local real yc
local real arf
local effect sfx1
local effect sfx2
local effect sfx3
local effect sfx4
set xc = x + 50 * Cos(0)
set yc = y + 50 * Sin(0)
set sfx1 = AddSpecialEffect(AREA_SFX2,xc,yc)
call BlzSetSpecialEffectScale(sfx1,1.4)
call BlzSetSpecialEffectYaw(sfx1,90 * bj_DEGTORAD)
call BlzSetSpecialEffectHeight(sfx1,75)
set xc = x + 50 * Cos(90 * bj_DEGTORAD)
set yc = y + 50 * Sin(90 * bj_DEGTORAD)
set sfx2 = AddSpecialEffect(AREA_SFX2,xc,yc)
call BlzSetSpecialEffectScale(sfx2,1.4)
call BlzSetSpecialEffectHeight(sfx1,75)
call BlzSetSpecialEffectYaw(sfx2,180 * bj_DEGTORAD)
set xc = x + 50 * Cos(180 * bj_DEGTORAD)
set yc = y + 50 * Sin(180 * bj_DEGTORAD)
set sfx3 = AddSpecialEffect(AREA_SFX2,xc,yc)
call BlzSetSpecialEffectScale(sfx3,1.4)
call BlzSetSpecialEffectYaw(sfx3,270 * bj_DEGTORAD)
call BlzSetSpecialEffectHeight(sfx3,75)
set xc = x + 50 * Cos(270 * bj_DEGTORAD)
set yc = y + 50 * Sin(270 * bj_DEGTORAD)
set sfx4 = AddSpecialEffect(AREA_SFX2,xc,yc)
call BlzSetSpecialEffectScale(sfx4,1.4)
call BlzSetSpecialEffectYaw(sfx4,0 * bj_DEGTORAD)
call BlzSetSpecialEffectHeight(sfx4,75)
set tb.unit[0] = u
set tb.effect[1] = sfx1
set tb.effect[2] = sfx2
set tb.effect[3] = sfx3
set tb.effect[4] = sfx4
set tb.real[5] = 0
set tb.real[6] = 90
set tb.real[7] = 180
set tb.real[8] = 270
if GetHeroMasteryType(u) == 2 then
set d = d / 2
endif
if IsUpgradeSuperior(u,UPGRADE_ID) then
set arf = (SPELL_AREA + SUP_AREA - 50) / (d * 32)
else
set arf = (SPELL_AREA - 50) / (d * 32)
endif
set tb.real[9] = arf
set tb.real[10] = 50
set tb.real[11] = d
call TimerStart(NewTimerEx(tb),0.03125,true,function Callback)
set u = null
set sfx1 = null
set sfx2 = null
set sfx3 = null
set sfx4 = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
set FS_HERO = HERO_AI.hero
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Frozenshell_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope FrostbittenBulwark initializer init
globals
private constant integer SPELL_ID = 'FSA2'
private constant integer UPGRADE_ID = 'FSI2'
private constant real RESIST_BASE = 50.00
private constant real STATUS_BASE = 0.70
private constant real BUFF_DURATION = 10.00
private constant real MA_BUFF_DURATION = 5.00
public Effect SFX
endglobals
private function GetResistance takes integer lvl returns real
return RESIST_BASE + RESIST_BASE * lvl
endfunction
struct FrostbittenBulwark extends array
integer count
integer armor
boolean block
real res
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-res,0)
call AddUnitNegativeStatusReduction(b.target,-STATUS_BASE,false)
if armor != 0 then
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-armor,0,true)
set armor = 0
endif
if block then
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,b.target,-res,0)
set block = false
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer up = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set res = GetResistance(b.level)
call AddUnitNegativeStatusReduction(b.target,STATUS_BASE,false)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,res,0)
if up != 0 then
set armor = 10 * up
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
endif
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set block = true
call BonusStruct.AddSpecial(BONUS_TYPE_BLOCK,b.target,res,0)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A086'
set BUFF_DATA.BuffID = 'B02D'
set BUFF_DATA.Name = "Frostbitten Bulwark"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local real d = BUFF_DURATION
if GetHeroMasteryType(u) == 1 then
set d = d + MA_BUFF_DURATION
endif
if t == null then
call UnitAddBuff(u,u,d,FrostbittenBulwark.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
else
call UnitAddBuff(t,u,d,FrostbittenBulwark.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
endif
set u = null
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,FrostbittenBulwark.buff)
if b != 0 and IsUnitType(data.source,UNIT_TYPE_STRUCTURE) then
if GetRandomInt(1,100) <= 15 then
call Status.Add(STATUS_STUN,data.source,1.2,SFX)
endif
endif
endif
endfunction
private function OnTarget takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
if t != null and IsUnitType(u,UNIT_TYPE_HERO) and IsUnitEnemy(u,GetOwningPlayer(t)) then
if GetUnitBuff(t,FrostbittenBulwark.buff) != 0 and GetRandomInt(1,100) <= 15 then
call Status.Add(STATUS_STUN,u,1.2,SFX)
endif
endif
set u = null
set t = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local trigger t = CreateTrigger()
if GetLearnedSkillLevel() == 1 then
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition(t,function OnTarget)
call DamageEvent.RegisterDamage(Filter(function OnDamage))
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FrostbittenBulwark.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
set SFX = Effect.create("Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathTargetArt.mdl","origin")
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Frozenshell_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Shatter initializer init
globals
private constant integer SPELL_ID = 'FSA3'
private constant integer UPGRADE_ID = 'FSI3'
private constant integer WALL_ID = 'B00A'
private constant real DAMAGE_BASE = 70.00
private constant real DAMAGE_LEVEL = 20.00
private constant real AREA_OF_EFFECT = 190.00
private constant real UP_CD_BASE = -1.00
private constant string MISSILE_SFX = "war3mapImported\\LordofIceMissile.mdx"
private constant string BLOCK_SFX = "war3mapImported\\IceSlam.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local BuffData b
local ability ab
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(UP_CD_BASE)
endif
if up.upID == 'FSI2' and up.isSuperior then
endif
if up.upID == 'FSI4' and GetHeroMasteryType(up.ownerHero.hero) == 1 then
set b = FrostbittenBulwark.buff
set b.Dispelable = false
set b.Stealable = false
set ab = BlzGetUnitAbility(up.ownerHero.hero,'FSA2')
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,0,1)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,1,1)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,2,1)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,3,1)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_CAST_RANGE,0,600)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_CAST_RANGE,1,600)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_CAST_RANGE,2,600)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_CAST_RANGE,3,600)
set ab = null
endif
endfunction
private function WallCallback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
call RemoveDestructable(tb.destructable[0])
call DestroyEffect(tb.effect[1])
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set t = null
endfunction
struct ShatterFirstMissile extends array
private static method onFinish takes Missile missile returns boolean
local group g
local unit temp
local effect sfx
local real dmg
local real x1
local real y1
local real x2
local real y2
local real a2
local real a
local real kd
local real sd
local Table tb
if missile.data == 1 then
set g = NewGroup()
set x1 = missile.x + 220 * Cos(missile.angle - 1.5707)
set y1 = missile.y + 220 * Sin(missile.angle - 1.5707)
set x2 = missile.x + 220 * Cos(missile.angle + 1.5707)
set y2 = missile.y + 220 * Sin(missile.angle + 1.5707)
call LineSegment.EnumUnits(g,x1,y1,x2,y2,AREA_OF_EFFECT)
set dmg = GetDamage(missile.level)
set kd = 1.2
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
set kd = kd + 0.8
endif
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) and not IsUnitMagicImmune(temp) then
set a = Angle(missile.x,missile.y,GetUnitX(temp),GetUnitY(temp))
set sd = Status.Add(STATUS_STUN,temp,kd,Status_EFFECT[STATUS_STUN])
if sd != 0 then
call KPJUnit.create(temp,140,a,sd,0,KPJDefaultConfig4,KPJ_TYPE_KNOCKBACK)
endif
call CodeDamage.Damage(missile.source,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
endif
set sfx = AddSpecialEffect(BLOCK_SFX,missile.x,missile.y)
call BlzSetSpecialEffectScale(sfx,0.40)
call BlzSetSpecialEffectTimeScale(sfx,1.5)
call DestroyEffect(sfx)
set tb = Table.create()
set tb.destructable[0] = CreateDestructable(WALL_ID,missile.x,missile.y,270,0.45,0)
set tb.effect[1] = AddSpecialEffect("Doodads\\Icecrown\\Terrain\\ClearIceRock\\ClearIceRock0.mdl",missile.x,missile.y)
call BlzSetSpecialEffectScale(tb.effect[1],0.45)
call TimerStart(NewTimerEx(tb),4.0,false,function WallCallback)
set sfx = null
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile1 takes unit source, real xs, real ys, real xt, real yt, integer lvl, integer op returns Missile
local Missile missile = Missile.createXYZ(xs,ys,100.00,xt,yt,0.00)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl)
set missile.speed = 26.00
set missile.level = lvl
set missile.data = op
set missile.model = MISSILE_SFX
set missile.scale = 0.50
call ShatterFirstMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real xu = GetUnitX(u)
local real yu = GetUnitY(u)
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real ang = Angle(xu,yu,x,y) * bj_RADTODEG
local real right = (ang + 90) * bj_DEGTORAD
local real left = (ang - 90) * bj_DEGTORAD
local real xc
local real yc
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Ability a
//right
set xc = x + 110 * Cos(right)
set yc = y + 110 * Sin(right)
call SetupMissile1(u,xu,yu,xc,yc,lvl,0)
set xc = x + 210 * Cos(right)
set yc = y + 210 * Sin(right)
call SetupMissile1(u,xu,yu,xc,yc,lvl,0)
//left
set xc = x + 110 * Cos(left)
set yc = y + 110 * Sin(left)
call SetupMissile1(u,xu,yu,xc,yc,lvl,0)
set xc = x + 210 * Cos(left)
set yc = y + 210 * Sin(left)
call SetupMissile1(u,xu,yu,xc,yc,lvl,0)
//center
call SetupMissile1(u,xu,yu,x,y,lvl,1)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Frozenshell_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope ArcticFang initializer init
globals
private constant integer SPELL_ID = 'FSA4'
private constant integer UPGRADE_ID = 'FSI4'
private constant real DELAY = 1.20
private constant real DMG_BASE = 150.00
private constant real DMG_LEVEL = 100.00
private constant real FROST_DUR = 3.00
private constant real SPELL_AREA = 400.00
private constant real MAX_HEIGHT = 500.00
private constant real UP_AREA = 200.00
private constant string TARGET_SFX1 = "war3mapImported\\CrystalImpale.mdl"
private constant string TARGET_SFX2 = "war3mapImported\\CrystalImpaleHit.mdl"
private constant string DPS_SFX = "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorDamage.mdl"
private KPJConfig KPJ_AF
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
struct Chill extends array
real dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int == 3 then
call AddUnitStatusReduction(STATUS_FROST,b.target,0.25,false)
endif
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if Status.UnitHasStatus(STATUS_FROST,b.target) then
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypeMagicOverTime,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(DPS_SFX,b.target,"overhead"))
else
set b.removeInside = true
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = 20.00 * b.level
if b.int == 3 then
call AddUnitStatusReduction(STATUS_FROST,b.target,-0.25,false)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Chill"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer tr = GetExpiredTimer()
local Table tb = GetTimerData(tr)
local unit u = tb.unit[0]
local unit t = tb.unit[1]
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real dmg = GetDamage(lvl)
local real area = SPELL_AREA
local real x = GetUnitX(t)
local real y = GetUnitY(t)
local integer wm = GetHeroMasteryType(u)
local effect sfx
local real xc
local real yc
local real s
local unit temp
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set area = area + UP_AREA
endif
call GroupEnumUnitsInRange(g,x,y,area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ENEMY(temp,p) then
if not IsUnitMagicImmune(temp) then
set sfx = AddSpecialEffect(TARGET_SFX1,GetUnitX(temp),GetUnitY(temp))
call BlzSetSpecialEffectScale(sfx,1.5)
call DestroyEffect(sfx)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX2,t,"origin"))
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call KPJUnit.create(temp,0,0,0.8,MAX_HEIGHT,KPJ_AF,KPJ_TYPE_JUMP)
call Status.Add(STATUS_STUN,temp,1.50,Status_EFFECT[STATUS_STUN])
call UnitAddBuff(temp,u,99.00,Chill.buff,lvl,wm)
if Status.UnitHasStatus(STATUS_FROST,temp) then
call Status.AddTime(STATUS_FROST,temp,FROST_DUR)
else
call Status.Add(STATUS_FROST,temp,FROST_DUR,Status_EFFECT[STATUS_FROST])
endif
endif
endif
endloop
call ReleaseGroup(g)
call ReleaseTimer(tr)
set sfx = null
set tr = null
set g = null
set p = null
set u = null
set t = null
endfunction
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
local Table tb = Table.create()
local timer tr = NewTimerEx(tb)
local real d = DELAY
set tb.unit[0] = u
set tb.unit[1] = t
if GetHeroMasteryType(u) == 2 then
set d = d * 0.75
endif
call Lightning.create("DRAM",u,t,d,0.25,100,100)
call TimerStart(tr,d,false,function Callback)
set tr = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
set KPJ_AF = KPJConfig.create()
set KPJ_AF= KPJConfig.create()
set KPJ_AF.friction = 0
set KPJ_AF.gravity = 0.5
set KPJ_AF.disable = false
set KPJ_AF.hardDisable = false
call Chill.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Frozenshell_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library DamnQueen initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HDQ1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'DQI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Blood Lust"
set up.Text = "|c00b4b4b4Vampiric Horde|r also drains Mana points."
set up.SupText = "Increases |c00b4b4b4Vampiric Horde|r bats attack counter by 2."
set up.LevelData1 = "5 Mana Drained"
set up.LevelData2 = "10 Mana Drained"
set up.LevelData3 = "15 Mana Drained"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNCarrionSwarm.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'DQI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Spectral Touch"
set up.Text = "Increases |c00b4b4b4Spirit Shout|r travel speed."
set up.SupText = "|c00b4b4b4Spirit Touch|r also damages the enemies upon teleport."
set up.LevelData1 = "Low speed bonus"
set up.LevelData2 = "Medium speed bonus"
set up.LevelData3 = "High speed bonus"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNPossession.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'DQI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Infinite Agony"
set up.Text = "Increases |c00b4b4b4Chains Of Fatality|r max range."
set up.SupText = "|c00b4b4b4Chains Of Fatality|r no longer breaks if the target is being affected by |c00b4b4b4Vampiric Horde|r."
set up.LevelData1 = "+50 range"
set up.LevelData2 = "+100 range"
set up.LevelData3 = "+150 range"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNLifeDrain.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'DQI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Midnight Terror"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HDQ1'
set d.Name = "Doomed Queen"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNBanshee.blp"
set d.WinAni = "spell"
set d.Block = 0
set d.Evasion = 0
set d.Resistance = 50
set d.LifeRegen = 1.0
set d.ManaRegen = 2.0
set d.Armor = 2
set d.AttackRange = 450
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'DQA1'
set d.HeroAbility2 = 'DQA2'
set d.HeroAbility3 = 'DQA3'
set d.HeroAbility4 = 'DQA4'
set d.HeroAbility6 = 'A01R'
set d.ChooseIconID = 'c014'
set d.ChooseDummy = 'dh14'
set d.spellDamageLevel = 7
set d.attackDamageLevel = 1
set d.healingLevel = 7
set d.survivavilityLevel = 6
set d.movementLevel = 3
set d.crowdControlLevel = 6
set d.HeroFaction = Game.FACTION_UNDEAD
set d.InfoID = 'HDQI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope VampiricHorde initializer init
globals
private constant integer SPELL_ID = 'DQA1'
private constant integer UPGRADE_ID = 'DQI1'
private constant integer DUMMY_ID = 'n01D'
private constant real BUFF_DURATION = 8.00
private constant real HP_BURNED_BASE = 10.00
private constant real HP_BURNED_LEVEL = 5.00
private constant real INTERVAL = 0.50
private constant real MISSILE_DISTANCE = 1200.00
private constant string MISSILE_SFX = "war3mapImported\\Shadow Saierra Viskal.mdx"
private constant real MISSILE_SPEED = 15.00
private constant real MISSILE_SCALE = 1.00
private constant string MISSILE_RETURN_SFX = "war3mapImported\\BatsOnly.mdx"
endglobals
private function GetMaxAffected takes integer lvl returns integer
return 4
endfunction
private function GetHpBurned takes integer lvl returns real
return HP_BURNED_BASE + HP_BURNED_LEVEL * lvl
endfunction
struct VampiricHordeReturnMissile extends array
private static method onFinish takes Missile missile returns boolean
if missile.level == 2 then
call UnitAddBuff(missile.target,missile.source,BUFF_DURATION,VampiricHorde.buff,GetUnitAbilityLevel(missile.source,SPELL_ID),0)
else
call CodeDamage.Damage(missile.target,missile.target,missile.damage,udg_DamageTypeHeal,"",0,0)
if missile.data != 0 then
call UnitAddMp(missile.target,missile.data)
endif
endif
call UnitRemoveAbility(missile.dummy,'A002')
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissileReturn takes unit source, unit target, real heal, real mana, integer op returns Missile
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real a = Angle(xs,ys,GetUnitX(target),GetUnitY(target))
local Missile missile = Missile.create(xs,ys,25.00,a,0,25.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(target)
set missile.damage = heal
set missile.speed = 15.00
set missile.model = MISSILE_RETURN_SFX
set missile.scale = MISSILE_SCALE
set missile.data = R2I(mana)
set missile.level = op
call UnitAddAbility(missile.dummy,'A002')
call SetUnitColor(missile.dummy,PLAYER_COLOR_PURPLE)
call VampiricHordeReturnMissile.launch(missile)
return missile
endfunction
struct VampiricHorde extends array
real hpBurned
real mpBurned
real hpBurnedPeriod
real mpBurnedPeriod
boolean removed
boolean mast
integer link
unit dummy
real time
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LinkedList list = GetUnitData(b.owner,"VH_List")
call SetUnitVertexColor(dummy,0,0,0,0)
if not removed and not mast then
call SetupMissileReturn(b.target,b.owner,hpBurned,mpBurned,0)
call RemoveUnit(dummy)
endif
call KillUnit(dummy)
call list.remove(link)
set dummy = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set time = time + 0.03125
if not UnitAlive(dummy) then
set removed = true
set b.removeInside = true
if GetHeroMasteryType(b.owner) == 3 then
if GetRandomInt(1,100) <= 25 then
call SetupMissileReturn(b.owner,b.target,0,0,2)
endif
endif
return
endif
call SetUnitX(dummy,GetUnitX(b.target))
call SetUnitY(dummy,GetUnitY(b.target))
if time == INTERVAL then
set time = 0
call UnitRemoveHp(b.target,hpBurnedPeriod)
set hpBurned = hpBurned + hpBurnedPeriod
if mpBurnedPeriod != 0 then
call UnitRemoveMp(b.target,mpBurnedPeriod)
set mpBurned = mpBurned + mpBurnedPeriod
endif
if mast then
call CodeDamage.Damage(b.owner,b.owner,hpBurnedPeriod,udg_DamageTypeHealOverTime,"",0,0)
if mpBurnedPeriod != 0 then
call UnitAddMp(b.owner,mpBurnedPeriod)
endif
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LinkedList list = GetUnitData(b.owner,"VH_List")
set hpBurned = 0
set mpBurned = 0
set hpBurnedPeriod = GetHpBurned(b.level)
set mpBurnedPeriod = 5 * GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set link = list.add(b)
set removed = false
set dummy = CreateUnit(GetOwningPlayer(b.owner),DUMMY_ID,GetUnitX(b.target),GetUnitY(b.target),0)
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
call BlzSetUnitMaxHP(dummy,5 * 2)
else
call BlzSetUnitMaxHP(dummy,3 * 2)
endif
set time = 0
set mast = GetHeroMasteryType(b.owner) == 1
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01Y'
set BUFF_DATA.BuffID = 'B00Y'
set BUFF_DATA.Name = "Vampiric Horde"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct VampiricHordeMissile extends array
private static method onCollide takes Missile missile, unit hit returns boolean
if missile.data > 0 then
if FILT_UNIT_ENEMY(hit,missile.owner) and not IsUnitMagicImmune(hit) then
set missile.data = missile.data - 1
call UnitAddBuff(hit,missile.source,BUFF_DURATION,VampiricHorde.buff,missile.level,0)
if missile.data == 0 then
return true
endif
endif
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real x, real y returns Missile
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real a = Angle(xs,ys,x,y)
local real xt = xs + MISSILE_DISTANCE * Cos(a)
local real yt = ys + MISSILE_DISTANCE * Sin(a)
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local Missile missile = Missile.createXYZ(xs,ys,25.00,xt,yt,25.00)
set missile.source = source
set missile.data = GetMaxAffected(lvl)
set missile.owner = GetOwningPlayer(source)
set missile.level = lvl
set missile.speed = MISSILE_SPEED
set missile.scale = MISSILE_SCALE
set missile.collision = 300.00
call VampiricHordeMissile.launch(missile)
set missile.model = MISSILE_SFX
return missile
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
if GetLearnedSkillLevel() == 1 then
call SetUnitData(u,"VH_List",LinkedList.create())
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
call SetupMissile(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call VampiricHorde.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID,function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DamnQueen_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
call Preload(MISSILE_RETURN_SFX)
endfunction
endscope
scope SpiritShout initializer init
globals
private constant integer SPELL_ID = 'DQA2'
private constant integer UPGRADE_ID = 'DQI2'
private constant integer EXTRA_ID = 'A0AT'
private constant real DAMAGE_BASE = 90.00
private constant real ETHEREAL_DUR_BASE = 1.00
private constant real ETHEREAL_DUR_LVL = 0.50
private constant real SILENCE_AREA_INI = 150.00
private constant real UP_SPEED = 4.00
private constant real MISSILE_DISTANCE = 1200.00
private constant string MISSILE_SFX = "war3mapImported\\BansheeCryMissile.mdx"
private constant string AREA_SFX = "Abilities\\Spells\\Undead\\UnholyFrenzyAOE\\UnholyFrenzyAOETarget.mdl"
private constant real MISSILE_SPEED = 20.00
private constant real MISSILE_SCALE = 2.2
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE * lvl
endfunction
struct BansheeCryMissile extends array
private static method onRemove takes Missile missile returns boolean
call UnitRemoveAbility(missile.source,EXTRA_ID)
call BlzUnitHideAbility(missile.source,SPELL_ID,false)
return true
endmethod
private static method onCollide takes Missile missile, unit hit returns boolean
if FILT_UNIT_ENEMY(hit,missile.owner) and not IsUnitMagicImmune(hit) then
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypeMagicAoe,"",0,0)
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real x, real y returns Missile
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real a = Angle(xs,ys,x,y)
local real xt = xs + MISSILE_DISTANCE * Cos(a)
local real yt = ys + MISSILE_DISTANCE * Sin(a)
local Missile missile = Missile.createXYZ(xs,ys,45.00,xt,yt,45.00)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.data = GetUnitAbilityLevel(source,SPELL_ID)
set missile.damage = GetDamage(missile.data)
set missile.speed = MISSILE_SPEED + UP_SPEED * GetUpgradeSkillLevel(source,UPGRADE_ID)
set missile.model = MISSILE_SFX
set missile.scale = MISSILE_SCALE
set missile.level = GetUnitAbilityLevel(source,SPELL_ID)
set missile.collision = SILENCE_AREA_INI
call UnitAddAbility(source,EXTRA_ID)
call UnitMakeAbilityPermanent(source,true,EXTRA_ID)
call BlzUnitHideAbility(source,SPELL_ID,true)
call SetUnitData(source,"SS_M",missile)
call BansheeCryMissile.launch(missile)
set AIDQ.a2missile = missile
return missile
endfunction
private function onCastExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local Missile m = GetUnitData(u,"SS_M")
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local boolean b = IsUpgradeSuperior(u,UPGRADE_ID)
local real dmg = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
local real d = ETHEREAL_DUR_BASE + ETHEREAL_DUR_LVL * GetUnitAbilityLevel(u,SPELL_ID)
local unit temp
local effect sfx
call SetUnitPosition(u,m.x,m.y)
set sfx = AddSpecialEffect(AREA_SFX,m.x,m.y)
call BlzSetSpecialEffectColor(sfx,230,210,255)
call BlzSetSpecialEffectScale(sfx,1.6)
call DestroyEffect(sfx)
call GroupEnumUnitsInRange(g,m.x,m.y,250,null)
call m.destroy()
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
if b then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
call Status.Add(STATUS_BANISH,temp,d,Status_EFFECT[STATUS_BANISH])
endif
endloop
set u = null
call ReleaseGroup(g)
set g = null
set p = null
endfunction
private function onCast takes nothing returns nothing
call SetupMissile(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCastExtra)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DamnQueen_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope ChainsOfFatality initializer init
globals
private constant integer SPELL_ID = 'DQA3'
private constant integer UPGRADE_ID = 'DQI3'
private constant real DAMAGE_BASE = 20.00
private constant real DAMAGE_LEVEL = 5.00
private constant integer MA_ATTACK_SLOW = 30
private constant real BUFF_DURATION = 6.00
private constant real INTERVAL = 0.50
private constant real BREAK_DISTANCE = 600.00
private constant real UP_BREAK_DISTANCE = 50.00
private constant string PERIOD_SFX = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct ChainsOfFatality extends array
Lightning lg
Movespeed ms
Movespeed ms2
boolean sup
real dmg
real bdist
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call lg.destroy()
call ms.destroy()
call ms2.destroy()
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local VampiricHorde bv = GetUnitBuff(b.target,VampiricHorde.buff).buffAllocIndex
local real d = 0
if (DistanceBetweenUnits(b.target,b.owner) >= bdist and not (sup and bv != 0)) or not UnitAlive(b.owner) then
set b.removeInside = true
else
if bv != 0 then
set d = bv.hpBurnedPeriod
set b.elapsedTime = b.elapsedTime - INTERVAL
endif
set d = d + dmg
call CodeDamage.Damage(b.owner,b.target,d,udg_DamageTypeMagicOverTime,"",0,0)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer msq = 10 + 10 * b.level
set lg = Lightning.create("WHCH",b.owner,b.target,9999,0.00,120,120)
call lg.setLightColor(175,50,225,255)
if GetHeroMasteryType(b.owner) == 2 then
set msq = msq + 20
endif
set ms = Movespeed.create(b.target,0,-msq)
set ms2 = Movespeed.create(b.owner,0,msq)
set dmg = GetDamage(b.level)
set bdist = BREAK_DISTANCE + UP_BREAK_DISTANCE * GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set sup = IsUpgradeSuperior(b.owner,UPGRADE_ID)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A04A'
set BUFF_DATA.BuffID = 'B01L'
set BUFF_DATA.Name = "Chains Of Fatality"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Period = INTERVAL
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local Ability a
if GetUnitAbilityLevel(u,SPELL_ID) == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call a.addMaxCharges(3)
endif
set u = null
endfunction
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
call UnitAddBuff(t,u,BUFF_DURATION,ChainsOfFatality.buff,lvl,0)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID and GetHeroMasteryType(up.ownerHero.hero) == 2 then
set ChainsOfFatality.buff.PierceImmune = true
set ChainsOfFatality.buff.Dispelable = true
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.isCharged = true
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ChainsOfFatality.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
call RegisterSpellLearn(SPELL_ID,function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DamnQueen_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A04A',PRELOAD_SECOND)
endfunction
endscope
scope TerrorShout initializer init
globals
private constant integer SPELL_ID = 'DQA4'
private constant integer UPGRADE_ID = 'DQI4'
private constant real AREA_BASE = 250.00
private constant real AREA_LEVEL = 50.00
private constant real DURATION_BASE = 2.50
private constant real DURATION_LEVEL = 0.50
private constant string AREA_SFX = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl"
endglobals
private function GetArea takes integer lvl returns real
return AREA_BASE + AREA_LEVEL * lvl
endfunction
private function GetDuration takes integer lvl returns real
return DURATION_BASE + DURATION_LEVEL * lvl
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real area = GetArea(lvl)
local real dur = GetDuration(lvl)
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local unit temp
local Link node
local Buff b
call DestroyEffect(AddSpecialEffect(AREA_SFX,x,y))
call GroupEnumUnitsInRange(g,x,y,area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and IsUnitType(temp,UNIT_TYPE_HERO) then
call Status.Add(STATUS_FEAR,temp,dur,Status_EFFECT[STATUS_FEAR])
endif
endloop
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set node = VampiricHorde.DATAS.head
loop
exitwhen node == null
set b = node.data
if b.owner == u then
if IsUnitType(b.target,UNIT_TYPE_HERO) then
call Status.Add(STATUS_FEAR,b.target,dur,Status_EFFECT[STATUS_FEAR])
endif
endif
set node = node.next
endloop
endif
call ReleaseGroup(g)
set g = null
set p = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DamnQueen_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
library Warlock initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HWL1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'WLI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Nether Affliction"
set up.Text = "|c00b4b4b4Nether Curse|r also reduce enemies |c00ffff95Attack Damage|r."
set up.SupText = "Increases the duration of |c00b4b4b4Nether Curse|r by 3 seconds."
set up.LevelData1 = "-20 Damage"
set up.LevelData2 = "-30 Damage"
set up.LevelData3 = "-40 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNCarrionSwarm.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'WLI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Devastation"
set up.Text = "Increases |c00b4b4b4Chaos Meteor|r Leash duration."
set up.SupText = "Increases |c00b4b4b4Chaos Meteor|r max damage by 200."
set up.LevelData1 = "+0.5 seconds"
set up.LevelData2 = "+1.0 seconds"
set up.LevelData3 = "+1.5 seconds"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNPossession.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'WLI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Shadow Suction"
set up.Text = "Increases |c00b4b4b4Life Drain|r damage if the target has less than 40% of his Hp."
set up.SupText = "Increases secondary |c00b4b4b4Life Drain|r damage factor by 25%."
set up.LevelData1 = "+10 Damage"
set up.LevelData2 = "+20 Damage"
set up.LevelData3 = "+30 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNLifeDrain.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'WLI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Demonic Knowledge"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HWL1'
set d.Name = "Warlock"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNGuldan.blp"
set d.WinAni = "stand channel"
set d.Block = 40
set d.Evasion = 0
set d.Resistance = 40
set d.LifeRegen = 0.5
set d.ManaRegen = 1.0
set d.Armor = 2
set d.AttackRange = 500
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'WLA1'
set d.HeroAbility2 = 'WLA2'
set d.HeroAbility3 = 'WLA3'
set d.HeroAbility4 = 'WLA4'
set d.ChooseIconID = 'c020'
set d.ChooseDummy = 'dh20'
set d.spellDamageLevel = 8
set d.attackDamageLevel = 1
set d.healingLevel = 5
set d.survivavilityLevel = 3
set d.movementLevel = 2
set d.crowdControlLevel = 5
set d.HeroFaction = Game.FACTION_UNDEAD
set d.InfoID = 'HWLI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope NetherCurse initializer init
globals
private constant integer SPELL_ID = 'WLA1'
private constant integer UPGRADE_ID = 'WLI1'
private constant real BUFF_DURATION = 7.00
private constant real DAMAGE_BASE = 15.00
private constant real SPELL_RED_BASE = 0.15
private constant real SPELL_RED_LEVEL = 0.05
private constant real AREA_OF_EFFECT = 210.00
private constant real INTERVAL = 1.00
private constant real SUP_DURATION = 3.00
private constant string AREA_SFX = "war3mapImported\\DamnationGreen.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE * lvl
endfunction
private function GetSpellReduction takes integer lvl returns real
return SPELL_RED_BASE + SPELL_RED_LEVEL * lvl
endfunction
struct NetherCurse extends array
real dmg
real red
integer dmgP
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if dmgP != 0 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmgP,0,true)
endif
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypeMagicOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = GetDamage(b.level)
set red = GetSpellReduction(b.level)
set AIWL.netherCurseCount = AIWL.netherCurseCount + 1
if b.int != 0 then
set dmgP = 10 + 10 * b.int
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmgP,0,true)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A017'
set BUFF_DATA.BuffID = 'B03J'
set BUFF_DATA.Name = "Nether Curse"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = INTERVAL
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local player p = GetOwningPlayer(u)
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local group g = NewGroup()
local unit temp
local real d = BUFF_DURATION
call GroupEnumUnitsInRange(g,x,y,AREA_OF_EFFECT,null)
call DestroyEffect(AddSpecialEffect(AREA_SFX,x,y))
if IsUpgradeSuperior(u,UPGRADE_ID) then
set d = d + SUP_DURATION
endif
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call UnitAddBuff(temp,u,d,NetherCurse.buff,lvl,ulvl)
endif
endloop
call ReleaseGroup(g)
set g = null
set u = null
set p = null
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local NetherCurse b
if data.dmgType <= 6 or data.dmgType == 8 then
set b = GetUnitBuff(data.source,NetherCurse.buff).buffAllocIndex
if b != 0 then
set data.mult = data.mult - b.red
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call NetherCurse.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Warlock_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
scope ChaosMeteor initializer init
globals
private constant integer SPELL_ID = 'WLA2'
private constant integer UPGRADE_ID = 'WLI2'
private constant real DAMAGE_BASE = 100.00
private constant real DAMAGE_LEVEL = 80.00
private constant real LEASH_DURATION = 3.00
private constant real LEASH_RANGE = 400.00
private constant real IMPACT_DELAY = 1.00
private constant real AREA_OF_EFFECT = 170.00
private constant real UP_LEASH_DURATION = 0.50
private constant real SUP_DAMAGE = 200.00
private constant string METEOR_SFX = "war3mapImported\\FelMeteor.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct ChaosMeteorLeash extends array
real maxDist
real x
real y
effect sfx
boolean pull
Lightning light
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call light.destroy()
call DestroyEffect(sfx)
set sfx = null
if pull then
call Status.Remove(STATUS_DISABLE,b.target)
call BlzUnitDisableAbility(b.target,'Amov',false,false)
call SetUnitPathing(b.target,true)
endif
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real xu = GetUnitX(b.target)
local real yu = GetUnitY(b.target)
local real d = Distance(x,y,xu,yu)
local real a
if not pull then
if d > maxDist then
set pull = true
call Status.Add(STATUS_DISABLE,b.target,0,0)
call BlzUnitDisableAbility(b.target,'Amov',true,false)
call SetUnitPathing(b.target,false)
set b.duration = 9999
set b.elapsedTime = 0.00
endif
else
if d > 50 then
set a = Angle(xu,yu,x,y)
set xu = xu + 16 * Cos(a)
set yu = yu + 16 * Sin(a)
call SetUnitX(b.target,xu)
call SetUnitY(b.target,yu)
else
set b.removeInside = true
set pull = false
call Status.Remove(STATUS_DISABLE,b.target)
call BlzUnitDisableAbility(b.target,'Amov',false,false)
call SetUnitPathing(b.target,true)
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set maxDist = LEASH_RANGE
set pull = false
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Chaos Meteor Leash"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real x = tb.real[1]
local real y = tb.real[2]
local real c = tb.real[3]
local effect sfx = tb.effect[4]
local real h = tb.real[5]
local unit array udmg
local integer lvl
local integer ulvl
local integer count = 0
local real dmg
local player p
local group g
local unit temp
local Buff b
set c = c + 0.03125
set h = h - tb.real[6]
call BlzSetSpecialEffectHeight(sfx,tb.real[7] + h)
if c >= IMPACT_DELAY then
set g = NewGroup()
set p = GetOwningPlayer(u)
set lvl = GetUnitAbilityLevel(u,SPELL_ID)
set dmg = GetDamage(lvl)
call DestroyEffect(sfx)
if IsUpgradeSuperior(u,UPGRADE_ID) then
set dmg = dmg + SUP_DAMAGE
endif
call GroupEnumUnitsInRange(g,x,y,AREA_OF_EFFECT,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
set ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
if IsUnitType(temp,UNIT_TYPE_HERO) then
set count = count + 1
set udmg[count] = temp
set b = UnitAddBuff(temp,u,LEASH_DURATION + UP_LEASH_DURATION * ulvl,ChaosMeteorLeash.buff,lvl,0)
if b != 0 then
set ChaosMeteorLeash[b.buffAllocIndex].x = x
set ChaosMeteorLeash[b.buffAllocIndex].y = y
set ChaosMeteorLeash[b.buffAllocIndex].light = Lightning.createEx("LEAS",x,y,0.00,GetUnitX(temp),GetUnitY(temp),85,999,0)
call ChaosMeteorLeash[b.buffAllocIndex].light.attachToUnitTarget(temp)
call ChaosMeteorLeash[b.buffAllocIndex].light.setLightColor(50,255,50,255)
set ChaosMeteorLeash[b.buffAllocIndex].sfx = AddSpecialEffect(METEOR_SFX,x,y)
call BlzSetSpecialEffectScale(ChaosMeteorLeash[b.buffAllocIndex].sfx,0.25)
endif
else
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
endif
endloop
if count != 0 then
set dmg = dmg / count
loop
call CodeDamage.Damage(u,udmg[count],dmg,udg_DamageTypeMagicAoe,"",0,0)
set udmg[count] = null
set count = count - 1
exitwhen count == 0
endloop
endif
call ReleaseTimer(t)
call ReleaseGroup(g)
call tb.flush()
call tb.destroy()
set g = null
set p = null
else
set tb.real[3] = c
set tb.real[5] = h
endif
set u = null
set t = null
set sfx = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local AoE aoe = AoE.create(x,y,null,AREA_OF_EFFECT)
call BlzSetSpecialEffectColor(aoe.sfx,149,245,66)
call aoe.setTime(1.00)
set tb.unit[0] = u
set tb.real[1] = x
set tb.real[2] = y
set tb.real[3] = 0
set tb.effect[4] = AddSpecialEffect(METEOR_SFX,x,y)
set tb.real[5] = 1500
set tb.real[6] = 46.87
set tb.real[7] = GetLocZ(x,y)
call BlzSetSpecialEffectHeight(tb.effect[4],tb.real[7] + 1500)
call TimerStart(t,0.03125,true,function callback)
set t = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ChaosMeteorLeash.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Warlock_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(METEOR_SFX)
endfunction
endscope
scope LifeDrain initializer init
globals
private constant integer SPELL_ID = 'WLA3'
private constant integer UPGRADE_ID = 'WLI3'
private constant real DAMAGE_BASE = 10.00
private constant real DAMAGE_LEVEL = 10.00
private constant real MAX_RANGE = 800.00
private constant real SECONDARY_DELAY = 3.00
private constant real SECONDARY_FACTOR = 0.50
private constant real INTERVAL = 0.50
private constant real UP_DAMAGE_BASE = 10.00
private constant real SUP_FACTOR = 0.75
private constant real MA_MAX_RANGE = 1400.00
private group TEMP_GROUP
private unit U
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetRandomEnemy takes player p, real x, real y, real range returns unit
local unit ru = null
local unit temp
local integer c = 0
call GroupClear(TEMP_GROUP)
call GroupEnumUnitsInRange(TEMP_GROUP,x,y,range,null)
loop
set temp = FirstOfGroup(TEMP_GROUP)
exitwhen temp == null
call GroupRemoveUnit(TEMP_GROUP,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and not UnitHasBuff(temp,LifeDrain.buff) then
set c = c + 1
if GetRandomInt(1,c) == 1 then
set ru = temp
endif
endif
endloop
set temp = null
set U = ru
set ru = null
return U
endfunction
struct LifeDrainMinor extends array
real life
real count
unit source
Lightning light
integer ulvl
real maxr
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call light.destroy()
set source = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local DamageOptions op
set count = count + 0.03125
if count >= INTERVAL then
set count = 0
set op = DamageOptions.create()
set op.notCritical = true
if ulvl != 0 and GetUnitLifePercent(b.target) < 40.00 then
call CodeDamage.Damage(b.owner,b.target,life + 10 * ulvl,udg_DamageTypeMagicOverTime,"LifeDrain",0,op)
else
call CodeDamage.Damage(b.owner,b.target,life,udg_DamageTypeMagicOverTime,"LifeDrain",0,op)
endif
endif
if DistanceBetweenUnits(b.target,source) >= maxr then
set b.removeInside = true
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
set life = GetDamage(b.level) * SUP_FACTOR
else
set life = GetDamage(b.level) * SECONDARY_FACTOR
endif
set source = GetUnitByIndex(b.int)
set count = 0
set ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set light = Lightning.create("DRAL",source,b.target,100,0.00,100,100)
if GetHeroMasteryType(b.owner) == 2 then
set maxr = MA_MAX_RANGE
else
set maxr = MAX_RANGE
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Life Drain Minor"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct LifeDrain extends array
real life
real count
real count1
unit second
real interval
integer countInt
boolean mast
Lightning light
integer ulvl
real maxr
real delay2
integer ult
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call light.destroy()
if GetUnitCurrentOrder(b.owner) == ORDER_drain and b.int != 1 then
call IssueImmediateOrderById(b.owner,ORDER_stop)
endif
if second != null then
call UnitRemoveBuff(second,LifeDrainMinor.buff)
set second = null
endif
call SetUnitData(b.owner,"LifeDrain",0)
set mast = false
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local unit rand
local Buff b2
local DamageOptions op
set count1 = count1 + 0.03125
if mast then
if interval > 0.20 then
set countInt = countInt + 1
if countInt == 32 then
set countInt = 0
set interval = interval - 0.06
endif
endif
endif
if count1 >= interval then
set count1 = 0
set op = DamageOptions.create()
set op.notCritical = true
if GetUnitLifePercent(b.target) < 40.00 then
if ulvl != 0 then
call CodeDamage.Damage(b.owner,b.target,life + 10 * ulvl,udg_DamageTypeMagicOverTime,"LifeDrain",0,op)
else
call CodeDamage.Damage(b.owner,b.target,life,udg_DamageTypeMagicOverTime,"LifeDrain",0,op)
endif
else
call CodeDamage.Damage(b.owner,b.target,life,udg_DamageTypeMagicOverTime,"LifeDrain",0,op)
endif
if b.int == 0 then
if second == null then
set count = count + INTERVAL
if count >= delay2 then
set count = 0
set rand = GetRandomEnemy(GetOwningPlayer(b.owner),GetUnitX(b.target),GetUnitY(b.target),400)
if rand != null then
set b2 = UnitAddBuff(rand,b.owner,100,LifeDrainMinor.buff,b.level,GetUnitUserData(b.target))
if b2 != 0 then
set second = rand
endif
set rand = null
endif
endif
endif
endif
endif
if second != null then
if not UnitHasBuff(second,LifeDrainMinor.buff) then
set second = null
set count = 0
endif
endif
if DistanceBetweenUnits(b.target,b.owner) >= maxr or GetUnitCurrentOrder(b.owner) != ORDER_drain then
set b.removeInside = true
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set life = GetDamage(b.level)
set ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set count = 0
set count1 = 0
set second = null
set light = Lightning.create("DRAL",b.owner,b.target,100,0.00,100,100)
call SetUnitData(b.owner,"LifeDrain",b)
if GetHeroMasteryType(b.owner) == 1 then
call Status.Add(STATUS_SPELL_IMMUNITY,b.owner,3.50,Status_EFFECT[STATUS_SPELL_IMMUNITY])
endif
if GetHeroMasteryType(b.owner) == 2 then
set maxr = MA_MAX_RANGE
set mast = true
else
set maxr = MAX_RANGE
endif
set countInt = 0
set interval = INTERVAL
set delay2 = SECONDARY_DELAY
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Life Drain"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u, unit t returns nothing
local Buff b = GetUnitData(u,"LifeDrain")
local InnerDemon id = GetUnitBuff(u,InnerDemon.buff).buffAllocIndex
if b != 0 then
set b.int = 1
call b.remove()
endif
if id != 0 then
if id.charge then
call id.setTarget(t)
else
if id.target != t then
call IssueTargetOrderById(id.dummy,ORDER_attack,t)
endif
endif
endif
call UnitAddBuff(t,u,100,LifeDrain.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t)
else
call IssueImmediateOrderById(u,ORDER_stop)
endif
set t = null
set u = null
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local InnerDemon id
if data.codeDmg.codeName == "LifeDrain" and not data.isAbsorbed then
call CodeDamage.Damage(data.source,data.source,data.damageMod,udg_DamageTypeHeal,"",0,0)
endif
if data.codeDmg.codeName == "DemonDamage" then
set id = GetUnitBuff(data.source,InnerDemon.buff)
if id != 0 then
if id.wmast then
call UnitAddMp(data.source,data.damageMod * 0.25)
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
set TEMP_GROUP = CreateGroup()
call SPELL_DATA()
call LifeDrain.Initialize()
call LifeDrainMinor.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDamage(Filter(function OnDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Warlock_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope InnerDemon initializer init
globals
private constant integer SPELL_ID = 'WLA4'
private constant integer UPGRADE_ID = 'WLI4'
private constant integer CHARGE_ID = 'A018'
private constant integer DUMMY_ID = 'h006'
private constant real DURATION = 25.00
private constant real LIFE_COST_BASE = 30.00
private constant real LIFE_COST_LEVEL = 10.00
private constant real CHARGED_RANGE = 1600.00
private constant real CHARGED_INTERVAL = 0.50
private constant real CHARGED_AOE = 145.00
private constant string MISSILE_SFX = "Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return LIFE_COST_BASE + LIFE_COST_LEVEL * lvl
endfunction
struct InnerDemonMissile extends array
private static method onCollide takes Missile missile, unit hit returns boolean
if FILT_UNIT_ENEMY(hit,missile.owner) and not IsUnitMagicImmune(hit) then
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypeMagicAoe,"DemonDamage",0,0)
call Status.Add(STATUS_STUN,hit,1.0,Status_EFFECT[STATUS_STUN])
call DestroyEffect(AddSpecialEffectTarget(MISSILE_SFX,hit,"overhead"))
endif
return false
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real a, real dmg returns Missile
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real xt = xs + CHARGED_RANGE * Cos(a)
local real yt = ys + CHARGED_RANGE * Sin(a)
local Missile missile = Missile.createXYZ(xs,ys,200.00,xt,yt,50.00)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.damage = dmg
set missile.speed = 25.00
set missile.model = MISSILE_SFX
set missile.scale = 2.0
set missile.collision = CHARGED_AOE
call InnerDemonMissile.launch(missile)
return missile
endfunction
struct InnerDemon extends array
unit dummy
unit target
effect sfxTarget
effect sfxCharge
real lifeCost
boolean charge
integer count
real update
boolean hiden
boolean wmast
public method setTarget takes unit u returns nothing
if target != u then
call DestroyEffect(sfxTarget)
set sfxTarget = AddSpecialEffect(MISSILE_SFX,GetUnitX(target),GetUnitY(target))
set target = u
endif
endmethod
public method startCharge takes nothing returns nothing
local real a = GetUnitFacing(dummy)
local real x = GetUnitX(dummy) + 75 * Cos(a)
local real y = GetUnitY(dummy) + 75 * Sin(a)
set charge = true
set sfxCharge = AddSpecialEffect(MISSILE_SFX,x,y)
call BlzSetSpecialEffectScale(sfxCharge,0.30)
call BlzSetSpecialEffectHeight(sfxCharge,GetLocZ(x,y) + 250)
call BlzSetSpecialEffectYaw(sfxCharge,a)
call IssueImmediateOrder(dummy,"stop")
call BlzUnitDisableAbility(dummy,'Aatk',true,false)
call SetUnitAnimationByIndex(dummy,3)
endmethod
public method stopCharge takes nothing returns nothing
local real dmg = lifeCost * count
//local real a = AngelBetweenUntis(dummy,target)
set charge = false
call DestroyEffect(sfxCharge)
call IssueImmediateOrder(dummy,"stop")
call BlzUnitDisableAbility(dummy,'Aatk',false,false)
call SetUnitAnimation(dummy, "stand")
call SetupMissile(thisBuff.target,GetUnitFacing(dummy) * bj_DEGTORAD,dmg)
set count = 0
set update = 0
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call KillUnit(dummy)
call UnitRemoveAbility(b.target,CHARGE_ID)
call DestroyEffect(sfxCharge)
set sfxCharge = null
call DestroyEffect(sfxTarget)
set sfxTarget = null
set dummy = null
set target = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local real x1 = GetUnitX(target)
local real y1 = GetUnitY(target)
local real a
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
if IsUnitHidden(b.target) or Status.UnitHasStatus(STATUS_CYCLONE,b.target) or Status.UnitHasStatus(STATUS_HEX,b.target) then
if not hiden then
call UnitRemoveAbility(dummy,'Aloc')
call ShowUnit(dummy,false)
call PauseUnit(dummy,true)
set hiden = true
endif
else
if hiden then
set hiden = false
call ShowUnit(dummy,true)
call PauseUnit(dummy,false)
call UnitAddAbility(dummy,'Aloc')
endif
endif
if target == null then
set a = GetUnitFacing(b.target)
call BlzSetUnitFacingEx(dummy,a)
else
if Distance(x,y,x1,y1) > 800 or not UnitAlive(target) then
set target = null
call DestroyEffect(sfxTarget)
set sfxTarget = null
call IssueImmediateOrder(dummy,"stop")
else
set a = AngleBetweenUnits(dummy,target)
call BlzSetUnitFacingEx(dummy,a * bj_RADTODEG)
endif
if sfxTarget != null then
call BlzSetSpecialEffectX(sfxTarget,GetUnitX(target))
call BlzSetSpecialEffectY(sfxTarget,GetUnitY(target))
call BlzSetSpecialEffectHeight(sfxTarget,125)
endif
endif
if charge then
set update = update + 0.03125
if update >= CHARGED_INTERVAL then
set update = 0
call QueueUnitAnimation(dummy,"spell")
if count < 10 then
call UnitRemoveHp(b.target,lifeCost)
set count = count + 1
endif
endif
set a = GetUnitFacing(dummy) * bj_DEGTORAD
set x = x + 75 * Cos(a)
set y = y + 75 * Sin(a)
call BlzSetSpecialEffectX(sfxCharge,x)
call BlzSetSpecialEffectY(sfxCharge,y)
call BlzSetSpecialEffectHeight(sfxCharge,GetLocZ(x,y) + 250)
call BlzSetSpecialEffectScale(sfxCharge,0.30 + 0.10 * count)
call BlzSetSpecialEffectYaw(sfxCharge,a)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set lifeCost = GetDamage(b.level)
set count = 0
set update = 0.0
set charge = false
set target = null
set hiden = false
set dummy = CreateUnit(GetOwningPlayer(b.owner),DUMMY_ID,GetUnitX(b.target),GetUnitY(b.target),GetUnitFacing(b.target))
call RemoveGuardPosition(dummy)
call IssueImmediateOrderById(dummy,ORDER_stop)
call SetDummyData(dummy,"IDBuff",b)
call BlzSetUnitBaseDamage(dummy,25 * b.level,0)
call UnitAddAbility(dummy,'Aloc')
call UnitAddAbility(b.target,CHARGE_ID)
call UnitMakeAbilityPermanent(b.target,true,CHARGE_ID)
if GetHeroMasteryType(b.owner) == 3 then
set wmast = true
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Inner Demon"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = DURATION
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set d = d + (GetHeroInt(u,true) * 10)/100
endif
call UnitAddBuff(u,u,d,InnerDemon.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function OnCharge takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer o = GetIssuedOrderId()
local InnerDemon b = GetUnitBuff(u,InnerDemon.buff).buffAllocIndex
if b != 0 and GetUnitAbilityLevel(u,CHARGE_ID) != 0 then
if o == ORDER_manashieldon then
call b.startCharge()
elseif o == ORDER_manashieldoff and not Status.UnitHasStatus(STATUS_STUN,u) then
call b.stopCharge()
endif
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local trigger t
if GetLearnedSkillLevel() == 1 then
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t,function OnCharge)
set t = null
endif
set u = null
endfunction
private function OnAttack takes nothing returns nothing
local unit u = GetAttacker()
local Buff b
if GetUnitTypeId(u) == DUMMY_ID then
set b = GetDummyData(u,"IDBuff")
if b != 0 then
if InnerDemon[b.buffAllocIndex].target == null then
call InnerDemon[b.buffAllocIndex].setTarget(GetTriggerUnit())
endif
endif
endif
set u = null
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if GetUnitTypeId(data.source) == DUMMY_ID then
set b = GetDummyData(data.source,"IDBuff")
call CodeDamage.Damage(b.owner,data.target,data.damageMod,udg_DamageTypeMagic,"DemonDamage",0,0)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call InnerDemon.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call DamageEvent.RegisterDummyDamage(Filter(function OnDamage))
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED,function OnAttack)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Warlock_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library PlagueBringer initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HPB1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'PBI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Underground Devourer"
set up.Text = "Increases |c00b4b4b4Underground Lash|r slow duration."
set up.SupText = "If the |c00b4b4b4Underground Lash|r hits a target reduces its cooldown by 50%."
set up.LevelData1 = "+1s Slow"
set up.LevelData2 = "+1.5s Slow"
set up.LevelData3 = "+2s Slow"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'PBI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Noxious Inside"
set up.Text = "Increases |c00b4b4b4Shake Entrails|r |c0000ced1Stun|r duration."
set up.SupText = "|c00b4b4b4Shake Entrails|r will add |c00ffff00Spell Immunity|r to the target if is an allied."
set up.LevelData1 = "+0.5 seconds"
set up.LevelData2 = "+1.0 seconds"
set up.LevelData3 = "+1.5 seconds"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'PBI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Dire Monstrosity"
set up.Text = "Increases |c00b4b4b4Rotten Monstrosity|r base Damage."
set up.SupText = "Increases |c0099b4d1Rotten Monstrosity|r strength bonus damage by 10%."
set up.LevelData1 = "+10 Damage"
set up.LevelData2 = "+20 Damage"
set up.LevelData3 = "+30 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'PBI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Decay"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HPB1'
set d.Name = "Plague Bringer"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNPlagueBringer.blp"
set d.WinAni = "stand victory"
set d.Block = 50
set d.Evasion = 0
set d.Resistance = 0
set d.LifeRegen = 0.5
set d.ManaRegen = 0.5
set d.Armor = 2
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'PBA1'
set d.HeroAbility2 = 'PBA2'
set d.HeroAbility3 = 'PBA3'
set d.HeroAbility4 = 'PBA4'
set d.ChooseIconID = 'c024'
set d.ChooseDummy = 'dh24'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 1
set d.healingLevel = 6
set d.survivavilityLevel = 7
set d.movementLevel = 1
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_UNDEAD
set d.InfoID = 'HPBI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope UndergroundLash initializer init
globals
private constant integer SPELL_ID = 'PBA1'
private constant integer UPGRADE_ID = 'PBI1'
private constant real DAMAGE_BASE = 80.00
private constant real DAMAGE_LEVEL = 40.00
private constant real SLOW_BASE = 0.15
private constant real SLOW_LEVEL = 0.05
private constant real AREA_OF_EFFECT = 100.00
private constant real UP_DIST = 50.00
private constant string HIT_SFX = "Units\\Creeps\\ForgottenOne\\ForgottenOneTent.mdl"
private constant string TARGET_SFX = "Objects\\Spawnmodels\\Naga\\NagaBlood\\NagaBloodWindserpent.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct UndergroundLash extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-(SLOW_BASE + SLOW_LEVEL * b.level),0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A079'
set BUFF_DATA.BuffID = 'B02K'
set BUFF_DATA.Name = "Underground Lash"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local effect sfx = tb.effect[0]
call DestroyEffect(sfx)
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set sfx = null
set t = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real ux = GetUnitX(u)
local real uy = GetUnitY(u)
local player p = GetOwningPlayer(u)
local group g = NewGroup()
local real d = Distance(x,y,ux,uy)
local real a = Angle(x,y,ux,uy)
local real dur = 2.7
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local unit temp
local Table tb = Table.create()
local Ability ab
local effect sfx = AddSpecialEffect(HIT_SFX,x,y)
call BlzSetSpecialEffectColor(sfx,175,255,0)
call BlzSetSpecialEffectScale(sfx,0.9)
call BlzSetSpecialEffectYaw(sfx,a)
call GroupEnumUnitsInRange(g,x,y,AREA_OF_EFFECT,null)
if ulvl != 0 then
set dur = dur + (0.50 + 0.50 * ulvl)
endif
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call KPJUnit.create(temp,d,a,0.70,550,KPJDefaultConfig2,KPJ_TYPE_JUMP)
call CodeDamage.Damage(u,temp,GetDamage(lvl),udg_DamageTypeMagic,"",0,0)
call UnitAddBuff(temp,u,dur,UndergroundLash.buff,lvl,0)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,temp,"overhead"))
if IsUpgradeSuperior(u,UPGRADE_ID) then
set ab = Ability.GetUnitAbilityByID(SPELL_ID,u)
call ab.addTempPercentCooldown(-0.50)
endif
exitwhen true
endif
endloop
if GetHeroMasteryType(u) == 3 then
set ab = Ability.GetUnitAbilityByID(SPELL_ID,u)
call UnitRemoveHp(u,ab.originalManaCost)
endif
set tb.effect[0] = sfx
call TimerStart(NewTimerEx(tb),0.80,false,function callback)
call ReleaseGroup(g)
set temp = null
set p = null
set sfx = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call UndergroundLash.Initialize()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,PlagueBringer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(HIT_SFX)
endfunction
endscope
scope ShakeEntrails initializer init
globals
private constant integer SPELL_ID = 'PBA2'
private constant integer UPGRADE_ID = 'PBI2'
private constant real DAMAGE_BASE = 75.00
private constant real DAMAGE_LEVEL = 50.00
private constant real AREA_OF_EFFECT = 250.00
private constant real STUN_DURATION = 1.50
private constant real DURATION = 2.50
private constant real UP_STUN = 0.50
private constant string TARGET_SFX = "Objects\\Spawnmodels\\Undead\\UndeadLargeDeathExplode\\UndeadLargeDeathExplode.mdl"
private constant string AOE_SFX = "war3mapImported\\NerubianDeath.mdx"
private RSound ABILITY_SOUND
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct ShakeEntrails extends array
real time
AoE aoe
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call aoe.destroy()
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local effect sfx
local real a
set time = time + 0.03125
if time >= 0.50 and b.elapsedTime <= 2.00 then
set time = 0
set sfx = AddSpecialEffect(TARGET_SFX,GetUnitX(b.target),GetUnitY(b.target))
set a = GetRandomReal(1,360) * bj_DEGTORAD
call BlzSetSpecialEffectScale(sfx,0.80)
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectColor(sfx,175,255,0)
call DestroyEffect(sfx)
set sfx = null
endif
endmethod
private static method onFinish takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local player p = GetOwningPlayer(b.owner)
local real dmg = GetDamage(b.level)
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local group g = NewGroup()
local real s = STUN_DURATION + (UP_STUN * GetUpgradeSkillLevel(b.owner,UPGRADE_ID))
local effect sfx
local unit temp
call GroupEnumUnitsInRange(g,x,y,AREA_OF_EFFECT,null)
set sfx = AddSpecialEffect(AOE_SFX,x,y)
call BlzSetSpecialEffectScale(sfx,1.25)
call BlzSetSpecialEffectColor(sfx,175,255,0)
call DestroyEffect(sfx)
set sfx = null
call ABILITY_SOUND.play(x,y,0,100)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(b.owner,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_STUN,temp,s,Status_EFFECT[STATUS_STUN])
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local boolean ally = IsUnitAlly(b.target,GetOwningPlayer(b.owner))
set time = 0
set aoe = AoE.create(0,0,b.target,AREA_OF_EFFECT)
call BlzSetSpecialEffectColor(aoe.sfx,175,255,0)
if IsUpgradeSuperior(b.owner,UPGRADE_ID) and ally then
call Status.Add(STATUS_SPELL_IMMUNITY,b.target,DURATION,Status_EFFECT[STATUS_SPELL_IMMUNITY])
endif
if ally then
call BlzSetAbilityTooltip(b.AuraID,"|cFF00FF00"+b.Name+"|r",0)
set b.buffType = BUFF_TYPE_POSITIVE
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A063'
set BUFF_DATA.BuffID = 'B05D'
set BUFF_DATA.Name = "Shake Entrails"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
set BUFF_DATA.PierceImmune = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local player p = GetOwningPlayer(u)
local Ability ab
if IsUnitAlly(t,p) then
call UnitAddBuff(t,u,DURATION,ShakeEntrails.buff,lvl,0)
else
if not TriggerSpellNegation(t) then
call UnitAddBuff(t,u,DURATION,ShakeEntrails.buff,lvl,0)
endif
if TriggerSpellReflection(t) then
call UnitAddBuff(u,t,DURATION,ShakeEntrails.buff,lvl,0)
endif
endif
if GetHeroMasteryType(u) == 3 then
set ab = Ability.GetUnitAbilityByID(SPELL_ID,u)
call UnitRemoveHp(u,ab.originalManaCost)
endif
set u = null
set p = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
local AbilityTag t
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ShakeEntrails.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
set ABILITY_SOUND = RSound.create("Sound\\Units\\Death\\ArtilleryCorpseExplodeDeath1.wav", true, false, 12700, 12700)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,PlagueBringer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
scope RottenMonstrosity initializer init
globals
private constant integer SPELL_ID = 'PBA3'
private constant integer UPGRADE_ID = 'PBI3'
private constant integer DUMMY_ID = 'h00N'
private constant integer DAMAGE_BASE = 35
private constant integer STR_BASE = 25
private constant real DMG_HEAL_BASE = 0.30
private constant real DMG_HEAL_LVL = 0.10
private constant integer UP_DMG = 10
private constant integer SUP_DMG = 10
private constant integer MA_SPEED = 50
private constant string TARGET_SFX = "Objects\\Spawnmodels\\Undead\\UndeadLargeDeathExplode\\UndeadLargeDeathExplode.mdl"
endglobals
private function GetHeal takes integer lvl returns real
return DMG_HEAL_BASE + DMG_HEAL_LVL * lvl
endfunction
struct RottenMonstrosity extends array
unit dummy
real heal
real healDmg
integer strFactor
integer dmg
boolean hiden
boolean dmast
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call KillUnit(dummy)
set dummy = null
set dmast = false
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real h = GetUnitFlyHeight(b.target)
local real a = GetUnitFacing(b.target)
local real aa = (a + 180) * bj_DEGTORAD
local real x = GetUnitX(b.target) + 20 * Cos(aa)
local real y = GetUnitY(b.target) + 20 * Sin(aa)
local integer str = GetHeroStr(b.target,true)*strFactor/100
local real hp = GetUnitLifePercent(b.target)
local real hb
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
call SetUnitFlyHeight(dummy,h,0)
call BlzSetUnitBaseDamage(dummy,(dmg + str) - 1,0)
if IsUnitHidden(b.target) or IsUnitDisabled(b.target) then
if not hiden then
call BlzUnitDisableAbility(dummy,'Aatk',true,false)
set hiden = true
endif
else
if hiden then
set hiden = false
call BlzUnitDisableAbility(dummy,'Aatk',false,false)
endif
endif
set hb = (100 - hp) / 100
set healDmg = heal + hb
if dmast then
set x = GetUnitState(b.target,UNIT_STATE_LIFE)
set y = GetUnitState(b.target,UNIT_STATE_MAX_LIFE)
set a = x / y * 100
set a = 0.20 - 0.002 * a
call BlzSetUnitAttackCooldown(dummy,0.80 - a,0)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real a = (GetUnitFacing(b.target) + 180) * bj_DEGTORAD
local real x = GetUnitX(b.target) + 20 * Cos(a)
local real y = GetUnitY(b.target) + 20 * Sin(a)
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set heal = GetHeal(b.level)
set healDmg = heal
set dmg = DAMAGE_BASE + UP_DMG * ulvl
set strFactor = STR_BASE
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set strFactor = strFactor + SUP_DMG
endif
set dummy = CreateUnit(GetOwningPlayer(b.target),DUMMY_ID,x,y,GetUnitFacing(b.target))
call MakeFly(dummy)
call BlzUnitDisableAbility(dummy,'Amov',true,true)
call SetDummyData(dummy,"RMBuff",this)
set hiden = false
if GetHeroMasteryType(b.target) == 2 then
call BlzSetUnitWeaponRealField(dummy,UNIT_WEAPON_RF_ATTACK_RANGE,0,230)
set dmast = true
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Rotten Monstrosity"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local RottenMonstrosity b
if GetUnitTypeId(data.source) == DUMMY_ID then
set b = GetDummyData(data.source,"RMBuff")
if b != 0 then
call CodeDamage.Damage(b.thisBuff.owner,data.target,data.damageMod,udg_DamageTypeMagic,"RM",0,0)
//call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,data.target,"overhead"))
endif
endif
endfunction
private function OnEnterCombat takes nothing returns nothing
local unit u = GetEventCombatEnterUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if lvl != 0 then
call UnitAddBuff(u,u,999999,RottenMonstrosity.buff,lvl,0)
endif
set u = null
endfunction
private function OnLeaveCombat takes nothing returns nothing
local unit u = GetEventCombatLeaveUnit()
local Buff b = GetUnitBuff(u,RottenMonstrosity.buff)
if b != 0 then
call UnitRemoveBuff(u,RottenMonstrosity.buff)
endif
set u = null
endfunction
private function onDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local RottenMonstrosity b
if data.codeDmg.codeName == "RM" then
set b = GetUnitBuff(data.source,RottenMonstrosity.buff).buffAllocIndex
if b != 0 then
call CodeDamage.Damage(data.source,data.source,data.damageMod * b.healDmg,udg_DamageTypeHeal,"",0,0)
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
local AbilityTag t
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RottenMonstrosity.Initialize()
call RegisterCombatEvent(function OnEnterCombat,EVENT_UNIT_ENTER_COMBAT)
call RegisterCombatEvent(function OnLeaveCombat,EVENT_UNIT_LEAVE_COMBAT)
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
call DamageEvent.RegisterDamage(Filter(function onDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,PlagueBringer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
scope RottenCloud initializer init
globals
private constant integer SPELL_ID = 'PBA4'
private constant integer UPGRADE_ID = 'PBI4'
private constant real DMG_BASE = 50.00
private constant real DMG_LVL = 25.00
private constant real HP_BASE = 0.06
private constant real HP_LEVEL = 0.06
private constant real BUFF_DURATION = 4.00
private constant real AREA_OF_EFFECT = 210.00
private constant real UP_HP = 0.05
private constant string TARGET_SFX = "war3mapImported\\ElitePlagueCloud.mdx"
endglobals
private function GetHpDmg takes integer lvl returns real
return HP_BASE + HP_LEVEL * lvl
endfunction
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL
endfunction
struct RottenCloud extends array
real hpCost
real dmg
group g
player p
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(sfx)
call ReleaseGroup(g)
set g = null
set p = null
set sfx = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local unit temp
call UnitRemoveHp(b.target,dmg)
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),AREA_OF_EFFECT,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(b.target,temp,dmg,udg_DamageTypePure,"",0,0)
endif
endloop
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real hpp = GetHpDmg(b.level)
if GetUpgradeSkillLevel(b.target,UPGRADE_ID) != 0 then
set hpp = hpp + UP_HP
endif
set hpCost = BlzGetUnitMaxHP(b.target) * hpp
set dmg = (GetDamage(b.level) + hpCost) / 8
set g = NewGroup()
set p = GetOwningPlayer(b.target)
set sfx = AddSpecialEffectTarget(TARGET_SFX,b.target,"origin")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00B'
set BUFF_DATA.BuffID = 'B055'
set BUFF_DATA.Name = "Rotten Cloud"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.50
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,BUFF_DURATION,RottenCloud.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function CMCallback takes nothing returns nothing
local Table tb = GetTimerData(GetExpiredTimer())
local unit u = tb.unit[0]
local integer strx = tb.integer[1]
local integer str
if UnitAlive(u) then
set str = GetHeroStr(u,true) - strx
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,-strx,0,false)
set str = str * 10 / 100
call BonusStruct.Add(BONUS_TYPE_STRENGTH,u,str,0,false)
set tb.integer[1] = str
endif
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local integer i
local Table tb
if up.upID == UPGRADE_ID then
set i = GetHeroMasteryType(up.ownerHero.hero)
if i == 1 then
set tb = tb.create()
set tb.unit[0] = up.ownerHero.hero
set tb.integer[1] = GetHeroStr(up.ownerHero.hero,true) * 10 / 100
call BonusStruct.Add(BONUS_TYPE_STRENGTH,up.ownerHero.hero,tb.integer[1],0,false)
call TimerStart(NewTimerEx(tb),0.50,true,function CMCallback)
elseif i == 3 then
set a = Ability.GetUnitAbilityByID('PBA1',up.ownerHero.hero)
call a.disableManaCost(true)
set a = Ability.GetUnitAbilityByID('PBA2',up.ownerHero.hero)
call a.disableManaCost(true)
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
local AbilityTag t
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RottenCloud.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,PlagueBringer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
library FleshBehemoth initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HFB1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'FBI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Deadly Chains"
set up.Text = "Increases |c00b4b4b4Nightmare Chains|r secondary target area of effect."
set up.SupText = "Reduces |c00b4b4b4Nightmare Chains|r |c00ffff95Cooldown|r by 3s."
set up.LevelData1 = "+50 AoE"
set up.LevelData2 = "+100 AoE"
set up.LevelData3 = "+150 AoE"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'FBI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Spit Bile"
set up.Text = "Increases |c00b4b4b4Putrid Breath|r duration."
set up.SupText = "Increases |c00b4b4b4Putrid Breath|r periodic damage by 30."
set up.LevelData1 = "+1.0 seconds"
set up.LevelData2 = "+1.5 seconds"
set up.LevelData3 = "+2.0 seconds"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'FBI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Fleash Heap"
set up.Text = "Increases |c00b4b4b4Sinister Harvest|r base healing."
set up.SupText = "|c0099b4d1Sinister Harvest|r gives 10(20 hero) bonus damage when triggers for 20 seconds. Stackable 8 times."
set up.LevelData1 = "+25 Heal"
set up.LevelData2 = "+50 Heal"
set up.LevelData3 = "+75 Heal"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'FBI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Living Flesh"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HFB1'
set d.Name = "Flesh Behemoth"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNAbomination.blp"
set d.WinAni = "stand 3"
set d.Block = 30
set d.Evasion = 0
set d.Resistance = 60
set d.LifeRegen = 2.0
set d.ManaRegen = 0.5
set d.Armor = 0
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'FBA1'
set d.HeroAbility2 = 'FBA2'
set d.HeroAbility3 = 'FBA3'
set d.HeroAbility4 = 'FBA4'
set d.ChooseIconID = 'c026'
set d.ChooseDummy = 'dh26'
set d.spellDamageLevel = 8
set d.attackDamageLevel = 3
set d.healingLevel = 6
set d.survivavilityLevel = 7
set d.movementLevel = 2
set d.crowdControlLevel = 5
set d.HeroFaction = Game.FACTION_UNDEAD
set d.InfoID = 'HFBI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope NightmareChains initializer init
globals
private constant integer SPELL_ID = 'FBA1'
private constant integer UPGRADE_ID = 'FBI1'
private constant real DMG_BASE = 100
private constant real DMG_LVL = 75
private constant real DISTANCE = 250
private constant real AREA = 250
private constant real DURATION = 3.0
private constant real STR_BASE = 0.10
private constant real UP_DMG_BASE = 20.00
private constant real UP_AREA = 50.00
private constant string CHAIN_SFX = "war3mapImported\\ChainElement.mdx"
private constant string LOOP_SFX = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
private RSound Sound
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function GetStr takes integer lvl returns real
return STR_BASE + STR_BASE * lvl
endfunction
struct NChain extends array
implement Alloc
effect sfx
public static method create takes real x, real y, real a returns thistype
local thistype this = thistype.allocate()
set sfx = AddSpecialEffect(CHAIN_SFX,x,y)
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectScale(sfx,2.0)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 50.00)
call BlzSetSpecialEffectColor(sfx,255,0,0)
return this
endmethod
public method destroy takes nothing returns nothing
call BlzSetSpecialEffectAlpha(sfx,0)
call DestroyEffect(sfx)
set sfx = null
call this.deallocate()
endmethod
endstruct
struct NightmareChain extends array
LinkedList list
real dmg
real time
boolean cm
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Link h = list.head
local integer i
local NChain c
loop
exitwhen h == 0
set c = h.data
call c.destroy()
set h = h.next
endloop
call list.destroy()
call Status.Remove(STATUS_STUN,b.target)
set i = GetUnitData(b.owner,"NCCount")
set i = i - 1
call SetUnitData(b.owner,"NCCount",i)
if i == 0 then
call Sound.stop(false)
call IssueImmediateOrderById(b.owner,ORDER_stop)
endif
endmethod
public method createChains takes nothing returns nothing
local Buff b = thisBuff
local real xu = GetUnitX(b.owner)
local real yu = GetUnitY(b.owner)
local real xt = GetUnitX(b.target)
local real yt = GetUnitY(b.target)
local real d = Distance(xu,yu,xt,yt)
local real a = Angle(xu,yu,xt,yt)
local real cos = Cos(a)
local real sin = Sin(a)
local real x
local real y
local real r = 0.00
local NChain chain
local integer c = R2I(d / 50)
//Move current chains to the right pos
local Link h = list.head
loop
exitwhen h == 0
set chain = h.data
set r = r + 50.00
set x = xu + r * cos
set y = yu + r * sin
call BlzSetSpecialEffectX(chain.sfx,x)
call BlzSetSpecialEffectY(chain.sfx,y)
call BlzSetSpecialEffectYaw(chain.sfx,a)
call BlzSetSpecialEffectHeight(chain.sfx,GetLocZ(x,y) + 50.00)
set h = h.next
endloop
if c != list.size then
if c > list.size then
//añadir chains
set c = c - list.size
loop
exitwhen c == 0
set r = r + 50.00
set x = xu + r * cos
set y = yu + r * sin
call list.add(NChain.create(x,y,a))
set c = c - 1
endloop
elseif c < list.size then
//eliminar chains
set c = list.size - c
loop
exitwhen c == 0
set h = list.head
set chain = h.data
call chain.destroy()
call list.remove(h)
set c = c - 1
endloop
endif
endif
if d > 100 then
set x = xt + 3 * Cos(a + bj_PI)
set y = yt + 3 * Sin(a + bj_PI)
call SetUnitX(b.target,x)
call SetUnitY(b.target,y)
endif
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set time = time + 0.03125
if time == 0.50 then
call DestroyEffect(AddSpecialEffectTarget(LOOP_SFX,b.target,"chest"))
set time = 0
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypePhysicalOverTime,"",0,0)
endif
if GetUnitCurrentOrder(b.owner) != ORDER_magicleash and not cm then
set b.removeInside = true
else
call createChains()
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = GetDamage(b.level) + GetHeroStr(b.owner,true) * GetStr(b.level)
set dmg = dmg / 6
set time = 0.00
set list = LinkedList.create()
call createChains()
call SetUnitData(b.owner,"NCCount",GetUnitData(b.owner,"NCCount") + 1)
call Status.Add(STATUS_STUN,b.target,0,Status_EFFECT[STATUS_STUN])
set cm = GetHeroMasteryType(b.owner) == 1
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Nightmare Chains"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
local real x = GetUnitX(t)
local real y = GetUnitY(t)
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local player p
local unit temp
local unit rand = null
local group g
local real a
call Sound.play(GetUnitX(u),GetUnitY(u),0,100)
if GetRandomInt(1,100) <= 50 or GetHeroMasteryType(u) == 1 then
set g = NewGroup()
set p = GetOwningPlayer(u)
set a = AREA + UP_AREA * ulvl
call GroupEnumUnitsInRange(g,x,y,a,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and temp != t then
set rand = temp
exitwhen true
endif
endloop
call ReleaseGroup(g)
if rand != null then
if not TriggerStatusNegation(STATUS_STUN,rand) then
call UnitAddBuff(rand,u,DURATION,NightmareChain.buff,lvl,0)
endif
endif
set g = null
set p = null
set temp = null
endif
if not TriggerStatusNegation(STATUS_STUN, t) then
call UnitAddBuff(t,u,DURATION,NightmareChain.buff,lvl,0)
endif
set rand = null
endfunction
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
else
call IssueImmediateOrderById(u,ORDER_stop)
endif
set u = null
set t = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local ability ab
if up.upID == UPGRADE_ID then
if up.isSuperior then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(-3)
endif
endif
if up.upID == 'FBI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 3 then
set ab = BlzGetUnitAbility(up.ownerHero.hero,'FBA4')
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_MANA_COST,0,0)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_MANA_COST,1,0)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_MANA_COST,2,0)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_MANA_COST,3,0)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_COOLDOWN,0,60.00)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_COOLDOWN,1,60.00)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_COOLDOWN,2,60.00)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_COOLDOWN,3,60.00)
set ab = null
endif
if GetHeroMasteryType(up.ownerHero.hero) == 2 then
call PutridBreath_DexMasterySetup.evaluate(up.ownerHero.hero)
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
set Sound = RSound.create("war3mapImported\\ChainLoop.mp3", true, true, 12700, 12700)
call NightmareChain.Initialize()
call RegisterSpellEffectEvent(SPELL_ID,function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FleshBehemoth_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope PutridBreath initializer init
globals
private constant integer SPELL_ID = 'FBA2'
private constant integer UPGRADE_ID = 'FBI2'
private constant integer EXTRA1_ID = 'A04H'
private constant integer EXTRA2_ID = 'Atdg'
private constant real DMG_BASE = 40
private constant real DMG_LVL = 10
private constant real DURATION = 6.0
private constant real UP_DMG_BASE = 20.00
private constant real UP_DURATION = 0.50
private constant real SUP_DMG = 30.00
private constant string MISSILE_SFX = "Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl"
private constant string AOE_SFX = "war3mapImported\\SporeCloud024_006.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function CallbackCorpse takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
call RemoveUnit(tb.unit[0])
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set t = null
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local Table tb2 = Table.create()
local unit u = tb.unit[0]
local effect sfx = tb.effect[1]
local AoE aoe = tb.integer[2]
local unit c
call aoe.destroy()
call flushDummyData(u)
call DestroyEffect(sfx)
set c = CreateCorpse(GetOwningPlayer(u),'h00V',GetUnitX(u),GetUnitY(u),GetRandomReal(1,360))
call SetUnitAnimation(c,"stand")
call SetUnitVertexColor(c,255,100,100,255)
call UnitSuspendDecay(c, true)
call SetUnitTimeScale(c, 0.0001)
set tb2.unit[0] = c
call TimerStart(NewTimerEx(tb2),15.00,false,function CallbackCorpse)
call RemoveUnit(u)
call ReleaseTimer(t)
call tb.flush()
call tb.destroy()
set AIFB.WActive = AIFB.WActive - 1
set sfx = null
set u = null
set t = null
set c = null
endfunction
struct PutridBreathMissile extends array
private static method onFinish takes Missile missile returns boolean
local Table tb = Table.create()
local real dur = DURATION
local integer ulvl = GetUpgradeSkillLevel(missile.source,UPGRADE_ID)
local timer t = NewTimerEx(tb)
local unit d = CreateUnit(missile.owner,'u001',missile.x,missile.y,0)
local AoE aoe = AoE.create(missile.x,missile.y,null,190)
local effect sfx
call BlzSetSpecialEffectColor(aoe.sfx,0,255,0)
set tb.integer[2] = aoe
call UnitAddAbility(d,EXTRA1_ID)
call UnitAddAbility(d,EXTRA2_ID)
call SetUnitAbilityLevel(d,EXTRA1_ID,missile.level)
call SetDummyData(d,"owner",GetUnitUserData(missile.source))
set tb.unit[0] = d
set sfx = AddSpecialEffect(AOE_SFX,missile.x,missile.y)
call BlzSetSpecialEffectTimeScale(sfx,2.0)
call BlzSetSpecialEffectScale(sfx,0.9)
set tb.effect[1] = sfx
if ulvl != 0 then
set dur = dur + (UP_DURATION + UP_DURATION * ulvl)
endif
if GetHeroMasteryType(missile.source) == 2 then
call UnitAddAbility(d,'A0C5')
endif
call TimerStart(t,dur,false,function Callback)
set t = null
set d = null
set sfx = null
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, real xt, real yt returns Missile
local real x = GetUnitX(source)
local real y = GetUnitY(source)
local real angle = Angle(x,y,xt,yt)
local real dist = Distance(x,y,xt,yt)
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local Missile missile = Missile.create(x, y,60.0, angle, dist,0.0)
set missile.source = source
set missile.level = lvl
set missile.owner = GetOwningPlayer(source)
set missile.speed = 35.00
set missile.arc = 40.*bj_DEGTORAD + RMinBJ(20., dist*.1)*bj_DEGTORAD
set missile.model = MISSILE_SFX
set missile.scale = 1.0
set AIFB.WActive = AIFB.WActive + 1
call PutridBreathMissile.launch(missile)
return missile
endfunction
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
call UnitRemoveHp(u,GetUnitState(u,UNIT_STATE_MAX_LIFE) * 0.12)
set AIFB.lastWX = x
set AIFB.lastWY = y
call SetupMissile(u,x,y)
set u = null
endfunction
private function DexMasteryCallback takes nothing returns nothing
local Table tb = GetTimerData(GetExpiredTimer())
local unit u = tb.unit[0]
local real x = GetUnitX(u)
local real y = GetUnitY(u)
call SetupMissile(u,x,y)
endfunction
public function DexMasterySetup takes unit u returns nothing
local Table tb = Table.create()
set tb.unit[0] = u
call TimerStart(NewTimerEx(tb),4.2,true,function DexMasteryCallback)
endfunction
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local unit h
local real dmg
local integer lvl = GetUnitAbilityLevel(data.source,EXTRA1_ID)
if lvl != 0 then
set h = GetUnitByIndex(GetDummyData(data.source,"owner"))
set dmg = GetDamage(lvl)
if IsUpgradeSuperior(h,UPGRADE_ID) then
set dmg = dmg + SUP_DMG
endif
call CodeDamage.Damage(h,data.target,dmg,udg_DamageTypeMagicOverTime,"",0,0)
set h = null
endif
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local Ability a
if GetUnitAbilityLevel(u,SPELL_ID) == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call a.addMaxCharges(3)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.isCharged = true
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID,function onCast)
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
call RegisterSpellLearn(SPELL_ID,function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FleshBehemoth_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope SinisterHarvest initializer init
globals
private constant integer SPELL_ID = 'FBA3'
private constant integer UPGRADE_ID = 'FBI3'
private constant real HEAL_BASE = 25.00
private constant real HP_BASE = 0.05
private constant real HP_CREEP = 0.02
private constant integer SUP_DMG = 10
private constant integer STR_BONUS = 2
private constant real UP_HEAL = 25.00
private constant string MISSILE_SFX = "Abilities\\Weapons\\MeatwagonMissile\\MeatwagonMissile.mdl"
private constant string HARVEST_SFX = "Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl"
endglobals
private function GetHp takes integer lvl returns real
return HP_BASE + HP_BASE * lvl
endfunction
struct SinisterHarvestDmg extends array
integer bonus
private static method onStackRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-bonus,0,true)
endmethod
private static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int == 1 then
set bonus = SUP_DMG * 2
else
set bonus = SUP_DMG
endif
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,bonus,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AV'
set BUFF_DATA.BuffID = 'B03Z'
set BUFF_DATA.Name = "Sinister Harvest Dmg"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 8
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct HarvestMissile extends array
private static method onFinish takes Missile missile returns boolean
call DestroyEffect(AddSpecialEffectTarget(MISSILE_SFX,missile.target,"chest"))
call CodeDamage.Damage(missile.target,missile.target,I2R(missile.data),udg_DamageTypeHeal,"",0,0)
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
if missile.scale == 1.2 then
call UnitAddBuff(missile.source,missile.source,20.0,SinisterHarvestDmg.buff,0,1)
call BonusStruct.Add(BONUS_TYPE_STRENGTH,missile.source,STR_BONUS,0,false)
else
call UnitAddBuff(missile.source,missile.source,20.0,SinisterHarvestDmg.buff,0,0)
endif
endif
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit s, unit t, real h, integer op returns Missile
local real x = GetUnitX(s)
local real y = GetUnitY(s)
local real xt = GetUnitX(t)
local real yt = GetUnitY(t)
local real angle = Angle(x,y,xt,yt)
local real dist = Distance(x,y,xt,yt)
local Missile missile = Missile.create(x,y,0.0,angle,0,120.0)
set missile.source = t
set missile.target = t
set missile.owner = GetOwningPlayer(t)
set missile.model = MISSILE_SFX
if op == 1 then
set missile.scale = 1.2
else
set missile.scale = 0.8
endif
set missile.speed = 25.0
set missile.data = R2I(h)
call HarvestMissile.launch(missile)
return missile
endfunction
private function onDeath takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit k = GetKillingUnit()
local Hero h = GetPlayerHero(GetOwningPlayer(k))
local integer lvl = GetUnitAbilityLevel(h.hero,SPELL_ID)
local real bheal
local real heal
local integer str
local real hp
if lvl != 0 then
if UnitAlive(h.hero) then
set bheal = HEAL_BASE + UP_HEAL * GetUpgradeSkillLevel(h.hero,UPGRADE_ID)
if IsUnitType(u,UNIT_TYPE_HERO) then
set heal = GetUnitState(h.hero,UNIT_STATE_MAX_LIFE) * GetHp(lvl) + bheal
call SetupMissile(u,h.hero,heal,1)
else
set heal = GetUnitState(h.hero,UNIT_STATE_MAX_LIFE) * HP_CREEP + bheal
call SetupMissile(u,h.hero,heal,0)
endif
endif
endif
set u = null
set k = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local group g = NewGroup()
local unit temp
local real bheal = HEAL_BASE + UP_HEAL * GetUpgradeSkillLevel(u,UPGRADE_ID)
local real heal = GetUnitState(u,UNIT_STATE_MAX_LIFE) * HP_CREEP + bheal
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),700.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if not UnitAlive(temp) and not IsUnitType(temp,UNIT_TYPE_HERO) then
call DestroyEffect(AddSpecialEffect(HARVEST_SFX,GetUnitX(temp),GetUnitY(temp)))
if GetUnitTypeId(temp) == 'h00V' then
call SetupMissile(temp,u,heal * 3,0)
else
call SetupMissile(temp,u,heal,0)
endif
call RemoveUnit(temp)
endif
endloop
call ReleaseGroup(g)
set g = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SinisterHarvestDmg.Initialize()
call RegisterSpellEffectEvent(SPELL_ID,function onCast)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function onDeath)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FleshBehemoth_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope CorrosiveScraps initializer init
globals
private constant integer SPELL_ID = 'FBA4'
private constant integer UPGRADE_ID = 'FBI4'
private constant real HP_BASE = 0.70
private constant real SC_BASE = 0.30
private constant real DELAY = 3.00
private constant real AOE = 500.00
private constant real STUN_DURATION = 1.25
private constant real STUN_DURATION_LVL = 0.75
private constant string MISSILE_SFX = "war3mapImported\\Instantdeath.mdx"
private constant string MID_SFX = "war3mapImported\\CorpseBomb.mdx"
private constant string REVIVE_SFX = "Abilities\\Spells\\Orc\\Reincarnation\\ReincarnationTarget.mdl"
private constant string EXPLOSION_SFX = "Units\\Undead\\Abomination\\AbominationExplosion.mdl"
endglobals
struct ScrapsMissile extends array
private static method onFinish takes Missile missile returns boolean
local CorrosiveScraps b
if missile.data == 1 then
set b = UnitAddBuff(missile.target,missile.source,DELAY,CorrosiveScraps.buff,missile.level,0).buffAllocIndex
set b.x = GetUnitX(missile.source)
set b.y = GetUnitY(missile.source)
set b.a = missile.damage
else
call SetUnitData(missile.source,"CSCount",GetUnitData(missile.source,"CSCount") + 1)
endif
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, unit s, unit t, integer data, real a, integer lvl returns Missile
local real x = GetUnitX(s)
local real y = GetUnitY(s)
local real xt = GetUnitX(t)
local real yt = GetUnitY(t)
local real angle = Angle(x,y,xt,yt)
local real dist = Distance(x,y,xt,yt)
local Missile missile = Missile.create(x,y,80.0,angle,0,80.0)
set missile.level = lvl
set missile.source = source
set missile.target = t
set missile.owner = GetOwningPlayer(source)
set missile.model = MISSILE_SFX
set missile.scale = 1.4
set missile.data = data
set missile.damage = a
set missile.speed = 35.00
call SetUnitTimeScale(missile.dummy,2.0)
call ScrapsMissile.launch(missile)
return missile
endfunction
struct CorrosiveScraps extends array
effect sfx
real x
real y
real a
real dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real sd
local Lightning light
if not b.removeInside then
call SetupMissile(b.owner,b.target,b.owner,2,0,b.level)
if GetUpgradeSkillLevel(b.owner,UPGRADE_ID) > 1 then
call Status.Add(STATUS_STUN,b.target,1.0,Status_EFFECT[STATUS_STUN])
call KPJUnit.create(b.target,Distance(GetUnitX(b.target),GetUnitY(b.target),x,y),Angle(GetUnitX(b.target),GetUnitY(b.target),x,y),0.75,0,KPJDefaultConfig,KPJ_TYPE_KNOCKBACK)
set light = Lightning.create("DRAL",b.owner,b.target,0.75,0.50,125,125)
call light.setLightColor(255,0,0,255)
endif
endif
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real d = Distance(GetUnitX(b.target),GetUnitY(b.target),x,y)
local real sd
local DeadChecker dc
local Lightning light
if d > a then
set b.removeInside = true
set sd = STUN_DURATION + STUN_DURATION_LVL * b.level
call Status.Add(STATUS_STUN,b.target,sd,Status_EFFECT[STATUS_STUN])
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypeMagic,"",0,0)
call KPJUnit.create(b.target,d,Angle(GetUnitX(b.target),GetUnitY(b.target),x,y),0.75,0,KPJDefaultConfig,KPJ_TYPE_KNOCKBACK)
set light = Lightning.create("DRAL",b.owner,b.target,0.75,0.50,125,125)
call light.setLightColor(255,0,0,255)
set dc = GetUnitBuff(b.owner,DeadChecker.buff).buffAllocIndex
set dc.lifeExtra = dc.lifeExtra - dmg
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Buff dc = GetUnitBuff(b.owner,DeadChecker.buff)
set sfx = AddSpecialEffectTarget(MISSILE_SFX,b.target,"overhead")
set dmg = GetUnitState(b.owner,UNIT_STATE_MAX_LIFE) * SC_BASE
set dmg = dmg / dc.int
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Corrosive Scraps"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct DeadChecker extends array
fogmodifier fog
effect sfx
real lifeExtra
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real h = GetUnitState(b.target,UNIT_STATE_MAX_LIFE) * HP_BASE
set h = h + lifeExtra
call SetUnitState(b.target,UNIT_STATE_LIFE,h)
call SetUnitState(b.target,UNIT_STATE_MANA,GetUnitState(b.target,UNIT_STATE_MAX_MANA) / 2)
call DestroyFogModifier(fog)
call SelectUnitForPlayer(b.target,GetOwningPlayer(b.target),true)
call DestroyEffect(sfx)
call DestroyEffect(AddSpecialEffect(REVIVE_SFX,GetUnitX(b.target),GetUnitY(b.target)))
call SetUnitVertexColor(b.target,255,255,255,255)
set sfx = null
set fog = null
endmethod
private static method onPeriodic takes Buff b returns nothing
if UnitAlive(b.target) then
set b.removeInside = true
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local effect exp
set fog = CreateFogModifierRadius(GetOwningPlayer(b.target),FOG_OF_WAR_VISIBLE,x,y,700,true,false)
call FogEnable(true)
call FogModifierStart(fog)
set sfx = AddSpecialEffect(MID_SFX,x,y)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 100.00)
call SetUnitVertexColor(b.target,255,255,255,0)
set exp = AddSpecialEffect(EXPLOSION_SFX,x,y)
call BlzSetSpecialEffectColorByPlayer(exp,GetOwningPlayer(b.target))
call DestroyEffect(exp)
set lifeExtra = GetUnitState(b.target,UNIT_STATE_MAX_LIFE) * SC_BASE
set exp = null
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = ""
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpreadScraps takes unit hero, real x, real y, integer lvl returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(hero)
local unit temp
local CorrosiveScraps b
local real a = AOE
local integer c = 0
local AoE aoe
set aoe = AoE.create(x,y,null,a)
call BlzSetSpecialEffectColor(aoe.sfx,230,25,0)
call aoe.setTime(DELAY)
call SetUnitData(hero,"CSCount",0)
call GroupEnumUnitsInRange(g,x,y,a,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ENEMY(temp,p) then
set c = c + 1
call SetupMissile(hero,hero,temp,1,a,lvl)
endif
endloop
call ReleaseGroup(g)
call PutridBreath_SetupMissile(hero,x,y)
call UnitAddBuff(hero,hero,999,DeadChecker.buff,lvl,c)
set g = null
set p = null
endfunction
private function onDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local AoE aoe
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if not data.isAbsorbed and data.damageMod > 0 then
set lvl = GetUnitAbilityLevel(data.target,SPELL_ID)
if lvl != 0 then
if GetWidgetLife(data.target) < 0.041 and not IsUnitIllusion(data.target) then
if BlzGetUnitAbilityCooldownRemaining(data.target,SPELL_ID) == 0 and (GetUnitState(data.target,UNIT_STATE_MANA) >= 150 or GetHeroMasteryType(data.target) == 3) then
call SpreadScraps(data.target,GetUnitX(data.target),GetUnitY(data.target),lvl)
endif
endif
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call CorrosiveScraps.Initialize()
call DeadChecker.Initialize()
call DamageEvent.RegisterDamage(Filter(function onDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FleshBehemoth_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library ShadowCrawler initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HSW1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'SWI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Dire Chasser"
set up.Text = "Gives a bonus |c00ffff95Damage|r for 4 seconds if |c00b4b4b4Morbid Leap|r is success."
set up.SupText = "Increases |c00b4b4b4Morbid Leap|r Cast Range by 300."
set up.LevelData1 = "+20 Damage"
set up.LevelData2 = "+30 Damage"
set up.LevelData3 = "+40 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'SWI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Infected Wounds"
set up.Text = "Increases |c00b4b4b4Sharpened Claws|r bleed duration."
set up.SupText = "Increases |c00b4b4b4Sharpened Claws|r duration by 3s."
set up.LevelData1 = "+1 seconds"
set up.LevelData2 = "+2 seconds"
set up.LevelData3 = "+3 seconds"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'SWI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Vile Scrapes"
set up.Text = "|c00b4b4b4Unholy Rage|r also gives a bonus |c00ffff95Lifesteal|r."
set up.SupText = "|c00b4b4b4Unholy Rage|r will adds 50 flat |c00ffff95Move Speed|r bonus."
set up.LevelData1 = "+10% Lifesteal"
set up.LevelData2 = "+15% Lifesteal"
set up.LevelData3 = "+20% Lifesteal"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'SWI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Shadow Hunter"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HSW1'
set d.Name = "Shadow Crawler"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNGhoul.blp"
set d.WinAni = "stand victory"
set d.Block = 0
set d.Evasion = 0
set d.Resistance = 0
set d.LifeRegen = 3.0
set d.ManaRegen = 0.5
set d.Armor = 3
set d.AttackRange = 125
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'SWA1'
set d.HeroAbility2 = 'SWA2'
set d.HeroAbility3 = 'SWA3'
set d.HeroAbility4 = 'SWA4'
set d.ChooseIconID = 'c031'
set d.ChooseDummy = 'dh31'
set d.spellDamageLevel = 3
set d.attackDamageLevel = 8
set d.healingLevel = 3
set d.survivavilityLevel = 6
set d.movementLevel = 6
set d.crowdControlLevel = 2
set d.HeroFaction = Game.FACTION_UNDEAD
set d.InfoID = 'HSWI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope MorbidLeap initializer init
globals
private constant integer SPELL_ID = 'SWA1'
private constant integer UPGRADE_ID = 'SWI1'
private constant real HP_BASE = 70
private constant real HP_LVL = 30
private constant real DURATION = 1.6
private constant integer UP_DMG = 10
private constant real DMG_DURATION = 4.0
private constant string TARGET_SFX = "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl"
endglobals
private function GetHp takes integer lvl returns real
return HP_BASE + HP_LVL * lvl
endfunction
struct MorbidLeapDmg extends array
integer dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = UP_DMG + UP_DMG * b.level
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0C9'
set BUFF_DATA.BuffID = 'B04P'
set BUFF_DATA.Name = "Morbid Leap Damage"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer tr = GetExpiredTimer()
local Table tb = GetTimerData(tr)
local unit u = tb.unit[0]
local unit t = tb.unit[1]
local integer lvl
local integer ulvl
local real hp
local boolean b
local group g
local unit temp
local player p
if t != null then
set b = DistanceBetweenUnits(u,t) <= 150
else
set b = Distance(GetUnitX(u),GetUnitY(u),tb.real[2],tb.real[3]) <= 150
endif
if b then
set lvl = GetUnitAbilityLevel(u,SPELL_ID)
set ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
set hp = GetHp(lvl)
if t == null then
set g = NewGroup()
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,tb.real[2],tb.real[3],200.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call Status.Add(STATUS_FEAR,temp,DURATION,Status_EFFECT[STATUS_FEAR])
call UnitRemoveHp(temp,hp)
call UnitAddHp(u,hp)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,temp,"origin"))
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
else
call Status.Add(STATUS_FEAR,t,DURATION,Status_EFFECT[STATUS_FEAR])
call UnitRemoveHp(t,hp)
call UnitAddHp(u,hp)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,t,"origin"))
endif
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,u,"origin"))
if ulvl != 0 then
call UnitAddBuff(u,u,DMG_DURATION,MorbidLeapDmg.buff,ulvl,0)
endif
endif
call SetUnitTimeScale(u,1)
call tb.flush()
call tb.destroy()
call ReleaseTimer(tr)
set u = null
set t = null
set tr = null
endfunction
private function SpellTrigger takes unit source, unit target, integer lvl, real xt, real yt returns nothing
local real x = GetUnitX(target)
local real y = GetUnitY(target)
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local real a
local real d
local real time
set tb.unit[0] = source
set tb.unit[1] = target
set tb.real[2] = xt
set tb.real[3] = yt
if target == null then
set x = xt
set y = yt
endif
set a = Angle(xs,ys,x,y)
set d = Distance(xs,ys,x,y)
set time = 0.05*(d/50)
call SetUnitTimeScale(source,0.8/time)
call SetUnitAnimationByIndex(source,5)
call TimerStart(t,time-0.01,false,function Callback)
call KPJUnit.create(source,d,a,time,50 + (10 * d/50),KPJDefaultConfig,KPJ_TYPE_JUMP)
if GetHeroMasteryType(source) == 3 then
call Status.Add(STATUS_SPELL_IMMUNITY,source,time + 1.0,Status_EFFECT[STATUS_SPELL_IMMUNITY])
endif
set t = null
endfunction
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if t == null then
call SpellTrigger(u,t,lvl,GetSpellTargetX(),GetSpellTargetY())
else
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl,0,0)
endif
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call MorbidLeapDmg.Initialize()
call RegisterSpellEffectEvent(SPELL_ID,function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ShadowCrawler_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope SharpenedClaws initializer init
globals
private constant integer SPELL_ID = 'SWA2'
private constant integer UPGRADE_ID = 'SWI2'
private constant real DMG_BASE = 25
private constant real DMG_LEVEL = 5
private constant integer AS_BASE = 20
private constant integer AS_LEVEL = 5
private constant real MS_BASE = 0.10
private constant real MS_LEVEL = 0.05
private constant real CRIT_BASE = 5
private constant real BLEED_DURATION = 2.00
private constant real BUFF_DURATION = 15.00
private constant real UP_DUR = 1.00
private constant real SUP_DUR = 3.00
private constant string LOOP_SFX = "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodPeasant.mdl"
endglobals
private function GetDmg takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private function GetAs takes integer lvl returns integer
return AS_BASE + AS_LEVEL * lvl
endfunction
private function GetMs takes integer lvl returns real
return MS_BASE + MS_LEVEL * lvl
endfunction
private function GetCrit takes integer lvl returns real
return CRIT_BASE + CRIT_BASE * lvl
endfunction
struct Bleeding extends array
integer as
Movespeed ms
real time
real dps
real crit
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local effect sfx = AddSpecialEffectTarget(LOOP_SFX,b.target,"chest")
set time = time + 0.50
if time >= 1.0 then
set time = 0.0
call CodeDamage.Damage(b.owner,b.target,dps,udg_DamageTypePhysicalOverTime,"",0,0)
endif
call BlzSetSpecialEffectYaw(sfx,GetRandomReal(1,360) * bj_DEGTORAD)
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = GetAs(b.level)
set ms = Movespeed.create(b.target,-GetMs(b.level),0)
set crit = GetCrit(b.level)
set dps = GetDmg(b.level)
set time = 0.0
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0C7'
set BUFF_DATA.BuffID = 'B04N'
set BUFF_DATA.Name = "Bleeding"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct SharpenedClaws extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A06C'
set BUFF_DATA.BuffID = 'B044'
set BUFF_DATA.Name = "Sharpened Claws"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real d = BUFF_DURATION
if IsUpgradeSuperior(u,UPGRADE_ID) then
set d = d + SUP_DUR
endif
call UnitAddBuff(u,u,d,SharpenedClaws.buff,lvl,0)
set u = null
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType == udg_DamageTypeAttack and not data.isMiss then
set b = GetUnitBuff(data.source,SharpenedClaws.buff)
if b != 0 and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) then
if not UnitHasBuff(data.target,Bleeding.buff) then
call UnitAddBuff(data.target,data.source,BLEED_DURATION + UP_DUR * GetUpgradeSkillLevel(data.source,UPGRADE_ID),Bleeding.buff,b.level,0)
endif
endif
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType == udg_DamageTypeAttack then
set b = GetUnitBuff(data.target,Bleeding.buff)
if b != 0 then
set data.criticalChanceAdd = data.criticalChanceAdd + Bleeding[b.buffAllocIndex].crit
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call SharpenedClaws.Initialize()
call Bleeding.Initialize()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ShadowCrawler_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope UnholyRage initializer init
globals
private constant integer SPELL_ID = 'SWA3'
private constant integer UPGRADE_ID = 'SWI3'
private constant integer AS_BASE = 50
private constant integer AS_LEVEL = 50
private constant real BUFF_DURATION = 3.00
private constant real CD_BASE = 13.00
private constant real CD_LEVEL = 1.00
private constant real UP_LS = 0.05
private constant integer SUP_MS = 50
private constant string LOOP_SFX = "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodPeasant.mdl"
endglobals
private function GetAs takes integer lvl returns integer
return AS_BASE + AS_LEVEL * lvl
endfunction
private function GetCd takes integer lvl returns real
return CD_BASE - CD_LEVEL * lvl
endfunction
struct UnholyRage extends array
integer as
real ls
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
if ls != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,-ls,0)
set ls = 0.
endif
if ms != 0 then
call ms.destroy()
set ms = 0
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set as = GetAs(b.level)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
if ulvl != 0 then
set ls = UP_LS + UP_LS * ulvl
call BonusStruct.AddSpecial(BONUS_TYPE_LIFESTEAL,b.target,ls,0)
endif
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set ms = Movespeed.create(b.target,0,SUP_MS)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0C8'
set BUFF_DATA.BuffID = 'B04O'
set BUFF_DATA.Name = "Unholy Rage"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
call UnitAddBuff(u,u,BUFF_DURATION,SharpenedClaws.buff,lvl,0)
set u = null
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
if data.dmgType == udg_DamageTypeAttack and not data.isMiss and data.mainAttack then
set lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
if lvl != 0 then
if BlzGetUnitAbilityCooldownRemaining(data.source,SPELL_ID) == 0 then
call UnitAddBuff(data.source,data.source,BUFF_DURATION,UnholyRage.buff,lvl,0)
call BlzStartUnitAbilityCooldown(data.source,SPELL_ID,GetCd(lvl))
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call UnholyRage.Initialize()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ShadowCrawler_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope ShadowRip initializer init
globals
private constant integer SPELL_ID = 'SWA4'
private constant integer UPGRADE_ID = 'SWI4'
private constant real DMG_BASE = 80
private constant real DMG_LEVEL = 20
private constant real AGI_BASE = 0.40
private constant string LOOP_SFX = "war3mapImported\\ShadowRip.mdx"
private constant string CLAW_SFX = "Abilities\\Spells\\Orc\\TrollBerserk\\HeadhunterWEAPONSLeft.mdl"
private RSound ABILITY_SOUND
endglobals
private function GetDmg takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private function GetAgi takes integer lvl returns real
return AGI_BASE * lvl
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real x = tb.real[2]
local real y = tb.real[3]
local real off = tb.real[4]
local real a = tb.real[5]
local real z = tb.real[18]
local integer c = tb.integer[14]
local effect sfx
local group g
local group g2
local player p
local unit temp
local DamageOptions op
local real x2
local real y2
local real x3
local real y3
set x = x + 35.00 * tb.real[8]
set y = y + 35.00 * tb.real[9]
set tb.real[2] = x
set tb.real[3] = y
call SetUnitX(u,x)
call SetUnitY(u,y)
call SetUnitX(tb.unit[17],x)
call SetUnitY(tb.unit[17],y)
set sfx = tb.effect[18]
call BlzSetSpecialEffectX(sfx,x)
call BlzSetSpecialEffectY(sfx,y)
call BlzSetSpecialEffectZ(sfx,z)
set sfx = AddSpecialEffect(LOOP_SFX,x,y)
call BlzSetSpecialEffectScale(sfx,0.75)
call BlzSetSpecialEffectZ(sfx,z)
call DestroyEffect(sfx)
set x2 = x + off * tb.real[10]
set y2 = y + off * tb.real[11]
set sfx = tb.effect[19]
call BlzSetSpecialEffectX(sfx,x2)
call BlzSetSpecialEffectY(sfx,y2)
call BlzSetSpecialEffectZ(sfx,z)
set sfx = AddSpecialEffect(LOOP_SFX,x2,y2)
call BlzSetSpecialEffectScale(sfx,0.50)
call BlzSetSpecialEffectZ(sfx,z)
call DestroyEffect(sfx)
set x3 = x + off * tb.real[12]
set y3 = y + off * tb.real[13]
set sfx = tb.effect[20]
call BlzSetSpecialEffectX(sfx,x3)
call BlzSetSpecialEffectY(sfx,y3)
call BlzSetSpecialEffectZ(sfx,z)
set sfx = AddSpecialEffect(LOOP_SFX,x3,y3)
call BlzSetSpecialEffectScale(sfx,0.50)
call BlzSetSpecialEffectZ(sfx,z)
call DestroyEffect(sfx)
set c = c - 1
set off = off + 5
set tb.real[4] = off
set tb.integer[14] = c
if c > 0 then
set g = NewGroup()
set g2 = tb.group[16]
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,x,y,150,null)
set y = tb.real[7]
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitInGroup(temp,g2) then
call GroupAddUnit(g2,temp)
set op = DamageOptions.create()
set op.allowOrbs = true
call CodeDamage.Damage(u,temp,y,udg_DamageTypeAttack,"",0,op)
endif
endloop
call ReleaseGroup(g)
set g = null
set g2 = null
set p = null
else
call Status.Remove(STATUS_HIDE,u)
call SelectUnitForPlayer(u,GetOwningPlayer(u),true)
call BlzUnitDisableAbility(u,'Aatk',false,false)
call RemoveUnit(tb.unit[17])
call DestroyEffect(tb.effect[18])
call DestroyEffect(tb.effect[19])
call DestroyEffect(tb.effect[20])
call ReleaseTimer(t)
call ReleaseGroup(tb.group[16])
call tb.flush()
call tb.destroy()
endif
set t = null
set u = null
set sfx = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real xt = GetSpellTargetX()
local real yt = GetSpellTargetY()
local real a = Angle(x,y,xt,yt)
local real z = GetLocZ(x,y) + 90
local effect sfx
set tb.unit[0] = u
set tb.integer[1] = lvl
set tb.real[2] = x
set tb.real[3] = y
set tb.real[4] = 10.00
set tb.real[5] = a
set tb.real[7] = GetDmg(lvl) + GetHeroAgi(u,true) * GetAgi(lvl)
set tb.real[8] = Cos(a)
set tb.real[9] = Sin(a)
set tb.real[10] = Cos(a - 1.5707)
set tb.real[11] = Sin(a - 1.5707)
set tb.real[12] = Cos(a + 1.5707)
set tb.real[13] = Sin(a + 1.5707)
set tb.integer[14] = R2I(Distance(x,y,xt,yt) / 35.00)
set tb.integer[15] = tb.integer[14] / 2
set tb.group[16] = NewGroup()
set tb.unit[17] = CreateUnit(GetTriggerPlayer(),'h00O',x,y,0)
set tb.real[18] = z
set sfx = AddSpecialEffect(CLAW_SFX,x,y)
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectScale(sfx,1.5)
call BlzSetSpecialEffectZ(sfx,z)
set tb.effect[18] = sfx
set sfx = AddSpecialEffect(CLAW_SFX,x + 10 * tb.real[10],y + 10 * tb.real[11])
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectScale(sfx,1.5)
call BlzSetSpecialEffectZ(sfx,z)
set tb.effect[19] = sfx
set sfx = AddSpecialEffect(CLAW_SFX,x + 10 * tb.real[12],y + 10 * tb.real[13])
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectScale(sfx,1.5)
call BlzSetSpecialEffectZ(sfx,z)
set tb.effect[20] = sfx
call Status.Add(STATUS_HIDE,u,0,0)
call BlzUnitDisableAbility(u,'Aatk',true,false)
call TimerStart(t,0.03125,true,function Callback)
call ABILITY_SOUND.play(x,y,0,100)
set t = null
set u = null
set sfx = null
endfunction
private function OnDeath takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit k = GetKillingUnit()
local Ability a
if IsUnitType(u,UNIT_TYPE_HERO) and GetUnitAbilityLevel(k,UPGRADE_ID) != 0 then
if UnitAlive(k) and GetHeroMasteryType(u) == 2 then
set a = Ability.GetUnitAbilityByID('SWA1',k)
call a.resetCooldown()
set a = Ability.GetUnitAbilityByID('SWA2',k)
call a.resetCooldown()
call BlzEndUnitAbilityCooldown(k,'SWA3')
set a = Ability.GetUnitAbilityByID('SWA4',k)
call a.addCharges(1)
endif
endif
set u = null
set k = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local ability ab
if up.upID == UPGRADE_ID then
if up.level == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addMaxCharges(1)
endif
if GetHeroMasteryType(up.ownerHero.hero) == 1 then
set ab = BlzGetUnitAbility(up.ownerHero.hero,'SWA1')
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,0,2)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,1,2)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,2,2)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,3,2)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_AREA_OF_EFFECT,0,200)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_AREA_OF_EFFECT,1,200)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_AREA_OF_EFFECT,2,200)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_AREA_OF_EFFECT,3,200)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_OPTIONS,0,3)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_OPTIONS,1,3)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_OPTIONS,2,3)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_OPTIONS,3,3)
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_BASE_ORDER_ID_NCL6,0,"shockwave")
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_BASE_ORDER_ID_NCL6,1,"shockwave")
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_BASE_ORDER_ID_NCL6,2,"shockwave")
call BlzSetAbilityStringLevelField(ab,ABILITY_SLF_BASE_ORDER_ID_NCL6,3,"shockwave")
set ab = null
endif
if GetHeroMasteryType(up.ownerHero.hero) == 2 then
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function OnDeath)
endif
endif
if up.upID == 'SWI1' and up.isSuperior then
set a = Ability.GetUnitAbilityByID('SWA1',up.ownerHero.hero)
call a.addCastRange(300)
endif
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local Ability a
if GetUnitAbilityLevel(u,SPELL_ID) == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call a.addMaxCharges(2)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.isCharged = true
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
set ABILITY_SOUND = RSound.create("war3mapImported\\Shadow Rip.mp3", true, false, 12700, 12700)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ShadowCrawler_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library ElderSage initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HEN1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'ENI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Damaging Glare"
set up.Text = "Increases |c00b4b4b4Nature Wave|r travel speed."
set up.SupText = "Increases the max |c0000ced1Entangle|r duration to 5 seconds."
set up.LevelData1 = "Low speed"
set up.LevelData2 = "Medium speed"
set up.LevelData3 = "High speed"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWisp.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'ENI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Life Seed"
set up.Text = "|c00b4b4b4Life Bloom|r Heals/Damages the units around."
set up.SupText = "Increases |c00b4b4b4Life Bloom|r area of effect by 100."
set up.LevelData1 = "100 Heal/Damage"
set up.LevelData2 = "140 Heal/Damage"
set up.LevelData3 = "180 Heal/Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWispSplode.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'ENI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Everlasting Shine"
set up.Text = "Increases the duration of |c00b4b4b4Nature's Touch|r."
set up.SupText = "Gives 25% Critical chance bonus to the Damage/Healing done by |c00b4b4b4Nature's Touch.|r"
set up.LevelData1 = "+1 seconds"
set up.LevelData2 = "+2 seconds"
set up.LevelData3 = "+3 seconds"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNReplenishHealth.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'ENI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Ancient Constitution"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HEN1'
set d.Name = "Elder Sage"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNFurion.blp"
set d.WinAni = "spell"
set d.Block = 10
set d.Evasion = 40
set d.Resistance = 40
set d.LifeRegen = 1.0
set d.ManaRegen = 2.5
set d.Armor = 2
set d.AttackRange = 490
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'ENA1'
set d.HeroAbility2 = 'ENA2'
set d.HeroAbility3 = 'ENA3'
set d.HeroAbility4 = 'ENA4'
set d.ChooseIconID = 'c002'
set d.ChooseDummy = 'dh09'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 1
set d.healingLevel = 6
set d.survivavilityLevel = 2
set d.movementLevel = 2
set d.crowdControlLevel = 5
set d.HeroFaction = Game.FACTION_NIGHTELF
set d.InfoID = 'HENI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope NatureWave initializer init
globals
private constant integer SPELL_ID = 'ENA1'
private constant integer SPELL_DUMMYID = 'A00I'
private constant integer UPGRADE_ID = 'ENI1'
private constant real DMG_BASE = 60
private constant real DMG_LVL = 40
private constant real DISTANCE_FACTOR = 100
private constant real TIME_FACTOR = 0.25
private constant real MIN_DURATION = 1.0
private constant real MAX_DURATION = 3.0
private constant real UP_DMG_BASE = 20.00
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local unit h
local real d
local real dist
local integer lvl
local integer ulvl
local real dmg
local real max
local real factor
if GetUnitAbilityLevel(data.source,SPELL_DUMMYID) > 0 then
set h = GetUnitByIndex(GetDummyData(data.source,"caster"))
set dist = Distance(GetUnitX(h),GetUnitY(h),GetUnitX(data.target),GetUnitY(data.target))
set lvl = GetUnitAbilityLevel(h,SPELL_ID)
if IsUpgradeSuperior(h,UPGRADE_ID) then
set max = 5.0
set factor = 0.40
else
set max = MAX_DURATION
set factor = TIME_FACTOR
endif
set d = MIN_DURATION + dist / DISTANCE_FACTOR * factor
set dmg = GetDamage(lvl)
if d > max then
set d = max
endif
call CodeDamage.Damage(h,data.target,dmg,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_ENTANGLE,data.target,d,Status_EFFECT[STATUS_ENTANGLE])
endif
set h = null
endfunction
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local unit d = Ability.GetUnitAbilityByID(SPELL_ID,u).auxDummy
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
call SetUnitX(d,GetUnitX(u))
call SetUnitY(d,GetUnitY(u))
call UnitAddAbility(d,SPELL_DUMMYID)
call BlzSetAbilityIntegerField(BlzGetUnitAbility(d,SPELL_DUMMYID),ABILITY_IF_MISSILE_SPEED,600 + 100 * ulvl)
call SetUnitScale(d,1.1,1.1,1.1)
call SetDummyData(d,"caster",GetUnitUserData(u))
call CastDummyWave(d,ORDER_carrionswarm,x,y)
set d = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.UseAuxDummy = true
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID,function onCast)
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ElderSage_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(SPELL_DUMMYID,PRELOAD_FIRST)
endfunction
endscope
scope LifeBloom initializer init
globals
private constant integer SPELL_ID = 'ENA2'
private constant integer UPGRADE_ID = 'ENI2'
private constant integer SPELL_DUMMY_ID = 'A00J'
private constant real DELAY_BASE = 2.50
private constant real DELAY_LVL = 0.25
private constant real AOE_BASE = 300.00
private constant real AOE_SUP_UP = 100.00
private constant real UP_DMG = 60.00
private constant real UP_DMG_LVL = 40.00
private constant string TARGET_SFX = "war3mapImported\\ForestBlessing_Form2.mdx"
private constant string EXP_SFX = "Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl"
private constant real MASTERY_HEAL_FACTOR= 1.2
endglobals
private function GetAoe takes unit u returns real
if IsUpgradeSuperior(u,UPGRADE_ID) then
return AOE_BASE + AOE_SUP_UP
endif
return AOE_BASE
endfunction
private struct LifeBloom extends array
effect sfx
AoE aoe
real area
public static method onFinish takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g = NewGroup()
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local player p = GetOwningPlayer(b.owner)
local boolean ally = IsUnitAlly(b.target,p)
local real dur = NaturesTouch_GetDuration.evaluate(b.owner)
local unit temp
local real dmg
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
if ulvl != 0 then
set dmg = UP_DMG + UP_DMG_LVL * ulvl
endif
call GroupEnumUnitsInRange(g,x,y,area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if ally then
if FILT_UNIT_ALLIED(temp,p) then
call DestroyEffect(AddSpecialEffectTarget(EXP_SFX,temp,"origin"))
if b.int != 0 then
call UnitAddBuff(temp,b.owner,dur,NaturesTouch.buff,b.int,1)
endif
if ulvl != 0 then
call CodeDamage.Damage(b.owner,temp,dmg,udg_DamageTypeHeal,"",0,0)
endif
endif
else
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call DestroyEffect(AddSpecialEffectTarget(EXP_SFX,temp,"origin"))
if b.int != 0 then
call UnitAddBuff(temp,b.owner,dur,NaturesTouchDebuff.buff,b.int,1)
endif
if ulvl != 0 then
call CodeDamage.Damage(b.owner,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(sfx)
set sfx = null
call aoe.destroy()
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
set area = GetAoe(b.owner)
set aoe = AoE.create(0,0,b.target,area)
call BlzSetSpecialEffectColor(aoe.sfx,0,255,0)
set sfx = AddSpecialEffectTarget(TARGET_SFX,b.target,"origin")
if IsUnitAlly(b.target,GetOwningPlayer(b.owner)) then
set b.buffType = BUFF_TYPE_POSITIVE
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00K'
set BUFF_DATA.BuffID = 'B000'
set BUFF_DATA.Name = "Life Bloom"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u, unit t, integer lvl, integer elvl returns nothing
call UnitAddBuff(t,u,DELAY_BASE - DELAY_LVL * lvl,LifeBloom.buff,lvl,elvl)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local integer elvl = GetUnitAbilityLevel(u,'ENA3')
if IsUnitEnemy(t,GetTriggerPlayer()) then
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl,elvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl,elvl)
endif
else
call SpellTrigger(u,t,lvl,elvl)
endif
set u = null
set t = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(-1.0)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call LifeBloom.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ElderSage_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(SPELL_DUMMY_ID,PRELOAD_FIRST)
call PreloadGen.Add('A00K',PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
scope NaturesTouch initializer init
globals
private constant integer SPELL_ID = 'ENA3'
private constant integer UPGRADE_ID = 'ENI3'
private constant real BUFF_DURATION = 7.00
private constant real HEAL_BASE = 20.00
private constant real HEAL_LVL = 5.00
private constant real HEAL_INTERVAL = 1.00
//Upgrade
private constant real UP_DURATION_BASE = 1.00
private constant real MASTERY_HEAL_INC = 25.00
private constant real MASTERY_INTERVAL_RED = 0.25
endglobals
public function GetDuration takes unit u returns real
return BUFF_DURATION + (UP_DURATION_BASE * GetUpgradeSkillLevel(u,UPGRADE_ID))
endfunction
private function GetHealAmount takes unit u, integer lvl returns real
return HEAL_BASE + HEAL_LVL * lvl
endfunction
struct NaturesTouchDebuff extends array
real dmg
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypeMagicOverTime,"NaturesTouch",0,0)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if GetHeroMasteryType(b.owner) == 2 then
set b.period = HEAL_INTERVAL - MASTERY_INTERVAL_RED
endif
set dmg = GetHealAmount(b.owner,b.level)
if b.int == 1 then
set dmg = dmg + dmg * 0.30
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00M'
set BUFF_DATA.BuffID = 'B002'
set BUFF_DATA.Name = "Natures Touch Debuff"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = HEAL_INTERVAL
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct NaturesTouch extends array
real heal
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,heal,udg_DamageTypeHealOverTime,"NaturesTouch",0,0)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if GetHeroMasteryType(b.owner) == 2 then
set b.period = HEAL_INTERVAL - MASTERY_INTERVAL_RED
endif
set heal = GetHealAmount(b.owner,b.level)
if b.int == 1 then
set heal = heal + heal * 0.30
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00L'
set BUFF_DATA.BuffID = 'B001'
set BUFF_DATA.Name = "Natures Touch"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = HEAL_INTERVAL
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
public function SpellTrigger takes unit caster, unit target, integer lvl, integer op returns nothing
if op == 1 then
call UnitAddBuff(target,caster,GetDuration(caster),NaturesTouch.buff,lvl,0)
elseif op == 2 then
call UnitAddBuff(target,caster,GetDuration(caster),NaturesTouchDebuff.buff,lvl,0)
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if IsUnitEnemy(t,GetTriggerPlayer()) then
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl,2)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl,2)
endif
else
call SpellTrigger(u,t,lvl,1)
endif
set u = null
set t = null
endfunction
private function onPreDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
local Buff b
if d.codeDmg.codeName == "NaturesTouch" then
if IsUpgradeSuperior(d.source,'ENI3') then
set d.criticalChanceAdd = d.criticalChanceAdd + 25
endif
endif
if d.dmgType == udg_DamageTypeAttack then
set b = GetUnitBuff(d.target,NaturesTouch.buff)
if b != 0 then
if GetHeroMasteryType(b.owner) == 1 then
if GetRandomInt(1,100) <= 15 then
call Status.Add(STATUS_ENTANGLE,d.source,1.0,Status_EFFECT[STATUS_ENTANGLE])
endif
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.activationType = ACTIVATION_TYPE_TARGET
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call NaturesTouch.Initialize()
call NaturesTouchDebuff.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ElderSage_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A00L',PRELOAD_SECOND)
call PreloadGen.Add('A00M',PRELOAD_SECOND)
endfunction
endscope
scope ElderMystic initializer init
globals
private constant integer SPELL_ID = 'ENA4'
private constant integer UPGRADE_ID = 'ENI4'
private constant real ENTANGLE_DURATION = 1.50
private constant real DAMAGE_BASE = 50.00
private constant real INT_DAMAGE_BASE = 0.25
private constant string IMPACT_SFX = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl"
private constant real UP_INT_DMG = 0.25
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + 100.00 * lvl
endfunction
private function onCast takes nothing returns nothing
local unit caster = GetTriggerUnit()
local Link head = NaturesTouch.DATAS.head
local real intdmg = INT_DAMAGE_BASE
local Link uh
local Buff b
local player p
local boolean wm = GetHeroMasteryType(caster) == 3
local real damage = GetDamage(GetUnitAbilityLevel(caster,SPELL_ID))
if GetUpgradeSkillLevel(caster,UPGRADE_ID) != 0 then
set intdmg = intdmg + UP_INT_DMG
endif
set damage = damage + GetHeroInt(caster,true) * intdmg
set p = GetOwningPlayer(caster)
loop
exitwhen head == null
set b = head.data
if b.owner == caster then
call b.restart()
call DestroyEffect(AddSpecialEffectTarget(IMPACT_SFX,b.target,"origin"))
call CodeDamage.Damage(caster,b.target,damage,udg_DamageTypeHeal,"ElderMystic",0,0)
if b.target != caster then
call Lightning.create("MFPB",caster,b.target,1.0,0.50,100,100)
endif
set b.dispelable = false
if wm then
set uh = UB[GetUnitUserData(b.target)].head
loop
exitwhen uh == 0
set b = uh.data
if not b.Persistent and b.data != NaturesTouch.buff then
if IsUnitAlly(b.target,p) then
if b.buffType == BUFF_TYPE_POSITIVE then
call b.restart()
endif
else
if b.buffType == BUFF_TYPE_NEGATIVE then
call b.restart()
endif
endif
endif
set uh = uh.next
endloop
endif
endif
set head = head.next
endloop
set head = NaturesTouchDebuff.DATAS.head
loop
exitwhen head == null
set b = head.data
if b.owner == caster then
call b.restart()
call Status.Add(STATUS_ENTANGLE,b.target,ENTANGLE_DURATION,Status_EFFECT[STATUS_ENTANGLE])
call CodeDamage.Damage(caster,b.target,damage,udg_DamageTypeMagic,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(IMPACT_SFX,b.target,"origin"))
call Lightning.create("MFPB",caster,b.target,1.00,0.50,100,100)
endif
set b.dispelable = false
set head = head.next
endloop
set caster = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ElderSage_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(IMPACT_SFX)
endfunction
endscope
library TempestDruid initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HTD1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'TDI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Living Tempest"
set up.Text = "Increases |c00b4b4b4Living Tornado|r distance traveled and cast range."
set up.SupText = "Reduces |c00b4b4b4Living Tornado|r cooldown by 25% during |c00b4b4b4Wild Flight|r."
set up.LevelData1 = "+100 Distance/Cast Range"
set up.LevelData2 = "+150 Distance/Cast Range"
set up.LevelData3 = "+200 Distance/Cast Range"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNTornado.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'TDI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Mystic Morph"
set up.Text = "|c00b4b4b4Wild Flight|r adds a bonus |c00ffff95Attack Speed|r."
set up.SupText = "Increases |c00b4b4b4Wild Flight|r area of effect by 75 and damage factor by 20%"
set up.LevelData1 = "+20% Attack Speed"
set up.LevelData2 = "+30% Attack Speed"
set up.LevelData3 = "+40% Attack Speed"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNRavenForm.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'TDI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Wind Shear"
set up.Text = "Increases |c00ffff95Movement Speed|r after casting |c00b4b4b4Fierce Gale|r for 3.5s."
set up.SupText = "Increases |c00b4b4b4Fierce Gale|r travel speed and |c00ffff95Cast Range|r by 300."
set up.LevelData1 = "+50 Movement Speed"
set up.LevelData2 = "+70 Movement Speed"
set up.LevelData3 = "+90 Movement Speed"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNCyclone.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'TDI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Ancient Zephyr"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HTD1'
set d.Name = "Tempest Druid"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNDruidOfTheTalon.blp"
set d.WinAni = "spell"
set d.Block = 0
set d.Evasion = 40
set d.Resistance = 50
set d.LifeRegen = 1.0
set d.ManaRegen = 2.0
set d.Armor = 1
set d.AttackRange = 500
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'TDA1'
set d.HeroAbility2 = 'TDA2'
set d.HeroAbility3 = 'TDA3'
set d.HeroAbility4 = 'TDA4'
set d.ChooseIconID = 'c011'
set d.ChooseDummy = 'dh13'
set d.spellDamageLevel = 9
set d.attackDamageLevel = 1
set d.healingLevel = 0
set d.survivavilityLevel = 4
set d.movementLevel = 8
set d.crowdControlLevel = 5
set d.HeroFaction = Game.FACTION_NIGHTELF
set d.InfoID = 'HTDI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope LivingTornado initializer init
globals
private constant integer SPELL_ID = 'TDA1'
private constant integer UPGRADE_ID = 'TDI1'
private constant real DAMAGE_BASE = 60.00
private constant real DAMAGE_LEVEL = 60.00
private constant real DAMAGE_AREA = 120.00
private constant real DURATION_BASE = 0.75
private constant real DURATION_LEVEL = 0.50
private constant real DISTANCE_TRAVELED = 800.00
private constant real UP_DIST_TRAVELED = 50.00
private constant string MISSILE_SFX = "Abilities\\Spells\\Other\\Tornado\\TornadoElemental.mdl"
public constant string THUNDER_SFX = "war3mapImported\\LightningWrath.mdx"
endglobals
private function GetDuration takes integer lvl returns real
return DURATION_BASE + DURATION_LEVEL * lvl
endfunction
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
public function GetThunderDamage takes integer lvl returns real
return 50.0 + 50.0 * lvl
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local effect sfx = tb.effect[1]
local real a = tb.real[2]
local real d = tb.real[3]
local unit l = tb.unit[4]
local real sp = tb.real[5]
local real dur = tb.real[6]
local LinkedList eye
local Link node
local Table tbes = 0
local Table tbes2 = 0
local real lan
local real x
local real y
local real r
local group g
local group g2
local unit temp
local player p
local boolean end = false
if l == null then
set x = BlzGetLocalSpecialEffectX(sfx)
set y = BlzGetLocalSpecialEffectY(sfx)
set x = x + sp * Cos(a)
set y = y + sp * Sin(a)
set d = d - sp
call BlzSetSpecialEffectPosition(sfx,x,y,GetLocZ(x,y))
set tb.real[3] = d
if d <= 0 then
set end = true
else
set g = NewGroup()
set g2 = tb.group[9]
set p = GetOwningPlayer(u)
set r = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
call GroupEnumUnitsInRange(g,x,y,DAMAGE_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and l == null then
set l = temp
exitwhen true
elseif FILT_UNIT_ENEMY(temp,p) and not IsUnitInGroup(temp,g2) then
call GroupAddUnit(g2,temp)
call CodeDamage.Damage(u,temp,r,udg_DamageTypeMagicAoe,"LivingTornado",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set g2 = null
set temp = null
set p = null
if l != null then
set tb.unit[4] = l
call SetUnitData(l,"LT_Active",tb)
set tb.real[6] = Status.Add(STATUS_STUN,l,dur,Status_EFFECT[STATUS_STUN])
set tb.real[7] = GetUnitFacing(l)
if tb.real[6] == 0 then
set end = true
else
set x = GetUnitX(l)
set y = GetUnitY(l)
call BlzSetSpecialEffectX(sfx,x)
call BlzSetSpecialEffectY(sfx,y)
call MakeFly(l)
call SetUnitFlyHeight(l,240,100)
set eye = GetUnitData(u,"WC_Inst")
if eye != 0 then
if eye.size != 0 then
set node = eye.head
set lan = 800
loop
exitwhen node == 0
set tbes = node.data
set r = Distance(x,y,GetUnitX(tbes.unit[1]),GetUnitY(tbes.unit[1]))
if r < lan then
set lan = r
set tbes2 = tbes
endif
set node = node.next
endloop
endif
endif
if tbes2 != 0 then
set tb.real[5] = (lan / (tb.real[6] / 0.03125))
set tb.real[2] = Angle(x,y,GetUnitX(tbes2.unit[1]),GetUnitY(tbes2.unit[1]))
set tb.real[3] = lan
set tb.integer[8] = tbes2
endif
endif
endif
endif
else
set dur = tb.real[6]
set lan = tb.real[7]
set dur = dur - 0.03125
set lan = lan + 22.5
if not Status.UnitHasStatus(STATUS_ENSNARE,l) or not Status.UnitHasStatus(STATUS_ENTANGLE,l) then
call BlzSetUnitFacingEx(l,lan)
endif
set tb.real[7] = lan
set tb.real[6] = dur
set tbes2 = tb.integer[8]
if tbes2 != 0 then
set x = GetUnitX(l) + sp * Cos(a)
set y = GetUnitY(l) + sp * Sin(a)
call SetUnitX(l,x)
call SetUnitY(l,y)
call BlzSetSpecialEffectPosition(sfx,x,y,GetLocZ(x,y))
endif
if dur <= 0 then
call SetUnitFlyHeight(l,GetUnitDefaultFlyHeight(l),0)
set g = NewGroup()
set p = GetOwningPlayer(u)
set r = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
call GroupEnumUnitsInRange(g,GetUnitX(l),GetUnitY(l),250,null)
call DestroyEffect(AddSpecialEffect(THUNDER_SFX,GetUnitX(l),GetUnitY(l)))
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,r,udg_DamageTypeMagicAoe,"LivingTornado",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set end = true
endif
endif
if end then
call SetUnitData(tb.unit[4],"LT_Active",0)
call ReleaseGroup(tb.group[9])
call BlzSetSpecialEffectTimeScale(sfx,3.0)
call DestroyEffect(sfx)
call ReleaseTimer(t)
call tb.flush()
call tb.destroy()
endif
set sfx = null
set t = null
set u = null
set l = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real xu = GetUnitX(u)
local real yu = GetUnitY(u)
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local real d = DISTANCE_TRAVELED
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local effect sfx = AddSpecialEffect(MISSILE_SFX,xu,yu)
local Table tba = GetUnitData(u,"LT_Active")
if tba != 0 then
call tba.flush()
call tba.destroy()
endif
call BlzSetSpecialEffectScale(sfx,0.30)
if ulvl != 0 then
set d = d + (UP_DIST_TRAVELED + UP_DIST_TRAVELED * ulvl)
endif
set tb.unit[0] = u
set tb.effect[1] = sfx
set tb.real[2] = Angle(xu,yu,x,y)
set tb.real[3] = d
set tb.unit[4] = null
set tb.real[5] = 18.00
set tb.real[6] = GetDuration(lvl)
set tb.group[9] = NewGroup()
call TimerStart(t,0.03125,true,function Callback)
set t = null
set sfx = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TempestDruid_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01J',PRELOAD_SECOND)
call Preload(THUNDER_SFX)
call Preload(MISSILE_SFX)
endfunction
endscope
scope WildFlight initializer init
globals
private constant integer SPELL_ID = 'TDA2'
private constant integer UPGRADE_ID = 'TDI2'
public constant integer MORPH_ID = 'A01B'
public constant integer MORPH_REVERSE_ID = 'A06K'
private constant integer DAMAGE_BASE = 30
private constant integer DAMAGE_LEVEL = 10
private constant real BUFF_DURATION = 20.00
private constant integer UP_AS_BASE = 10
public constant string TRANSFORMATION_SFX = "Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl"
private RSound ABILITY_SOUND
endglobals
private function GetDamage takes integer lvl returns integer
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct WildFlight extends array
integer as
real df
integer dmg
integer count
boolean cdq
Ability W
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local effect e1
local effect e2
local real f
local Ability a
if UnitAlive(b.target) then
set f = GetUnitFacing(b.target)
call AddUnitAnimationProperties(b.target,"alternate",false)
call UnitAddAbility(b.target,MORPH_REVERSE_ID)
call UnitRemoveAbility(b.target,MORPH_REVERSE_ID)
call Upgrade.SetHeroTittle(b.target,GetHeroMasteryType(b.target))
call BlzSetUnitFacingEx(b.target,f)
else
call SetUnitData(b.target,"UnMorph",MORPH_REVERSE_ID)
endif
call SetUnitVertexColor(b.target,255,255,255,255)
set e1 = AddSpecialEffect(TRANSFORMATION_SFX,x,y)
call BlzSetSpecialEffectScale(e1,1.5)
call BlzSetSpecialEffectZ(e1,GetLocZ(x,y) + 210.00)
call DestroyEffect(e1)
set e2 = AddSpecialEffect(TRANSFORMATION_SFX,x,y)
call BlzSetSpecialEffectScale(e2,1.5)
call DestroyEffect(e2)
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
set as = 0
endif
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
if cdq then
set a = Ability.GetUnitAbilityByID('TDA1',b.target)
call a.addPercentCooldown(0.25)
set cdq = false
endif
if b.int == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,b.target)
call a.forceCooldown()
call BlzUnitDisableAbility(b.target,SPELL_ID,false,false)
endif
call W.abilityNumber.setValue(0)
set e1 = null
set e2 = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local effect e1
local effect e2
local integer m = GetHeroMasteryType(b.target)
local Ability a
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set W = Ability.GetUnitAbilityByID(SPELL_ID,b.target)
set dmg = GetDamage(b.level)
set count = 2 + 1 * b.level
call W.abilityNumber.setValue(count)
set df = 0.40 + 0.10 * b.level
if ulvl != 0 then
set as = UP_AS_BASE + UP_AS_BASE * ulvl
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endif
if IsUpgradeSuperior(b.target,'TDI1') then
set a = Ability.GetUnitAbilityByID('TDA1',b.target)
call a.addPercentCooldown(-0.25)
set cdq = true
endif
call ABILITY_SOUND.play(x,y,0,100)
call UnitAddAbility(b.target,MORPH_ID)
call UnitRemoveAbility(b.target,MORPH_ID)
call AddUnitAnimationProperties(b.target,"alternate",true)
call SetUnitVertexColor(b.target,200,200,100,255)
if IsUpgradeSuperior(b.target,'TDI2') then
call BlzSetUnitWeaponRealField(b.target,UNIT_WEAPON_RF_ATTACK_AREA_OF_EFFECT_FULL_DAMAGE,0,325)
call BlzSetUnitWeaponRealField(b.target,UNIT_WEAPON_RF_ATTACK_AREA_OF_EFFECT_MEDIUM_DAMAGE,0,325)
call BlzSetUnitWeaponRealField(b.target,UNIT_WEAPON_RF_ATTACK_AREA_OF_EFFECT_SMALL_DAMAGE,0,325)
call BlzSetUnitWeaponRealField(b.target,UNIT_WEAPON_RF_ATTACK_BASE_COOLDOWN,0,1.8)
set df = df + 0.20
endif
if b.int == 1 then
call BlzUnitDisableAbility(b.target,SPELL_ID,true,false)
endif
set e1 = AddSpecialEffect(TRANSFORMATION_SFX,x,y)
call BlzSetSpecialEffectScale(e1,1.5)
call BlzSetSpecialEffectZ(e1,GetLocZ(x,y) + 210.00)
call DestroyEffect(e1)
set e2 = AddSpecialEffect(TRANSFORMATION_SFX,x,y)
call BlzSetSpecialEffectScale(e2,1.5)
call DestroyEffect(e2)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call Upgrade.SetHeroTittle(b.target,GetHeroMasteryType(b.target))
set e1 = null
set e2 = null
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "WildFlight"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local real f
local Buff b
if GetUnitTypeId(data.source) == 'H004' then
set b = GetUnitBuff(data.source,WildFlight.buff)
if b != 0 then
if data.target == GetUnitByIndex(GetUnitData(data.source,"Target")) then
set WildFlight[b.buffAllocIndex].count = WildFlight[b.buffAllocIndex].count - 1
call WildFlight[b.buffAllocIndex].W.abilityNumber.setValue(WildFlight[b.buffAllocIndex].count)
if WildFlight[b.buffAllocIndex].count == 0 then
call SetUnitBuffDuration(data.source,WildFlight.buff,0.01)
endif
call CodeDamage.Damage(data.source,data.target,data.damageMod,udg_DamageTypeMagicAoe,"WFMain",0,0)
else
call CodeDamage.Damage(data.source,data.target,data.damageMod * WildFlight[b.buffAllocIndex].df,udg_DamageTypeMagicAoe,"WFSplash",0,0)
endif
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
if GetHeroMasteryType(u) == 2 then
call UnitAddBuff(u,u,999999,WildFlight.buff,GetUnitAbilityLevel(u,SPELL_ID),1)
else
call UnitAddBuff(u,u,BUFF_DURATION,WildFlight.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local Ability a
local unit u = GetTriggerUnit()
if GetUnitAbilityLevel(u,SPELL_ID) == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
set a.abilityNumber = AbilityNumber.create(a.objectID,u)
call a.abilityNumber.setValue(0)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call WildFlight.Initialize()
set ABILITY_SOUND = RSound.create("Units\\NightElf\\DruidOfTheTalon\\DruidOfTheTalonMorph1.wav", true, false, 12700, 12700)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID,function onLearn)
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TempestDruid_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A02V',PRELOAD_SECOND)
endfunction
endscope
scope FierceGale initializer init
globals
private constant integer SPELL_ID = 'TDA3'
private constant integer UPGRADE_ID = 'TDI3'
private constant real DASH_AREA = 180.00
private constant real DURATION = 4.0
private constant string AREA_SFX = "war3mapImported\\Cyclone.mdl"
private constant string HIT_SFX = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl"
private RSound ABILITY_SOUND
endglobals
struct FierceGaleSpeed extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,0,30 + 20 * b.level)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0D3'
set BUFF_DATA.BuffID = 'B05U'
set BUFF_DATA.Name = "Fierce Gale Speed"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct FierceGale extends array
integer miss
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set miss = 0
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set miss = 20 + 20 * b.level
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01K'
set BUFF_DATA.BuffID = 'B00O'
set BUFF_DATA.Name = "Fierce Gale"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct FierceGaleDash extends array
integer attAdd
Buff wf
integer ulvl
boolean morph
real speed
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local effect sfx
local Table tb = b.int
local real f
if morph then
if UnitAlive(b.target) then
set f = GetUnitFacing(b.target)
call AddUnitAnimationProperties(b.target,"alternate",false)
call UnitAddAbility(b.target,WildFlight_MORPH_REVERSE_ID)
call UnitRemoveAbility(b.target,WildFlight_MORPH_REVERSE_ID)
call BlzSetUnitFacingEx(b.target,f)
else
call SetUnitData(b.target,"UnMorph",WildFlight_MORPH_REVERSE_ID)
endif
call SetUnitVertexColor(b.target,255,255,255,255)
else
call wf.pause(false)
set WildFlight[wf.buffAllocIndex].count = WildFlight[wf.buffAllocIndex].count + attAdd
call WildFlight[wf.buffAllocIndex].W.abilityNumber.setValue(WildFlight[wf.buffAllocIndex].count)
call CreateTextTagForPlayer(GetOwningPlayer(b.target),GetUnitX(b.target),GetUnitY(b.target),"|c000000ff+"+I2S(attAdd)+"|r",12)
call SetUnitVertexColor(b.target,200,200,100,255)
endif
if ulvl != 0 then
call UnitAddBuff(b.target,b.target,3.5,FierceGaleSpeed.buff,ulvl,0)
endif
set sfx = AddSpecialEffect(WildFlight_TRANSFORMATION_SFX,GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectScale(sfx,1.5)
call DestroyEffect(sfx)
call BlzUnitDisableAbility(b.target,'TDA1',false,false)
call BlzUnitDisableAbility(b.target,'TDA2',false,false)
call BlzUnitDisableAbility(b.target,'TDA4',false,false)
call Status.Remove(STATUS_DISARM,b.target)
call Status.Remove(STATUS_UNTURN,b.target)
call Status.Remove(STATUS_UNPATH,b.target)
call UnitRemoveAbility(b.target,'A09G')
set morph = false
set wf = 0
call tb.flush()
call tb.destroy()
set sfx = null
endmethod
private method CheckWindOfChanges takes Buff b returns nothing
local LinkedList l = GetUnitData(b.target,"WC_Inst")
local Link node
local Table tb
local group g
local player p
local unit temp
local real dmg
local real x
local real y
if l != 0 then
if l.size != 0 then
set node = l.head
loop
exitwhen node == 0
set tb = node.data
if IsUnitInRange(tb.unit[1],b.target,150) and not tb.boolean[b] then
set tb.boolean[b] = true
set g = NewGroup()
set p = GetOwningPlayer(b.target)
set dmg = LivingTornado_GetThunderDamage(GetUnitAbilityLevel(b.target,'TDA4'))
set x = GetUnitX(tb.unit[1])
set y = GetUnitY(tb.unit[1])
call GroupEnumUnitsInRange(g,x,y,200,null)
call DestroyEffect(AddSpecialEffect(LivingTornado_THUNDER_SFX,x,y))
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(b.target,temp,dmg,udg_DamageTypeMagicAoe,"Thunder",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
set node = node.next
endloop
endif
endif
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g = NewGroup()
local Table tb = b.int
local real a = tb.real[1]
local real d = tb.real[0]
local player p = GetOwningPlayer(b.target)
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local integer id
local unit temp
local real durEff = I2R(b.level)
set x = x + speed * Cos(a)
set y = y + speed * Sin(a)
set d = d - speed
call SetUnitX(b.target,x)
call SetUnitY(b.target,y)
call CheckWindOfChanges(b)
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),DASH_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
set id = GetUnitUserData(temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and not tb.boolean[id] then
set tb.boolean[id] = true
call Status.Add(STATUS_SILENCE,temp,durEff,Status_EFFECT[STATUS_SILENCE])
call UnitAddBuff(temp,b.target,durEff,FierceGale.buff,b.level,0)
if IsUnitType(temp,UNIT_TYPE_HERO) then
set attAdd = attAdd + 1
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
if d <= 0 then
set b.removeInside = true
else
set tb.real[0] = d
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Buff bw = GetUnitBuff(b.target,WildFlight.buff)
local real xu = GetUnitX(b.target)
local real yu = GetUnitY(b.target)
local effect sfx
set ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set speed = 40
else
set speed = 30
endif
set attAdd = 0
if bw == 0 then
set morph = true
call UnitAddAbility(b.target,WildFlight_MORPH_ID)
call UnitRemoveAbility(b.target,WildFlight_MORPH_ID)
call AddUnitAnimationProperties(b.target,"alternate",true)
else
set wf = bw
call bw.pause(true)
set morph = false
endif
call ABILITY_SOUND.play(xu,yu,0,100)
set sfx = AddSpecialEffect(WildFlight_TRANSFORMATION_SFX,xu,yu)
call BlzSetSpecialEffectScale(sfx,1.5)
call DestroyEffect(sfx)
call BlzUnitDisableAbility(b.target,'TDA1',true,false)
call BlzUnitDisableAbility(b.target,'TDA2',true,false)
call BlzUnitDisableAbility(b.target,'TDA4',true,false)
call Status.Add(STATUS_DISARM,b.target,0,0)
call Status.Add(STATUS_UNTURN,b.target,0,0)
call Status.Add(STATUS_UNPATH,b.target,0,0)
call SetUnitAnimationByIndex(b.target,2)
call UnitAddAbility(b.target,'A09G')
call SetUnitVertexColor(b.target,200,200,100,155)
set sfx = null
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Wind Flutter Dash"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local Table tb = Table.create()
if UnitHasBuff(u,FierceGaleDash.buff) then
call UnitRemoveBuff(u,FierceGaleDash.buff)
endif
set tb.real[0] = Distance(GetUnitX(u),GetUnitY(u),GetSpellTargetX(),GetSpellTargetY())
set tb.real[1] = Angle(GetUnitX(u),GetUnitY(u),GetSpellTargetX(),GetSpellTargetY())
call UnitAddBuff(u,u,20,FierceGaleDash.buff,GetUnitAbilityLevel(u,SPELL_ID),tb)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FierceGaleDash.Initialize()
call FierceGaleSpeed.Initialize()
set ABILITY_SOUND = RSound.create("Units\\NightElf\\DruidOfTheTalon\\DruidOfTheTalonMorphedYes3.wav", true, false, 12700, 12700)
call FierceGale.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TempestDruid_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01K',PRELOAD_SECOND)
call Preload(AREA_SFX)
call Preload(HIT_SFX)
endfunction
endscope
scope EyeoftheStorm initializer init
globals
private constant integer SPELL_ID = 'TDA4'
private constant integer UPGRADE_ID = 'TDI4'
private constant integer AURA_ID = 'A01L'
private constant real DAMAGE_INC = 0.10
private constant real DURATION = 35.00
private constant string AREA_SFX = "war3mapImported\\WindAura.mdx"
endglobals
private function callback takes nothing returns nothing
local Table tb = GetTimerData(GetExpiredTimer())
local LinkedList l = GetUnitData(tb.unit[0],"WC_Inst")
//local AoE aoe = tb.integer[4]
call UnitRemoveAbility(tb.unit[1],AURA_ID)
call SetUnitOwner(tb.unit[1],Game.PLAYER_NEUTRAL_EXTRA,false)
call RecycleMissile(tb.unit[1])
call DestroyEffect(tb.effect[2])
//call aoe.destroy()
call l.remove(tb.integer[3])
call tb.flush()
call tb.destroy()
call ReleaseTimer(GetExpiredTimer())
endfunction
private function onLearn takes nothing returns nothing
local Ability a
local unit u = GetTriggerUnit()
if GetUnitAbilityLevel(u,SPELL_ID) == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call a.addMaxCharges(3)
call SetUnitData(u,"WC_Inst",LinkedList.create())
endif
set u = null
endfunction
private function WMCallback takes nothing returns nothing
local unit u = GetUnitByIndex(GetTimerData(GetExpiredTimer()))
local LinkedList es = GetUnitData(u,"WC_Inst")
local Link node
local integer r = 0
local Link s = 0
local Table tb
local group g
local player p
local unit temp
if es != 0 then
set node = es.head
loop
exitwhen node == 0
set r = r + 1
if GetRandomInt(1,r) == 1 then
set s = node
endif
set node = node.next
endloop
if s != 0 then
set tb = s.data
set g = NewGroup()
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,GetUnitX(tb.unit[1]),GetUnitY(tb.unit[1]),220,null)
call DestroyEffect(AddSpecialEffect(LivingTornado_THUNDER_SFX,GetUnitX(tb.unit[1]),GetUnitY(tb.unit[1])))
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,120,udg_DamageTypeMagicAoe,"Thunder",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
endif
set u = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == 'TDI3' then
if up.isSuperior then
set a = Ability.GetUnitAbilityByID('TDA3',up.ownerHero.hero)
call a.addCastRange(300)
endif
endif
if up.upID == 'TDI1' then
set a = Ability.GetUnitAbilityByID('TDA1',up.ownerHero.hero)
if a != 0 then
if up.level == 1 then
call a.addCastRange(100)
else
call a.addCastRange(50)
endif
endif
endif
if up.upID == UPGRADE_ID and up.level == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
if a != 0 then
call a.addMaxCharges(1)
endif
endif
if up.upID == UPGRADE_ID and GetHeroMasteryType(up.ownerHero.hero) == 3 then
call TimerStart(NewTimerEx(GetUnitUserData(up.ownerHero.hero)),1.8,true,function WMCallback)
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local Buff b
if data.dmgType == 5 or data.dmgType == 6 then
set lvl = GetUnitAbilityLevel(data.target,'B00P')
if lvl != 0 then
set data.mult = data.mult + (DAMAGE_INC * lvl)
endif
endif
if data.dmgType == udg_DamageTypeAttack then
set b = GetUnitBuff(data.source,FierceGale.buff)
if b != 0 then
if GetRandomInt(1,100) <= FierceGale[b.buffAllocIndex].miss then
set data.trueEvasion = true
endif
endif
set lvl = GetUnitData(data.target,"LT_Active")
if lvl != 0 then
set data.trueEvasion = true
endif
endif
if data.codeDmg != 0 then
if data.codeDmg.codeName == "LivingTornado" or data.codeDmg.codeName == "WFMain" or data.codeDmg.codeName == "WFSplash" or data.codeDmg.codeName == "Thunder" then
if GetHeroMasteryType(data.source) == 1 then
set data.slifestealAdd = data.slifestealAdd + 0.25
endif
endif
endif
endfunction
private function SpellTrigger takes unit u, real x, real y returns nothing
local unit d = GetRecycledMissile(x,y,0.00,20.00)
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local LinkedList l = GetUnitData(u,"WC_Inst")
//local AoE aoe = AoE.create(x,y,null,300.00)
set tb.unit[0] = u
call SetUnitOwner(d,GetOwningPlayer(u),false)
call UnitAddAbility(d,AURA_ID)
call SetUnitAbilityLevel(d,AURA_ID,GetUnitAbilityLevel(u,SPELL_ID))
call UnitMakeAbilityPermanent(d,true,AURA_ID)
set tb.unit[1] = d
set tb.effect[2] = AddSpecialEffect(AREA_SFX,x,y)
set tb.integer[3] = l.add(tb)
//set tb.integer[4] = aoe
call BlzSetSpecialEffectTimeScale(tb.effect[2],2.0)
call TimerStart(t,DURATION,false,function callback)
set t = null
set d = null
endfunction
private function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function onExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local LinkedList list = GetUnitData(u,"WC_Inst")
local Link h = list.head
local Table tb
loop
exitwhen h == 0
set tb = h.data
if IsUnitInRangeXY(tb.unit[1],x,y,150) then
call PauseUnit(u,true)
call IssueImmediateOrderById(u,ORDER_stop)
call PauseUnit(u,false)
call Message.ShowToPlayer(GetTriggerPlayer(),"Cannot be placed near another Eye of the Storm",MESSAGE_STYLE_ERROR)
exitwhen true
endif
set h = h.next
endloop
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.isCharged = true
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
call RegisterSpellCastEvent(SPELL_ID, function onExtra)
call RegisterSpellLearn(SPELL_ID,function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TempestDruid_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(AURA_ID,PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
library ShadowSlayer initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HSA1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'SAI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Shadow Rush"
set up.Text = "Increases |c00b4b4b4Silent Edge|r |c00ffff95Movement Speed|r bonus."
set up.SupText = "Increases |c00b4b4b4Silent Edge|r damage factor by 25% and the damage can apply on-Attack effects."
set up.LevelData1 = "+10% MS"
set up.LevelData2 = "+20% MS"
set up.LevelData3 = "+30% MS"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNBlink.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'SAI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Sigil of Demon"
set up.Text = "|c00b4b4b4Vile Tricks|r also increases |c00ffff95Resistance|r."
set up.SupText = "|c00b4b4b4Vile Tricks|r gives 4% chance per stack to perform a low |c00b4b4b4Silent Edge|r attack."
set up.LevelData1 = "+10(1.5%) Resistance"
set up.LevelData2 = "+15(2.3%) Resistance"
set up.LevelData3 = "+20(3.1%) Resistance"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAuraOfDarkness.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'SAI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Feint"
set up.Text = "Reduces |c00b4b4b4Hateful Glaive |r|c00ffff95Cooldown|r."
set up.SupText = "Gains |c00ffff00Magic Immunity|r during |c00b4b4b4Dash|r."
set up.LevelData1 = "-2s Cooldown"
set up.LevelData2 = "-4s Cooldown"
set up.LevelData3 = "-6s Cooldown"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNEvasion.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'SAI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Dark Slash"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HSA1'
set d.Name = "Shadow Slayer"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNHeroDemonHunter.blp"
set d.WinAni = "stand channel"
set d.Block = 0
set d.Evasion = 60
set d.Resistance = 20
set d.LifeRegen = 2.0
set d.ManaRegen = 1.0
set d.Armor = 4
set d.AttackRange = 125
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'SAA1'
set d.HeroAbility2 = 'SAA2'
set d.HeroAbility3 = 'SAA3'
set d.HeroAbility4 = 'SAA4'
set d.ChooseIconID = 'c010'
set d.ChooseDummy = 'dh01'
set d.spellDamageLevel = 2
set d.attackDamageLevel = 8
set d.healingLevel = 0
set d.survivavilityLevel = 3
set d.movementLevel = 6
set d.crowdControlLevel = 2
set d.HeroFaction = Game.FACTION_NIGHTELF
set d.InfoID = 'HSAI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope SilentEdge initializer init
globals
private constant integer SPELL_ID = 'SAA1'
private constant integer UPGRADE_ID = 'SAI1'
private constant real DAMAGE_BASE = 20.00
private constant real DAMAGE_LEVEL = 20.00
private constant real MOVEMENT_BASE = 0.10
private constant real SPILL_DAMAGE_BASE = 0.60
private constant real SPILL_DAMAGE_LEVEL = 0.10
private constant real SPILL_AREA = 125.00
private constant real SPILL_DISTANCE = 650.00
private constant real BUFF_DURATION = 3.00
private constant real UP_MOVE_BASE = 0.10
private constant real SUP_SPILL = 0.25
private constant string MISSILE_SFX = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetDamageSpill takes integer lvl returns real
return SPILL_DAMAGE_BASE + SPILL_DAMAGE_LEVEL * lvl
endfunction
struct SilentEdgeMissile extends array
boolean orb
private static method onCollide takes Missile missile, unit hit returns boolean
local DamageOptions op = 0
if FILT_UNIT_ENEMY(hit,missile.owner) and hit != GetUnitByIndex(missile.data) then
call DestroyEffect(AddSpecialEffectTarget(MISSILE_SFX,hit,"chest"))
if thistype[missile].orb then
set op = DamageOptions.create()
set op.allowOrbs = true
endif
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypeAttack,"SilentEdge",0,op)
endif
return false
endmethod
implement MissileStruct
endstruct
struct SilentEdge extends array
Movespeed ms
real dmg
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real msa = MOVEMENT_BASE + UP_MOVE_BASE * GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set ms = Movespeed.create(b.target,msa,0)
set dmg = GetDamage(b.level)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01A'
set BUFF_DATA.BuffID = 'B00J'
set BUFF_DATA.Name = "Silent Edge"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function SetupMissile takes unit source, unit target, real dmg, integer op returns Missile
local real x = GetUnitX(source)
local real y = GetUnitY(source)
local real xt = GetUnitX(target)
local real yt = GetUnitY(target)
local real angle = Angle(x,y,xt,yt)
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local Missile missile = Missile.create(x, y, 100.0, angle, SPILL_DISTANCE, 100.0)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
if IsUpgradeSuperior(source,UPGRADE_ID) then
set missile.damage = dmg * (GetDamageSpill(lvl) + SUP_SPILL)
set SilentEdgeMissile[missile].orb = true
else
set missile.damage = dmg * GetDamageSpill(lvl)
set SilentEdgeMissile[missile].orb = false
endif
if op == 2 then
set missile.damage = missile.damage * 0.50
endif
set missile.speed = 40.00
set missile.collision = SPILL_AREA
set missile.model = MISSILE_SFX
set missile.scale = 2.0
set missile.data = GetUnitUserData(target)
call SilentEdgeMissile.launch(missile)
call VileTricks_VileTricksApply.evaluate(source)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,BUFF_DURATION,SilentEdge.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer dt
local Buff b
if data.dmgType == udg_DamageTypeAttack and not data.isMiss then
if UnitHasBuff(data.source,SilentEdge.buff) and not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) then
call UnitRemoveBuff(data.source,SilentEdge.buff)
call SetupMissile(data.source,data.target,data.damageMod,1)
endif
set b = GetUnitBuff(data.source,VileTricks.buff)
if b != 0 then
if IsUpgradeSuperior(b.owner,'SAI2') then
if GetRandomInt(1,100) <= b.stacks * 4 and data.mainAttack and data.codeDmg.codeName != "SilentEdge" then
call SetupMissile(data.source,data.target,data.damageMod,2)
endif
endif
endif
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local SilentEdge b
if data.codeDmg.codeName == "BladeDance" then
set data.trueAttack = true
set data.trueCritical = true
set data.allowOrbs = true
if GetHeroMasteryType(data.source) == 1 then
set data.lifestealAdd = data.lifestealAdd + 0.40
endif
endif
if data.codeDmg.codeName == "SilentEdge" then
if GetHeroMasteryType(data.source) == 1 then
set data.lifestealAdd = data.lifestealAdd + 0.40
endif
endif
if data.dmgType == udg_DamageTypeAttack then
set b = GetUnitBuff(data.source,SilentEdge.buff).buffAllocIndex
if b != 0 then
if data.mainAttack then
set data.add = data.add + b.dmg
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SilentEdge.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ShadowSlayer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01A',PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope VileTricks initializer init
globals
private constant integer SPELL_ID = 'SAA2'
private constant integer UPGRADE_ID = 'SAI2'
private constant integer DAMAGE_INC_BASE = 5
private constant integer ATTACK_SPEED_BASE = 5
private constant real BUFF_DURATION = 15.00
private constant real UP_RESISTANCE_BASE = 5
endglobals
private function GetUpgradeResistance takes integer ulvl returns real
return UP_RESISTANCE_BASE + UP_RESISTANCE_BASE * ulvl
endfunction
private function GetDamageInc takes integer lvl returns integer
return DAMAGE_INC_BASE * lvl
endfunction
private function GetSpeedInc takes integer lvl returns integer
return ATTACK_SPEED_BASE * lvl
endfunction
struct VileTricksSecond extends array
integer dmg
integer speed
real res
integer qchance
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-speed,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-res,0)
set res = 0
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
if GetHeroMasteryType(b.owner) != 1 then
set dmg = GetDamageInc(b.level) / 2
set speed = GetSpeedInc(b.level) / 2
else
set dmg = R2I(GetDamageInc(b.level) * 1.5)
set speed = R2I(GetSpeedInc(b.level) * 1.5)
endif
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,speed,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
if ulvl != 0 then
set res = GetUpgradeResistance(ulvl)
if GetHeroMasteryType(b.owner) != 3 then
set res = res / 2
else
set res = res * 1.5
endif
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,res,0)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01D'
set BUFF_DATA.BuffID = 'B00M'
set BUFF_DATA.Name = "Vile Tricks Secondary"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct VileTricks extends array
integer dmg
integer speed
real res
public static method onStackRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-speed,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-res,0)
set res = 0
endif
endmethod
public static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set dmg = GetDamageInc(b.level)
set speed = GetSpeedInc(b.level)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,speed,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
if ulvl != 0 then
set res = GetUpgradeResistance(ulvl)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,res,0)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01C'
set BUFF_DATA.BuffID = 'B00L'
set BUFF_DATA.Name = "Vile Tricks"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_INDEPENDENT
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 99999
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
public function VileTricksApply takes unit u returns nothing
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if lvl != 0 then
call UnitAddBuff(u,u,BUFF_DURATION,VileTricks.buff,lvl,0)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
set d.activationType = ACTIVATION_TYPE_NONE
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call VileTricks.Initialize()
call VileTricksSecond.Initialize()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ShadowSlayer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01D',PRELOAD_SECOND)
call PreloadGen.Add('A01C',PRELOAD_SECOND)
endfunction
endscope
scope HatefulGlaive initializer init
globals
private constant integer SPELL_ID = 'SAA3'
private constant integer UPGRADE_ID = 'SAI3'
private constant integer EXTRA_ID = 'A06J'
private constant real PERIOD_DAMAGE_BASE = 20.00
private constant real PERIOD_DAMAGE_LEVEL = 5.00
private constant real SPILL_DISTANCE = 710.00
private constant real PERIOD = 0.50
private constant real STUN_DURATION = 0.80
private constant real MAX_DISTANCE = 1000.00
private constant real MISSILE_SPEED = 65.00
private constant real MISSILE_SCALE = 0.70
private constant real UP_CD_REDUCTION = 2.00
private constant string MISSILE_SFX = "war3mapImported\\IllidanMissile.mdx"
private constant string PERIOD_SFX = "Objects\\Spawnmodels\\Human\\HumanBlood\\HumanBloodFootman.mdl"
endglobals
private function GetDamagePeriod takes integer lvl returns real
return PERIOD_DAMAGE_BASE + PERIOD_DAMAGE_LEVEL * lvl
endfunction
struct HatefulGlaive extends array
real dmg
boolean dashed
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypePhysicalOverTime,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(PERIOD_SFX,b.target,"chest"))
if DistanceBetweenUnits(b.owner,b.target) >= MAX_DISTANCE then
set b.removeInside = true
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = GetDamagePeriod(b.level)
set dashed = false
call Status.Add(STATUS_STUN,b.target,STUN_DURATION,Status_EFFECT[STATUS_STUN])
endmethod
private static method onRemove takes Buff b returns nothing
call HatefulGlaive_SetupMissile.evaluate(b.target,b.owner,b.level,0)
call Status.Add(STATUS_STUN,b.target,STUN_DURATION,Status_EFFECT[STATUS_STUN])
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A019'
set BUFF_DATA.BuffID = 'B00K'
set BUFF_DATA.Name = "Hateful Glaive"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = PERIOD
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct HatefulGlaiveMissile extends array
private static method onFinish takes Missile missile returns boolean
if UnitAlive(missile.target) then
if missile.data == 1 then
if not TriggerSpellNegation(missile.target) then
if GetHeroMasteryType(missile.source) == 3 then
call UnitAddBuff(missile.target,missile.source,6,HatefulGlaive.buff,missile.level,0)
else
call UnitAddBuff(missile.target,missile.source,4,HatefulGlaive.buff,missile.level,0)
endif
endif
if TriggerSpellReflection(missile.target) then
call HatefulGlaive_SetupMissile.evaluate(missile.target,missile.source,missile.level,1)
endif
endif
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer level, integer option returns Missile
local real x = GetUnitX(source)
local real y = GetUnitY(source)
local real xt = GetUnitX(target)
local real yt = GetUnitY(target)
local real angle = Angle(x,y,xt,yt)
local Missile missile = Missile.create(x,y,50.0,angle,0,50.0)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.target = target
set missile.level = level
set missile.speed = MISSILE_SPEED
set missile.model = MISSILE_SFX
set missile.scale = MISSILE_SCALE
set missile.data = option
call HatefulGlaiveMissile.launch(missile)
return missile
endfunction
struct Dash extends array
boolean sb
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local unit t = GetUnitByIndex(b.int)
local real a = AngleBetweenUnits(b.target,t)
local real x = GetUnitX(t)
local real y = GetUnitY(t)
local real xm = GetUnitX(b.target) + 35 * Cos(a)
local real ym = GetUnitY(b.target) + 35 * Sin(a)
local integer lvl
call SetUnitX(b.target,xm)
call SetUnitY(b.target,ym)
call SetUnitFacing(b.target,a * bj_RADTODEG)
if GetUnitCurrentOrder(b.target) != ORDER_fingerofdeath then
set b.removeInside = true
else
if Distance(x,y,xm,ym) <= 100 then
set lvl = GetUnitAbilityLevel(b.target,'SAA1')
if lvl != 0 and b.level != -1 then
call UnitAddBuff(b.target,b.target,3.00,SilentEdge.buff,lvl,0)
endif
call IssueTargetOrderById(b.target,ORDER_attack,t)
set b.int = 1
set b.removeInside = true
endif
endif
set t = null
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_UNPATH,b.target)
if b.int == 0 then
call IssueImmediateOrderById(b.target,ORDER_stop)
endif
call UnitRemoveAbility(b.target,'A06I')
call SetUnitVertexColor(b.target,255,255,255,255)
if sb then
call Status.Remove(STATUS_SPELL_IMMUNITY,b.target)
set sb = false
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Add(STATUS_UNPATH,b.target,0,0)
call UnitAddAbility(b.target,'A06I')
call UnitMakeAbilityPermanent(b.target,true,'A06I')
call SetUnitAnimationByIndex(b.target,8)
call SetUnitVertexColor(b.target,125,125,125,175)
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set sb = true
call Status.Add(STATUS_SPELL_IMMUNITY,b.target,0,Status_EFFECT[STATUS_SPELL_IMMUNITY])
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Dash"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(-UP_CD_REDUCTION)
endif
if up.upID == 'SAI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 2 then
call BlzSetUnitAbilityCooldown(up.ownerHero.hero,EXTRA_ID,0,3.0)
endif
endif
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
if GetLearnedSkillLevel() == 1 then
call UnitAddAbility(u,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local unit rand = null
call SetupMissile(u,t,GetUnitAbilityLevel(u,SPELL_ID),1)
if GetHeroMasteryType(u) == 3 then
set rand = GetRandomEnemyHeroInAreaExcept(GetOwningPlayer(u),GetUnitX(t),GetUnitY(t),500,t)
if rand != null then
call SetupMissile(u,rand,GetUnitAbilityLevel(u,SPELL_ID),1)
endif
endif
set u = null
set t = null
endfunction
private function onCastExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local boolean m = GetHeroMasteryType(u) == 2
local HatefulGlaive b = GetUnitBuff(t,HatefulGlaive.buff).buffAllocIndex
if b != 0 or m then
if not b.dashed or m then
set b.dashed = true
call UnitAddBuff(u,u,9999,Dash.buff,GetUnitAbilityLevel(u,SPELL_ID),GetUnitUserData(t))
else
call Message.ShowToPlayer(GetTriggerPlayer(),"This unit was already striked.",MESSAGE_STYLE_ERROR)
endif
else
call Message.ShowToPlayer(GetTriggerPlayer(),"This unit does not have the Hateful Glaive.",MESSAGE_STYLE_ERROR)
call UnitRemoveAbility(u,EXTRA_ID)
call UnitAddAbility(u,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
endif
set t = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call HatefulGlaive.Initialize()
call Dash.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCastExtra)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ShadowSlayer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(EXTRA_ID,PRELOAD_SECOND)
call PreloadGen.Add('A019',PRELOAD_SECOND)
endfunction
endscope
scope BladeDance initializer init
globals
private constant integer SPELL_ID = 'SAA4'
private constant integer UPGRADE_ID = 'SAI4'
private constant real DAMAGE_END_BASE = 120.00
private constant real DAMAGE_END_LEVEL = 100.00
private constant real AGI_BONUS_BASE = 1.00
private constant real SLASH_DELAY = 0.50
private constant real UP_AREA = 400
private constant string TARGET_SFX = "war3mapImported\\ShadowAssault.mdx"
private constant string SLASH_SFX = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"
private constant string HIDE_SFX = "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl"
endglobals
private function GetDamageFinish takes integer lvl returns real
return DAMAGE_END_BASE + DAMAGE_END_LEVEL * lvl
endfunction
private function callback takes nothing returns nothing
local Table tb = GetTimerData(GetExpiredTimer())
local unit u = tb.unit[0]
local unit t = tb.unit[1]
local real count = tb.real[2]
local integer slash = tb.integer[3]
local real angle = tb.real[4]
local real delay = tb.real[5]
local real dmg = tb.real[6]
local real x = tb.real[7]
local real y = tb.real[8]
local unit dummy = tb.unit[9]
local real a
local group g
local unit temp
local player p
set delay = delay - 0.03125
set tb.real[5] = delay
if delay <= 0.00 then
if delay == 0.00 then
call DestroyEffect(AddSpecialEffect(HIDE_SFX,GetUnitX(u),GetUnitY(u)))
call Status.Add(STATUS_HIDE,u,0,0)
endif
if count == 0.00 then
if slash == 1 then
set angle = 45.00
set angle = angle * bj_RADTODEG
set tb.real[4] = angle
set x = GetUnitX(t) - 250 * Cos(angle)
set y = GetUnitY(t) - 250 * Sin(angle)
set tb.real[7] = x
set tb.real[8] = y
endif
if slash == 2 then
set angle = 135
set angle = angle * bj_RADTODEG
set tb.real[4] = angle
set x = GetUnitX(t) - 250 * Cos(angle)
set y = GetUnitY(t) - 250 * Sin(angle)
set tb.real[7] = x
set tb.real[8] = y
endif
endif
call SetUnitX(u,GetUnitX(t))
call SetUnitY(u,GetUnitY(t))
call SetUnitX(dummy,GetUnitX(t))
call SetUnitY(dummy,GetUnitY(t))
set x = x + 31.25 * Cos(angle)
set y = y + 31.25 * Sin(angle)
call DestroyEffect(AddSpecialEffect(SLASH_SFX,x,y))
set tb.real[7] = x
set tb.real[8] = y
set count = count + 0.03125
if count >= SLASH_DELAY then
set tb.real[2] = 0.00
set tb.integer[3] = slash + 1
if slash + 1 == 3 then
set x = GetUnitX(t)
set y = GetUnitY(t)
call RemoveUnit(dummy)
call Status.Remove(STATUS_HIDE,u)
call Status.Remove(STATUS_PAUSE,u)
call Status.Remove(STATUS_INVULNERABLE,u)
call SelectUnitForPlayer(u,GetOwningPlayer(u),true)
call SetUnitVertexColor(u,255,255,255,255)
call IssueTargetOrder(u,"attack",t)
call CodeDamage.Damage(u,t,dmg,udg_DamageTypeAttack,"BladeDance",0,0)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,t,"origin"))
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set g = NewGroup()
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,x,y,UP_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and temp != t then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeAttack,"BladeDance",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
call tb.flush()
call tb.destroy()
call ReleaseTimer(GetExpiredTimer())
endif
else
set tb.real[2] = count
endif
endif
set u = null
set t = null
set dummy = null
endfunction
private function SpellTrigger takes unit u, unit t returns nothing
local Table tb = Table.create()
local timer ti = NewTimerEx(tb)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
set tb.unit[0] = u
set tb.unit[1] = t
set tb.real[2] = 0.00
set tb.integer[3] = 1
set tb.real[5] = 1.00
set tb.real[6] = GetDamageFinish(lvl) + GetHeroAgi(u,true) * AGI_BONUS_BASE
set tb.unit[9] = CreateUnit(GetOwningPlayer(u),'h00O',GetUnitX(u),GetUnitY(u),0)
call Status.Add(STATUS_INVULNERABLE,u,0,0)
call Status.Add(STATUS_PAUSE,u,0,0)
call UnitDispelAllBuffs(u,BUFF_TYPE_NEGATIVE)
call SetUnitAnimation(u,"morph")
call TimerStart(ti,0.03125,true,function callback)
set ti = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,ShadowSlayer_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library LizardArcher initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HLM1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'LMI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Snake Arrows"
set up.Text = "Increases |c00b4b4b4Chameleon Shot|r base damage on enemies with less than 25% of his Hp."
set up.SupText = "|c00b4b4b4Chameleon Shot|r deals |c00ee82eePure Damage|r."
set up.LevelData1 = "+20 Damage"
set up.LevelData2 = "+40 Damage"
set up.LevelData3 = "+60 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'LMI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Master Training"
set up.Text = "Improves |c00b4b4b4Lylia's|r |c00ffff95Attack Damage|r, |c00ffff95Movement Speed|r and |c00ffff95Armor|r."
set up.SupText = "Increases Lylia's Hp by 1000."
set up.LevelData1 = "+10 Damage 20 MS and 2 Armor"
set up.LevelData2 = "+20 Damage 30 MS and 4 Armor"
set up.LevelData3 = "+30 Damage 40 MS and 6 Armor"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'LMI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Reptile Regeneration"
set up.Text = "Increases |c00b4b4b4Guardian Cobra|r periodic |c0000ff00Healing|r."
set up.SupText = "Increases the duration of the reflected effect by 50%."
set up.LevelData1 = "+5 Heal"
set up.LevelData2 = "+10 Heal"
set up.LevelData3 = "+15 Heal"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTN1ThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'LMI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Scaled Bark"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HLM1'
set d.Name = "Lizard Archer"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNNightElfRanger.blp"
set d.WinAni = "stand victory"
set d.Block = 0
set d.Evasion = 40
set d.Resistance = 40
set d.LifeRegen = 0.5
set d.ManaRegen = 1.0
set d.Armor = 2
set d.AttackRange = 560
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'LMA1'
set d.HeroAbility2 = 'LMA2'
set d.HeroAbility3 = 'LMA3'
set d.HeroAbility4 = 'LMA4'
set d.ChooseIconID = 'c015'
set d.ChooseDummy = 'dh15'
set d.spellDamageLevel = 4
set d.attackDamageLevel = 5
set d.healingLevel = 5
set d.survivavilityLevel = 7
set d.movementLevel = 2
set d.crowdControlLevel = 7
set d.HeroFaction = Game.FACTION_NIGHTELF
set d.InfoID = 'HLAI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ChameleonShot initializer init
globals
private constant integer SPELL_ID = 'LMA1'
private constant integer UPGRADE_ID = 'LMI1'
private constant real BUFF_DURATION = 2.00
private constant real DAMAGE_BASE = 90.00
private constant real DAMAGE_LEVEL = 30.00
private constant real SLOW_MS_BASE = 0.45
private constant real RESTORE_PERCENT_BASE = 0.75
private constant real UP_DAMAGE_BASE = 20.00
private constant string MISSILE_SFX = "war3mapImported\\BonefireArrow1.mdx"
private constant real MISSILE_SPEED = 30.00
private constant real MISSILE_SCALE = 1.80
private constant integer CF_MAX_UNITS = 2
private constant real CF_AREA_BASE = 200.00
private constant real CF_AREA_LEVEL = 50.00
endglobals
private function GetCFArea takes integer lvl returns real
return CF_AREA_BASE + CF_AREA_LEVEL * lvl
endfunction
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetUpgradeDamage takes integer ulvl returns real
return UP_DAMAGE_BASE * ulvl
endfunction
struct ChameleonShot extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-SLOW_MS_BASE,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01Z'
set BUFF_DATA.BuffID = 'B00Z'
set BUFF_DATA.Name = "Chameleon Shot"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct ChameleonShotMissile extends array
private static method onFinish takes Missile missile returns boolean
local integer ulvl
if not TriggerSpellNegation(missile.target) then
set ulvl = GetUpgradeSkillLevel(missile.source,UPGRADE_ID)
if ulvl != 0 then
if GetUnitLifePercent(missile.target) < 25 then
set missile.damage = missile.damage + GetUpgradeDamage(ulvl)
endif
endif
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypePure,"ChameleonShot",0,0)
else
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypePhysical,"ChameleonShot",0,0)
endif
call UnitAddBuff(missile.target,missile.source,BUFF_DURATION,ChameleonShot.buff,missile.level,0)
endif
if TriggerSpellReflection(missile.target) then
call ChameleonShot_SetupMissile.evaluate(missile.target,missile.source,missile.level)
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl returns Missile
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real a = Angle(xs,ys,GetUnitX(target),GetUnitY(target))
local Missile missile = Missile.create(xs,ys,75.00,a,20.00,75.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl)
set missile.speed = MISSILE_SPEED
set missile.level = lvl
set missile.model = MISSILE_SFX
set missile.scale = MISSILE_SCALE
call ChameleonShotMissile.launch(missile)
return missile
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local real life
local real mana
local real add
local integer id
local unit pet
if data.codeDmg.codeName == "ChameleonShot" and not data.isAbsorbed then
set add = (data.damageMod * RESTORE_PERCENT_BASE)
set id = GetUnitData(data.source,"Lylia")
set pet = GetUnitByIndex(id)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl",data.source,"overhead"))
call CodeDamage.Damage(data.source,data.source,add,udg_DamageTypeHeal,"",0,0)
if id != 0 and UnitAlive(pet) then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl",pet,"overhead"))
call CodeDamage.Damage(data.source,pet,add * 2,udg_DamageTypeHeal,"",0,0)
endif
set pet = null
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local group g
local integer c
local real a
local Buff b
local player p
local unit temp
if UnitHasBuff(u,CrocodileFangs.buff) then
set b = GetUnitBuff(u,CrocodileFangs.buff)
set g = NewGroup()
set c = CF_MAX_UNITS
set a = GetCFArea(b.level)
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,GetUnitX(t),GetUnitY(t),a,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null or c == 0
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and temp != t and c != 0 then
set c = c - 1
call SetupMissile(u,temp,lvl)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set temp = null
endif
call SetupMissile(u,t,lvl)
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ChameleonShot.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDamage(Filter(function OnDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,LizardArcher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01Z',PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope SummonLylia initializer init
globals
private constant integer SPELL_ID = 'LMA2'
private constant integer UPGRADE_ID = 'LMI2'
private constant integer SUMMON_ID = 'n00W'
private constant integer TP_ID = 'A06O'
private constant integer HP_LEVEL = 500
private constant string SUMMON_SFX = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl"
endglobals
private function GetHpBonus takes integer lvl returns integer
return HP_LEVEL * lvl
endfunction
private function StartingAttributes takes unit u returns nothing
local Ability a
set a = Ability.create(AbilityData.GetDataByID('LYA1'),u)
call a.updateTooltip(true)
set a = Ability.create(AbilityData.GetDataByID('LYA2'),u)
call a.updateTooltip(true)
set a = Ability.create(AbilityData.GetDataByID('LYA3'),u)
call a.updateTooltip(true)
set a = Ability.create(AbilityData.GetDataByID('A06O'),u)
call a.updateTooltip(true)
call BlzUnitDisableAbility(u,'LYA3',true,true)
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local unit pet
if up.upID == UPGRADE_ID then
call SetPlayerTechResearched(GetOwningPlayer(up.ownerHero.hero),'R000',up.level)
endif
if up.upID == 'LMI4' then
if up.level == 1 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
if a != 0 then
call a.addFlatCooldown(-15.00)
endif
endif
if GetHeroMasteryType(up.ownerHero.hero) == 3 then
set pet = GetUnitByIndex(GetUnitData(up.ownerHero.hero,"Lylia"))
if pet != null then
call BlzSetUnitWeaponIntegerField(pet,UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE,0,6)
call BlzSetUnitIntegerField(pet,UNIT_IF_DEFENSE_TYPE,5)
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(-60)
call a.addManaCost(-75,0)
endif
endif
if GetHeroMasteryType(up.ownerHero.hero) == 1 then
set pet = GetUnitByIndex(GetUnitData(up.ownerHero.hero,"Lylia"))
if pet != null then
call UnitAddAbility(pet,'A06M')
call UnitMakeAbilityPermanent(pet,true,'A06M')
endif
call UnitAddAbility(up.ownerHero.hero,'A06M')
call UnitMakeAbilityPermanent(up.ownerHero.hero,true,'A06M')
endif
endif
if up.upID == 'LMI2' then
if IsUpgradeSuperior(up.ownerHero.hero,'LMI2') then
set pet = GetUnitByIndex(GetUnitData(up.ownerHero.hero,"Lylia"))
if pet != null then
call BlzSetUnitMaxHP(pet,BlzGetUnitMaxHP(pet) + 1000)
endif
endif
endif
set pet = null
endfunction
private function onCastExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit s = GetUnitByIndex(GetUnitData(u,"Alcira"))
local real x
local real y
local real a
if s != null then
set a = GetUnitFacing(s) * bj_DEGTORAD
set x = GetUnitX(s) + 100 * Cos(a)
set y = GetUnitY(s) + 100 * Sin(a)
call SetUnitX(u,x)
call SetUnitY(u,y)
call DestroyEffect(AddSpecialEffect(SUMMON_SFX,x,y))
endif
set u = null
set s = null
endfunction
private function OnDeath takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer id = GetUnitTypeId(u)
local effect sfx
if id == SUMMON_ID then
call ShowUnit(u,false)
set sfx = AddSpecialEffect("units\\creeps\\ThunderLizardVizier\\ThunderLizardVizier.mdx",GetUnitX(u),GetUnitY(u))
call BlzSetSpecialEffectYaw(sfx,GetUnitFacing(u) * bj_DEGTORAD)
call BlzSetSpecialEffectScale(sfx,0.80)
call DestroyEffect(sfx)
set sfx = null
call SetUnitX(u,GetPlayerStartLocationX(GetOwningPlayer(u)))
call SetUnitY(u,GetPlayerStartLocationY(GetOwningPlayer(u)))
endif
if id == 'HLM1' then
call KillUnit(GetUnitByIndex(GetUnitData(u,"Lylia")))
endif
set u = null
return false
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real a = GetUnitFacing(u) * bj_DEGTORAD
local real x = GetUnitX(u) + 100 * Cos(a)
local real y = GetUnitY(u) + 100 * Sin(a)
local unit s = GetUnitByIndex(GetUnitData(u,"Lylia"))
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local integer blvl
local real h
local trigger t
if s == null then
set s = CreateUnit(GetOwningPlayer(u),SUMMON_ID,x,y,a * bj_RADTODEG)
call SetUnitData(u,"Lylia",GetUnitUserData(s))
call SetUnitData(s,"Alcira",GetUnitUserData(u))
call SetUnitData(s,"LyliaLvl",lvl)
call LockIndex(s,true)
call StartingAttributes(s)
if GetPlayerController(GetOwningPlayer(u)) == MAP_CONTROL_COMPUTER then
set AILA.pet = s
call RemoveGuardPosition(s)
endif
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_DEATH)
call TriggerRegisterUnitEvent(t,s,EVENT_UNIT_DEATH)
call TriggerAddCondition(t,function OnDeath)
set t = null
else
set blvl = GetUnitData(s,"LyliaLvl")
if not UnitAlive(s) then
call ShowUnit(s,true)
call ReviveUnit(s)
else
call SetUnitState(s,UNIT_STATE_LIFE,99999)
endif
call SetUnitX(s,x)
call SetUnitY(s,y)
call BlzSetUnitFacingEx(s,a * bj_RADTODEG)
call IssueImmediateOrder(s,"stop")
if lvl != blvl then
call SetUnitData(s,"LyliaLvl",lvl)
endif
endif
if GetHeroMasteryType(u) == 1 then
call UnitAddAbility(s,'A06M')
call UnitMakeAbilityPermanent(s,true,'A06M')
endif
set h = GetHpBonus(lvl) - (GetUnitState(s,UNIT_STATE_MAX_LIFE) - 1000)
if IsUpgradeSuperior(u,'LMI2') then
set h = h + 1000
endif
if h != 0 then
call BonusStruct.Add(BONUS_TYPE_HP,s,R2I(h),0,false)
endif
call DestroyEffect(AddSpecialEffect(SUMMON_SFX,x,y))
call SetUnitAbilityLevel(s,'LYA1',lvl)
call SetUnitAbilityLevel(s,'LYA2',lvl)
set s = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d = AbilityData.create()
set d.objectID = TP_ID
set d.hotkey = "F"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(TP_ID, function onCastExtra)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,LizardArcher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(SUMMON_ID,PRELOAD_UNIT)
call PreloadGen.Add('A06M',PRELOAD_UNIT)
call Preload(SUMMON_SFX)
endfunction
endscope
scope Nibble initializer init
globals
private constant integer SPELL_ID = 'LYA1'
private constant real BUFF_DURATION = 4.00
private constant real DAMAGE_BASE = 20.00
private constant real DAMAGE_LEVEL = 10.00
private constant real STUN_DURATION = 1.50
private constant string TARGET_SFX = "Abilities\\Weapons\\HydraliskImpact\\HydraliskImpact.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct Nibble extends array
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,b.target,"chest"))
call CodeDamage.Damage(b.owner,b.target,GetDamage(b.level),udg_DamageTypePhysical,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Add(STATUS_STUN,b.target,STUN_DURATION,Status_EFFECT[STATUS_STUN])
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A020'
set BUFF_DATA.BuffID = 'B010'
set BUFF_DATA.Name = "Nibble"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u,unit t returns nothing
call UnitAddBuff(t,u,BUFF_DURATION,Nibble.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Nibble.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,LizardArcher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A020',PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
scope WildCharge initializer init
globals
private constant integer SPELL_ID = 'LYA2'
private constant real DAMAGE_INC_BASE = 0.40
private constant real BUFF_DURATION = 8.00
private constant integer AS_BONUS_BASE = 25
private constant integer AS_BONUS_LEVEL = 10
private constant real MAX_DISTANCE = 1000.00
private constant string PATH_SFX = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
endglobals
private function GetASBonus takes integer lvl returns integer
return AS_BONUS_BASE + AS_BONUS_LEVEL * lvl
endfunction
struct WildCharge extends array
integer as
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = GetASBonus(b.level)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A021'
set BUFF_DATA.BuffID = 'A011'
set BUFF_DATA.Name = "Wild Charge"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function callback takes nothing returns nothing
local Table tb = GetTimerData(GetExpiredTimer())
local unit u = tb.unit[0]
local real a = tb.real[1]
local real d = tb.real[2]
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local integer sw = 0
local integer lvl
local unit hero
local group g
local unit temp
local group g2
local player p
if d > 100.0 then
call DestroyEffect(AddSpecialEffect(PATH_SFX,x,y))
set x = x + 23.00 * Cos(a)
set y = y + 23.00 * Sin(a)
set d = d - 23.00
call SetUnitX(u,x)
call SetUnitY(u,y)
call SetUnitFacing(u,a * bj_RADTODEG)
set tb.real[2] = d
set g = NewGroup()
set g2 = tb.group[3]
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,x,y,170,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitInGroup(temp,g2) then
call GroupAddUnit(g2,temp)
call KPJUnit.create(temp,140,a,1.0,0,KPJDefaultConfig2,KPJ_TYPE_KNOCKBACK)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
else
set sw = 1
endif
if d <= 100.00 or sw == 1 or GetUnitCurrentOrder(u) != ORDER_rainoffire then
set hero = GetUnitByIndex(GetUnitData(u,"Alcira"))
set lvl = GetUnitAbilityLevel(u,SPELL_ID)
call UnitAddBuff(u,u,BUFF_DURATION,WildCharge.buff,lvl,0)
call UnitAddBuff(hero,hero,BUFF_DURATION,WildCharge.buff,lvl,0)
call UnitRemoveType(u,UNIT_TYPE_PEON)
call IssueImmediateOrderById(u,ORDER_stop)
set AILA.petOrder = 0
call SetUnitTimeScale(u,1.0)
call SetUnitAnimation(u,"attack")
call ReleaseTimer(GetExpiredTimer())
call ReleaseGroup(tb.group[3])
call tb.flush()
call tb.destroy()
endif
set u = null
set hero = null
endfunction
private function OnPostDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer id1
local integer id2
local unit hero
local unit pet
local real sd
local integer sw = 0
local Ability a
if not data.isAbsorbed and data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if GetUnitAbilityLevel(data.target,'A06M') != 0 and not IsUnitIllusion(data.target) then
set id1 = GetUnitData(data.target,"Alcira")
set id2 = GetUnitData(data.target,"Lylia")
if id2 != 0 then
//heroe
set hero = data.target
set pet = GetUnitByIndex(id2)
set sd = 0.30
set sw = 1
elseif id1 != 0 then
//pet
set hero = GetUnitByIndex(id1)
set pet = data.target
set sd = 0.30
set sw = 2
endif
endif
if sw != 0 then
if sd != 0 then
if sw == 1 then
call UnitRemoveHp(pet,data.damageMod * sd)
set data.damageMod = data.damageMod - data.damageMod * sd
elseif sw == 2 then
call UnitRemoveHp(hero,data.damageMod * sd)
set data.damageMod = data.damageMod - data.damageMod * sd
endif
endif
endif
if data.dmgType == udg_DamageTypeAttack and not data.isMiss and not data.isBlock then
if GetUnitAbilityLevel(data.source,'LMA2') != 0 then
set pet = GetUnitByIndex(GetUnitData(data.source,"Lylia"))
if BlzGetUnitAbilityCooldownRemaining(pet,SPELL_ID) != 0 and GetHeroMasteryType(data.source) == 2 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,pet)
if a != 0 then
call a.addCooldownRemaining(-1.0)
endif
endif
endif
endif
set hero = null
set pet = null
endif
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
if UnitHasBuff(data.source,WildCharge.buff) then
set data.mult = data.mult + DAMAGE_INC_BASE
endif
if data.dmgType != udg_DamageTypeAttack then
if UnitHasBuff(data.source,RoyalShout.buff) then
set data.mult = data.mult - 0.25
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local Table tb = Table.create()
local timer ti = NewTimerEx(tb)
local unit h = GetUnitByIndex(GetUnitData(u,"Alcira"))
set tb.unit[0] = u
set tb.real[1] = Angle(GetUnitX(u),GetUnitY(u),x,y)
set tb.real[2] = 1000
set tb.group[3] = NewGroup()
call SetUnitAnimationByIndex(u,7)
call SetUnitTimeScale(u,2.0)
call UnitAddType(u,UNIT_TYPE_PEON)
call TimerStart(ti,0.03125,true,function callback)
set ti = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call WildCharge.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call DamageEvent.RegisterPostCalculation(Filter(function OnPostDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,LizardArcher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A022',PRELOAD_SECOND)
call PreloadGen.Add('A021',PRELOAD_SECOND)
call Preload(PATH_SFX)
endfunction
endscope
scope RoyalShout initializer init
globals
public constant integer SPELL_ID = 'LYA3'
private constant real BUFF_DURATION = 4.00
private constant real AREA = 350.00
endglobals
struct RoyalShout extends array
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01S'
set BUFF_DATA.BuffID = 'B00S'
set BUFF_DATA.Name = "Royal Shout"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local unit temp
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call UnitAddBuff(temp,u,BUFF_DURATION,RoyalShout.buff,0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RoyalShout.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,LizardArcher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01S',PRELOAD_SECOND)
endfunction
endscope
scope GuardianCobra initializer init
globals
private constant integer SPELL_ID = 'LMA3'
private constant integer UPGRADE_ID = 'LMI3'
private constant integer DUMMY_ID = 'h00D'
private constant real BUFF_DURATION = 4.00
private constant real HP_REGEN_BASE = 10.00
private constant real HP_REGEN_LEVEL = 5.00
private constant real AREA = 650.00
private constant real UP_HOT_BASE = 5.00
private constant string MISSILE_SFX = "Abilities\\Weapons\\SerpentWardMissile\\SerpentWardMissile.mdl"
endglobals
private function GetHeal takes integer lvl returns real
return HP_REGEN_BASE + HP_REGEN_LEVEL * lvl
endfunction
struct GuardianCobraMissile extends array
integer status
real duration
Effect sfxData
private static method onFinish takes Missile missile returns boolean
local thistype this = thistype[missile]
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
set duration = duration * 1.5
endif
call Status.Add(status,missile.target,duration,sfxData)
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, real x, real y, unit target, integer lvl, integer s, real d, Effect sfx returns Missile
local real a = Angle(x,y,GetUnitX(target),GetUnitY(target))
local Missile missile = Missile.create(x,y,250.00,a,20.00,50.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.speed = 25.00
set missile.level = lvl
set missile.model = MISSILE_SFX
set missile.scale = 1.3
call SetUnitVertexColor(missile.dummy,255,0,255,255)
set GuardianCobraMissile[missile].status = s
set GuardianCobraMissile[missile].duration = d
set GuardianCobraMissile[missile].sfxData = sfx
call GuardianCobraMissile.launch(missile)
return missile
endfunction
struct GuardianCobraHeal extends array
real heal
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,heal,udg_DamageTypeHealOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set heal = GetHeal(b.level) + UP_HOT_BASE * GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A023'
set BUFF_DATA.BuffID = 'B013'
set BUFF_DATA.Name = "Guardian Cobra Heal"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
struct GuardianCobra extends array
unit dummy
boolean done
boolean hiden
public method attack takes integer s, real d, Effect sfx returns nothing
local Buff b = thisBuff
local integer id
local group g = NewGroup()
local player p = GetOwningPlayer(b.target)
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local unit temp
call GroupEnumUnitsInRange(g,x,y,AREA,null)
set done = true
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and IsUnitType(temp,UNIT_TYPE_HERO) then
call SetupMissile(b.target,x,y,temp,b.level,s,d,sfx)
endif
endloop
call ReleaseGroup(g)
call SetUnitAnimation(dummy,"attack")
call UnitApplyTimedLife(dummy,'BTLF',1.00)
call UnitAddBuff(b.target,b.target,4.0,GuardianCobraHeal.buff,b.level,0)
set id = GetUnitData(b.target,"Lylia")
if id != 0 then
set temp = GetUnitByIndex(id)
call UnitAddBuff(temp,b.target,4.0,GuardianCobraHeal.buff,b.level,0)
endif
set p = null
set g = null
set temp = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call SetUnitX(dummy,GetUnitX(b.target))
call SetUnitY(dummy,GetUnitY(b.target))
call SetUnitFacing(dummy,GetUnitFacing(b.target))
if IsUnitHidden(b.target) then
if not hiden then
call UnitRemoveAbility(dummy,'Aloc')
call ShowUnit(dummy,false)
set hiden = true
endif
else
if hiden then
set hiden = false
call ShowUnit(dummy,true)
call UnitAddAbility(dummy,'Aloc')
endif
endif
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local unit temp
if done then
set dummy = null
else
call UnitApplyTimedLife(dummy,'BTLF',0.01)
set dummy = null
endif
set temp = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dummy = CreateUnit(GetOwningPlayer(b.target),DUMMY_ID,GetUnitX(b.target),GetUnitY(b.target),GetUnitFacing(b.target))
set done = false
set hiden = false
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Guardian Cobra"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
call UnitAddBuff(u,u,BUFF_DURATION,GuardianCobra.buff,lvl,0)
set u = null
endfunction
private function onStatus takes nothing returns nothing
local StatusObject s = EVENT_STATUS
local Buff b = GetUnitBuff(s.target,GuardianCobra.buff)
if b != 0 and not s.permanent and s.status <= 12 then
if not GuardianCobra[b.buffAllocIndex].done then
call GuardianCobra[b.buffAllocIndex].attack(s.status,s.duration,s.sfxData)
call b.remove()
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call GuardianCobra.Initialize()
call GuardianCobraHeal.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUnitStatusEvent(function onStatus)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,LizardArcher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A023',PRELOAD_SECOND)
endfunction
endscope
scope CrocodileFangs initializer init
globals
private constant integer SPELL_ID = 'LMA4'
private constant integer UPGRADE_ID = 'LMI4'
private constant real BUFF_DURATION = 20.00
private constant real UP_BUFF_DURATION = 5.00
private constant integer DAMAGE_BONUS_BASE = 20
endglobals
private function GetDamageBonus takes integer lvl returns integer
return DAMAGE_BONUS_BASE * lvl
endfunction
struct CrocodileFangs extends array
integer dmg
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local unit l = GetUnitByIndex(GetUnitData(b.target,"Lylia"))
if l != null then
call BlzUnitDisableAbility(l,'LYA3',true,true)
endif
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
set l = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local unit l = GetUnitByIndex(GetUnitData(b.target,"Lylia"))
set dmg = GetDamageBonus(b.level)
if l != null then
call BlzUnitDisableAbility(l,'LYA3',false,false)
endif
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
set l = null
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A024'
set BUFF_DATA.BuffID = 'B014'
set BUFF_DATA.Name = "Crocodile Fangs"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = BUFF_DURATION
local integer id = GetUnitData(u,"Lylia")
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set d = d + UP_BUFF_DURATION
endif
call UnitAddBuff(u,u,d,CrocodileFangs.buff,lvl,0)
if id != 0 then
call UnitAddBuff(GetUnitByIndex(id),u,d,CrocodileFangs.buff,lvl,0)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call CrocodileFangs.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,LizardArcher_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A024',PRELOAD_SECOND)
endfunction
endscope
library MoonMistress initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HMM1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'MMI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Night Imprisonment"
set up.Text = "Increases |c00b4b4b4Lunar Ring|r area of effect."
set up.SupText = "Increases |c00b4b4b4Lunar Ring|r |c0000ced1Ensnare|r duration by 1 second during night."
set up.LevelData1 = "+50 Area of Effect"
set up.LevelData2 = "+100 Area of Effect"
set up.LevelData3 = "+150 Area of Effect"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWisp.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'MMI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Skywrath"
set up.Text = "Increases |c00b4b4b4Starfall|r damage during night."
set up.SupText = "Adds 2 waves count to |c00b4b4b4Starfall|r ."
set up.LevelData1 = "+15% Damage"
set up.LevelData2 = "+20% Damage"
set up.LevelData3 = "+25% Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWispSplode.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'MMI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Night's Judgement"
set up.Text = "|c00b4b4b4Moon Fire|r passive reduces Resistance."
set up.SupText = "Increases |c00b4b4b4Moon Fire|r debuff duration by 2 seconds."
set up.LevelData1 = "+20(3.1%) Resistance"
set up.LevelData2 = "+40(6.2%) Resistance"
set up.LevelData3 = "+60(9.3%) Resistance"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNReplenishHealth.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'MMI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Elune's Blessing"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HMM1'
set d.Name = "Moon Mistress"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNVicaressofElune.blp"
set d.WinAni = "spell"
set d.Block = 0
set d.Evasion = 10
set d.Resistance = 40
set d.LifeRegen = 1.0
set d.ManaRegen = 2.0
set d.Armor = 1
set d.AttackRange = 500
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'MMA1'
set d.HeroAbility2 = 'MMA2'
set d.HeroAbility3 = 'MMA3'
set d.HeroAbility4 = 'MMA4'
set d.ChooseIconID = 'c022'
set d.ChooseDummy = 'dh22'
set d.spellDamageLevel = 8
set d.attackDamageLevel = 1
set d.healingLevel = 0
set d.survivavilityLevel = 2
set d.movementLevel = 2
set d.crowdControlLevel = 7
set d.HeroFaction = Game.FACTION_NIGHTELF
set d.InfoID = 'HMMI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope LunarRing initializer init
globals
private constant integer SPELL_ID = 'MMA1'
private constant integer UPGRADE_ID = 'MMI1'
private constant real AREA_OF_EFFECT = 250.00
private constant real DAMAGE_BASE = 70.00
private constant real DAMAGE_LEVEL = 30.00
private constant real STUN_DURATION = 2.00
private constant real SHRIK_DELAY = 1.20
private constant real UP_CD_REDUCTION = 1.00
private constant real SUP_STUN = 1.00
private constant string AREA_SFX = "war3mapImported\\Moon Disc Floor.mdx"
Effect MM_EFFECT
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local real time = tb.real[3]
local real size
local real td
local real x
local real y
local real xt
local real yt
local unit u
local real area
local effect sfx
local real sd
local unit rand
if time >= SHRIK_DELAY then
set u = tb.unit[0]
set x = tb.real[1]
set y = tb.real[2]
set size = tb.real[4]
set sfx = tb.effect[5]
set area = tb.real[8]
set size = size - tb.real[10]
call BlzSetSpecialEffectScale(sfx,size)
set tb.real[4] = size
if tb.unit[6] == null then
set rand = GetRandomEnemyHeroInAreaExcept(GetOwningPlayer(u),x,y,area,null)
if rand != null then
set tb.unit[6] = rand
set xt = GetUnitX(rand)
set yt = GetUnitY(rand)
call KPJUnit.create(rand,Distance(x,y,xt,yt),Angle(xt,yt,x,y),0.50,0,KPJDefaultConfig,KPJ_TYPE_KNOCKBACK)
endif
endif
set td = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
set sd = STUN_DURATION
if IsUpgradeSuperior(u,UPGRADE_ID) and (td >= 18 or td < 6) then
set sd = sd + SUP_STUN
endif
if td >= 18 or td < 6 then
if tb.unit[7] == null then
set rand = GetRandomEnemyHeroInAreaExcept(GetOwningPlayer(u),x,y,area,tb.unit[6])
if rand != null then
set tb.unit[7] = rand
set xt = GetUnitX(rand)
set yt = GetUnitY(rand)
call KPJUnit.create(rand,Distance(x,y,xt,yt),Angle(xt,yt,x,y),0.50,0,KPJDefaultConfig,KPJ_TYPE_KNOCKBACK)
endif
endif
endif
set area = area - tb.real[9]
set tb.real[8] = area
if size <= 0 then
set rand = tb.unit[6]
if rand != null then
call CodeDamage.Damage(u,rand,GetDamage(GetUnitAbilityLevel(u,SPELL_ID)),udg_DamageTypeMagic,"LunarRing",0,0)
call Status.Add(STATUS_ENSNARE,rand,sd,MM_EFFECT)
endif
set rand = tb.unit[7]
if rand != null then
call CodeDamage.Damage(u,rand,GetDamage(GetUnitAbilityLevel(u,SPELL_ID)),udg_DamageTypeMagic,"LunarRing",0,0)
call Status.Add(STATUS_ENSNARE,rand,sd,MM_EFFECT)
endif
call DestroyEffect(AddSpecialEffect(AREA_SFX,x,y))
call ReleaseTimer(t)
call DestroyEffect(sfx)
call tb.flush()
call tb.destroy()
endif
set u = null
set sfx = null
set rand = null
else
set time = time + 0.03125
set tb.real[3] = time
endif
set t = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local Table tb = Table.create()
local timer t = NewTimerEx(tb)
local effect sfx = AddSpecialEffect(AREA_SFX,x,y)
local real a = AREA_OF_EFFECT + 50 * GetUpgradeSkillLevel(u,UPGRADE_ID)
call BlzSetSpecialEffectTimeScale(sfx,1.2)
call BlzSetSpecialEffectHeight(sfx,50.00 + GetLocZ(x,y))
set tb.unit[0] = u
set tb.real[1] = x
set tb.real[2] = y
set tb.real[3] = 0.00
set tb.real[4] = a / 64 * 0.5
call BlzSetSpecialEffectScale(sfx,tb.real[4])
set tb.effect[5] = sfx
set tb.unit[6] = null
set tb.unit[7] = null
set tb.real[8] = a
set tb.real[9] = a / 16
set tb.real[10] = tb.real[4] / 16
call TimerStart(t,0.03125,true,function Callback)
set u = null
set t = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local ability ab
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addAreaOfEffect(50)
endif
if up.upID == 'MMI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 2 then
set a = Ability.GetUnitAbilityByID('MMA4',up.ownerHero.hero)
call a.addCastRange(99999)
set ab = BlzGetUnitAbility(up.ownerHero.hero,'MMA4')
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_CASTING_TIME,0,1.0)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_CASTING_TIME,1,1.0)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_CASTING_TIME,2,1.0)
call BlzSetAbilityRealLevelField(ab,ABILITY_RLF_CASTING_TIME,3,1.0)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,0,2)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,1,2)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,2,2)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,3,2)
endif
if GetHeroMasteryType(up.ownerHero.hero) == 3 then
set a = Ability.GetUnitAbilityByID('MMA2',up.ownerHero.hero)
call a.addCastRange(99999)
call a.addManaCost(100,0)
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
set MM_EFFECT = Effect.create("war3mapImported\\Stun.mdx","overhead")
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,MoonMistress_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
scope Starfall initializer init
globals
private constant integer SPELL_ID = 'MMA2'
private constant integer UPGRADE_ID = 'MMI2'
private constant integer DUMMY_ID = 'A02E'
private constant real DURATION_BASE = 3.00
private constant real SUP_DMG = 0.25
endglobals
private function GetDamage takes integer lvl returns real
return 20.00 + 40.00 * lvl
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real d = DURATION_BASE
local unit temp = CreateUnit(GetTriggerPlayer(),'u001',x,y,0)
call RemoveGuardPosition(temp)
call SetUnitUserData(temp,GetUnitUserData(u))
call UnitAddAbility(temp,DUMMY_ID)
if IsUpgradeSuperior(u,UPGRADE_ID) then
call SetUnitAbilityLevel(temp,DUMMY_ID,2)
call UnitApplyTimedLife(temp,'BTLF',d + 2.1)
else
call UnitApplyTimedLife(temp,'BTLF',d + 0.01)
endif
call IssuePointOrderById(temp,ORDER_blizzard,x,y)
set AIMM.SFx = x
set AIMM.SFy = y
set temp = null
set u = null
endfunction
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local unit u
local real dmg
local real x
local integer ulvl
if GetUnitAbilityLevel(data.source,DUMMY_ID) != 0 then
set u = GetUnitByIndex(GetUnitUserData(data.source))
set dmg = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
set ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
set x = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
if x >= 18 or x < 6 then
if ulvl != 0 then
set dmg = dmg + dmg * (0.10 + 0.05 * ulvl)
endif
endif
call CodeDamage.Damage(u,data.target,dmg,udg_DamageTypeMagicAoe,"Starfall",0,0)
set u = null
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,MoonMistress_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(DUMMY_ID,PRELOAD_SECOND)
endfunction
endscope
scope MoonFire initializer init
globals
private constant integer SPELL_ID = 'MMA3'
private constant integer UPGRADE_ID = 'MMI3'
private constant real DAMAGE_BASE = 10.00
private constant real BUFF_DURATION = 4.00
private constant real MR_AREA_BASE = 600.00
private constant real MR_AREA_LVL = 100.00
private constant real UP_RES = 20.00
private constant real SUP_DURATION = 2.00
private constant string CASTER_SFX = "war3mapImported\\StarfallCaster2.mdx"
endglobals
private function GetArea takes integer lvl returns real
return MR_AREA_BASE + MR_AREA_LVL * lvl
endfunction
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE * lvl
endfunction
struct MoonFire extends array
real dmg
real res
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,res,0)
endif
set res = 0
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypeMagicOverTime,"",0,0)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set dmg = GetDamage(b.level)
if ulvl != 0 then
set res = UP_RES * ulvl
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-res,0)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02G'
set BUFF_DATA.BuffID = 'B017'
set BUFF_DATA.Name = "Moon Fire"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetTriggerPlayer()
local group g = NewGroup()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local Lightning light
local real t
local unit temp
local real area = GetArea(GetUnitAbilityLevel(u,SPELL_ID))
call DestroyEffect(AddSpecialEffectTarget(CASTER_SFX,u,"origin"))
call GroupEnumUnitsInRange(g,x,y,area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if UnitHasBuff(temp,MoonFire.buff) then
set light = Lightning.create("WHBM",u,temp,1.25,0.50,125,125)
call light.setLightColor(25,25,255,200)
call Status.Add(STATUS_ENSNARE,temp,1.75,MM_EFFECT)
endif
endloop
call ReleaseGroup(g)
set g = null
set u = null
set p = null
endfunction
private function onCast1 takes nothing returns nothing
local unit u = GetTriggerUnit()
local real r = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
if r < 18 and r > 6 then
call PauseUnit(u,true)
call IssueImmediateOrderById(u,ORDER_stop)
call PauseUnit(u,false)
call Message.ShowToPlayer(GetTriggerPlayer(),"Cannot be activated during day time",MESSAGE_STYLE_ERROR)
endif
set u = null
endfunction
private function onDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local real r
if data.codeDmg.codeName == "LunarRing" or data.codeDmg.codeName == "Starfall" then
set lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
set r = BUFF_DURATION
if lvl != 0 then
if IsUpgradeSuperior(data.source,UPGRADE_ID) then
set r = r + SUP_DURATION
endif
call UnitAddBuff(data.target,data.source,BUFF_DURATION,MoonFire.buff,lvl,0)
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call MoonFire.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellChannelEvent(SPELL_ID, function onCast1)
call DamageEvent.RegisterDamage(Filter(function onDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,MoonMistress_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Moonlight initializer init
globals
private constant integer SPELL_ID = 'MMA4'
private constant integer UPGRADE_ID = 'MMI4'
private constant integer DUMMY_ID = 'AIct'
private constant real BUFF_DURATION = 45.00
private constant real CD_BASE = 0.05
private constant real CD_LVL = 0.05
private constant integer MANA_BASE = 8
private constant integer MA_HP = 200
private constant integer MA_SR = 300
private constant integer MA_MR = 12
private constant string TARGET_SFX = "war3mapImported\\StarfallCaster2.mdx"
endglobals
private function GetCooldown takes integer lvl returns real
return CD_BASE + CD_LVL * lvl
endfunction
struct Moonlight extends array
real cd
integer mr
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,-mr,0)
call BonusStruct.AddSpecial(BONUS_TYPE_CD_REDUCTION,b.target,cd,0)
if b.int == 2 then
call AddUnitAnimationProperties(b.target,"alternate",false)
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set cd = GetCooldown(b.level)
set mr = MANA_BASE * b.level
if b.int == 1 then
set cd = cd / 2
set mr = mr / 2
endif
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,mr,0)
call BonusStruct.AddSpecial(BONUS_TYPE_CD_REDUCTION,b.target,-cd,0)
if b.int == 2 then
call AddUnitAnimationProperties(b.target,"alternate",true)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02J'
set BUFF_DATA.BuffID = 'B019'
set BUFF_DATA.Name = "Moonlight"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local group g = tb.group[0]
local unit temp
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
call BonusStruct.Add(BONUS_TYPE_SIGHT_RANGE,temp,200,0,true)
endloop
call ReleaseGroup(g)
call ReleaseTimer(t)
call tb.flush()
call tb.destroy()
set t = null
set g = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetTriggerPlayer()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Hero h
local integer i
local Players ps
local player p2
local group g
local Table tb
local unit dummy
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set i = 2
loop
set ps = Players[i]
set p2 = Player(i)
if ps.isPlaying and IsPlayerAlly(p2,p) and p2 != p then
set h = ps.hero
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,h.hero,"origin"))
call UnitAddBuff(h.hero,u,BUFF_DURATION,Moonlight.buff,lvl,1)
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
endif
set dummy = CreateUnit(p,'u001',0,0,0)
call UnitAddAbility(dummy,'A0D1')
call IssueImmediateOrderById(dummy,ORDER_eclipse)
call UnitApplyTimedLife(dummy,'BTLF',1.0)
set dummy = null
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,u,"origin"))
call UnitAddBuff(u,u,BUFF_DURATION,Moonlight.buff,lvl,2)
if GetHeroMasteryType(u) == 2 then
call SetUnitX(u,GetSpellTargetX())
call SetUnitY(u,GetSpellTargetY())
endif
if GetHeroMasteryType(u) == 1 then
set g = NewGroup()
set tb = Table.create()
set tb.group[0] = g
set i = 2
loop
set ps = Players[i]
set p2 = Player(i)
if ps.isPlaying and IsPlayerEnemy(p2,p) then
set h = ps.hero
if UnitAlive(h.hero) then
call GroupAddUnit(g,h.hero)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,h.hero,"origin"))
call BonusStruct.Add(BONUS_TYPE_SIGHT_RANGE,h.hero,-200,0,true)
endif
endif
set i = i + 1
exitwhen i > Game.PLAYER_MAX
endloop
set g = null
call TimerStart(NewTimerEx(tb),BUFF_DURATION,false,function Callback)
endif
set u = null
set p = null
set p2 = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Moonlight.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,MoonMistress_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(DUMMY_ID,PRELOAD_SECOND)
endfunction
endscope
library Dreamweaver initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HDE1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'DEI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Dream Path"
set up.Text = "Increases |c00b4b4b4Fairy Dust|r distance traveled."
set up.SupText = "|c00b4b4b4Fairy Dust|r leaves a trail of magic that reduces 100(15.6%) |c00ffff95Resistance|r to enemies inside it, lasts 10 seconds."
set up.LevelData1 = "+100 Distance"
set up.LevelData2 = "+200 Distance"
set up.LevelData3 = "+300 Distance"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWisp.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'DEI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Deep Trance"
set up.Text = "The damage bonus of |c00b4b4b4Induce Sleep|r increases based on how long the target was |c0000ced1Sleeping|r."
set up.SupText = "The wake up damage is applied in 250 AoE around the target."
set up.LevelData1 = "+10% max Damage Increased"
set up.LevelData2 = "+15% max Damage Increased"
set up.LevelData3 = "+20% max Damage Increased"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWispSplode.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'DEI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Rainbow Surge"
set up.Text = "Increases |c00b4b4b4Phase Shift|r cast range."
set up.SupText = "Increases |c00b4b4b4Phase Shift|r AoE by 200."
set up.LevelData1 = "+100 Cast Range"
set up.LevelData2 = "+150 Cast Range"
set up.LevelData3 = "+200 Cast Range"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNReplenishHealth.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'DEI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Mesmerize"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HDE1'
set d.Name = "Dreamweaver"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNFaerieDragon.blp"
set d.WinAni = "attack"
set d.Block = 0
set d.Evasion = 20
set d.Resistance = 50
set d.LifeRegen = 1.5
set d.ManaRegen = 1.5
set d.Armor = 0
set d.AttackRange = 620
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'DEA1'
set d.HeroAbility2 = 'DEA2'
set d.HeroAbility3 = 'DEA3'
set d.HeroAbility4 = 'DEA4'
set d.ChooseIconID = 'c027'
set d.ChooseDummy = 'dh27'
set d.spellDamageLevel = 7
set d.attackDamageLevel = 3
set d.healingLevel = 0
set d.survivavilityLevel = 5
set d.movementLevel = 5
set d.crowdControlLevel = 5
set d.HeroFaction = Game.FACTION_NIGHTELF
set d.InfoID = 'HDEI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope FairyDust initializer init
globals
private constant integer SPELL_ID = 'DEA1'
private constant integer UPGRADE_ID = 'DEI1'
private constant real DAMAGE_BASE = 90.00
private constant real DAMAGE_LEVEL = 50.00
private constant real AREA_OF_EFFECT = 200.00
private constant real BUFF_DURATION = 8.00
private constant integer MISS_BASE = 50
private constant real UP_DIST = 100.00
private constant real SUP_RESISTANCE = 100.00
private constant string MISSILE_SFX = "Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl"
private constant string PATH_SFX = "war3mapImported\\ConvictionAura.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct Trail extends array
implement Alloc
effect sfx
public static method create takes real x, real y returns thistype
local thistype this = thistype.allocate()
set sfx = AddSpecialEffect(PATH_SFX,x,y)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 50.00)
call BlzSetSpecialEffectTimeScale(sfx,2.0)
return this
endmethod
public method destroy takes nothing returns nothing
call DestroyEffect(sfx)
set sfx= null
call this.deallocate()
endmethod
endstruct
struct FairyDustTrail extends array
public static method onRemove takes Buff b returns nothing
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,SUP_RESISTANCE,0)
endmethod
public static method onApply takes Buff b returns nothing
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-SUP_RESISTANCE,0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A04J'
set BUFF_DATA.BuffID = 'B01O'
set BUFF_DATA.Name = "Fairy Dust Trail Buff"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct FDTrail extends array
implement Alloc
unit caster
LinkedList trails
real ax
real ay
real bx
real by
real duration
public method applyEffect takes nothing returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(caster)
local unit temp
local Buff b
call LineSegment.EnumUnits(g,ax,ay,bx,by,160)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
set b = GetUnitBuff(temp,FairyDustTrail.buff)
if b != 0 then
set b.elapsedTime = 0.0
else
call UnitAddBuff(temp,caster,1.1,FairyDustTrail.buff,0,0)
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endmethod
private static method Periodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
set duration = duration - 1.0
if duration <= 0 then
call this.destroy()
call ReleaseTimer(t)
else
call this.applyEffect()
endif
set t = null
endmethod
public method add takes real x, real y returns nothing
call trails.add(Trail.create(x,y))
if trails.size == 1 then
set ax = x
set ay = y
endif
set bx = x
set by = y
endmethod
public static method create takes unit caster, real dur returns thistype
local thistype this = thistype.allocate()
set .caster = caster
set trails = LinkedList.create()
set duration = dur
call TimerStart(NewTimerEx(this),1.0,true,function thistype.Periodic)
return this
endmethod
public method destroy takes nothing returns nothing
local Link h = trails.head
local Trail t
loop
exitwhen h == 0
set t = h.data
call t.destroy()
set h = h.next
endloop
call trails.destroy()
set caster = null
call this.deallocate()
endmethod
endstruct
struct FairyDust extends array
integer chance
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set chance = MISS_BASE
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0AZ'
set BUFF_DATA.BuffID = 'B041'
set BUFF_DATA.Name = "Fairy Dust"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct FairyDustMissile extends array
real cos1
real sin1
real cos2
real sin2
effect sfx1
effect sfx2
FDTrail trail
real trailDist
integer trailCount
private static method onFinish takes Missile missile returns boolean
local thistype this = thistype[missile]
call BlzSetSpecialEffectScale(sfx1,1.5)
call BlzSetSpecialEffectScale(sfx2,1.5)
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
set sfx1 = null
set sfx2 = null
call SetUnitScale(missile.dummy,1.5,1.5,1.5)
return true
endmethod
private static method onPeriod takes Missile missile returns boolean
local thistype this = thistype[missile]
local real h = GetUnitFlyHeight(missile.dummy)
local real x
local real y
local real z = GetLocZ(missile.x,missile.y)
if trail != 0 then
set trailDist = trailDist + missile.speed
if trailDist >= 200.00 then
set trailCount = trailCount - 1
set trailDist = 0.00
if trailCount != 0 then
call trail.add(missile.x,missile.y)
endif
endif
endif
set x = missile.x + 85.00 * cos1
set y = missile.y + 85.00 * sin1
call BlzSetSpecialEffectX(sfx1,x)
call BlzSetSpecialEffectY(sfx1,y)
call BlzSetSpecialEffectHeight(sfx1,z + h)
set x = missile.x + 85.00 * cos2
set y = missile.y + 85.00 * sin2
call BlzSetSpecialEffectX(sfx2,x)
call BlzSetSpecialEffectY(sfx2,y)
call BlzSetSpecialEffectHeight(sfx2,z + h)
return false
endmethod
private static method onCollide takes Missile missile, unit hit returns boolean
if FILT_UNIT_ENEMY(hit,missile.owner) and not IsUnitMagicImmune(hit) then
call CodeDamage.Damage(missile.source,hit,missile.damage,udg_DamageTypeMagicAoe,"",0,0)
call UnitAddBuff(hit,missile.source,BUFF_DURATION,FairyDust.buff,missile.level,missile.data)
endif
return false
endmethod
public static method onStart takes Missile missile, real dist returns nothing
local thistype this = thistype[missile]
local real h = GetUnitFlyHeight(missile.dummy)
local real x
local real y
set cos1 = Cos(missile.angle - 1.5707)
set sin1 = Sin(missile.angle - 1.5707)
set cos2 = Cos(missile.angle + 1.5707)
set sin2 = Sin(missile.angle + 1.5707)
set x = missile.x + 85.00 * cos1
set y = missile.y + 85.00 * sin1
set sfx1 = AddSpecialEffect(MISSILE_SFX,x,y)
call BlzSetSpecialEffectScale(sfx1,4.0)
call BlzSetSpecialEffectYaw(sfx1,missile.angle)
call BlzSetSpecialEffectHeight(sfx1,h)
call BlzSetSpecialEffectTime(sfx1,0.00)
set x = missile.x + 85.00 * cos2
set y = missile.y + 85.00 * sin2
set sfx2 = AddSpecialEffect(MISSILE_SFX,x,y)
call BlzSetSpecialEffectScale(sfx2,4.0)
call BlzSetSpecialEffectYaw(sfx2,missile.angle)
call BlzSetSpecialEffectHeight(sfx2,h)
call BlzSetSpecialEffectTime(sfx2,0.00)
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
set trail = FDTrail.create(missile.source,10.00)
set trailDist = 0
set trailCount = 7
else
set trail = 0
endif
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, real x, real y returns Missile
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local real xu = GetUnitX(source)
local real yu = GetUnitY(source)
local real a = Angle(xu,yu,x,y)
local real d = 1000 + UP_DIST * GetUpgradeSkillLevel(source,UPGRADE_ID)
local integer ulvl
local Missile missile
set x = xu + d * Cos(a)
set y = yu + d * Sin(a)
set missile = Missile.createXYZ(xu,yu,150.00,x,y,150.00)
set missile.source = source
set missile.level = lvl
set missile.collision = AREA_OF_EFFECT
set missile.owner = GetOwningPlayer(source)
set missile.speed = 15.00
set missile.model = MISSILE_SFX
set missile.damage = GetDamage(lvl)
set missile.scale = 4.00
if IsUpgradeSuperior(source,UPGRADE_ID) then
set missile.data = 1
endif
call FairyDustMissile.launch(missile)
call FairyDustMissile.onStart(missile,d)
set source = null
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
call SetupMissile(u,x,y)
set u = null
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType == udg_DamageTypeAttack then
set b = GetUnitBuff(data.source,FairyDust.buff)
if b != 0 then
set data.evasionPercentAdd = FairyDust[b.buffAllocIndex].chance
endif
set b = GetUnitBuff(data.target,EmeraldTrance.buff)
if b != 0 then
set data.mult = data.mult + 1.50
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FairyDust.Initialize()
call FairyDustTrail.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Dreamweaver_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope SleepS initializer init
globals
private constant integer SPELL_ID = 'DEA2'
private constant integer UPGRADE_ID = 'DEI2'
private constant real DMG_BASE = 0.10
private constant real DMG_LVL = 0.10
private constant real DURATION_BASE = 5.00
private constant real DELAY = 1.80
private constant real UP_DMG = 0.05
private constant string TARGET_SFX = "Objects\\Spawnmodels\\NightElf\\NEDeathSmall\\NEDeathSmall.mdl"
private constant string PRE_SFX = "Abilities\\Spells\\Undead\\Sleep\\SleepSpecialArt.mdl"
endglobals
private function GetDmgInc takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
struct SleepB extends array
real dmgBonus
real dmgBonusFactor
real time
real timesfx
boolean remove
boolean asleep
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real r
set time = time + 0.03125
if time >= DELAY and not asleep then
set r = Status.Add(STATUS_SLEEP,b.target,DURATION_BASE,Status_EFFECT[STATUS_SLEEP])
if r != 0 then
set b.duration = r
set b.elapsedTime = 0.00
set asleep = true
else
set b.removeInside = true
endif
else
if time > DELAY then
if not Status.UnitHasStatus(STATUS_SLEEP,b.target) or remove then
set b.removeInside = true
else
set dmgBonus = dmgBonus + dmgBonusFactor
endif
else
set timesfx = timesfx + 0.03125
if timesfx >= 0.36 then
set timesfx = 0.00
call DestroyEffect(AddSpecialEffectTarget(PRE_SFX,b.target,"overhead"))
endif
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set dmgBonusFactor = 0
if ulvl != 0 then
set dmgBonusFactor = (UP_DMG + UP_DMG * ulvl) / (DURATION_BASE*32)
endif
set dmgBonus = 0
set remove = false
set asleep = false
set time = 0.00
set timesfx = 0.00
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Sleep"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u,unit t, integer lvl returns nothing
call UnitAddBuff(t,u,DELAY,SleepB.buff,lvl,0)
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function SleepDamageAoE takes unit source, unit target, real damage returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(source)
local unit temp
local integer i = 0
local real x = GetUnitX(target)
local real y = GetUnitY(target)
loop
exitwhen i == 5
set i = i + 1
call DestroyEffect(AddSpecialEffect(TARGET_SFX,x + 130 * Cos((72 * i) * bj_DEGTORAD),y + 130 * Sin((72 * i) * bj_DEGTORAD)))
endloop
call GroupEnumUnitsInRange(g,x,y,250.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and temp != target then
call CodeDamage.Damage(source,temp,damage,udg_DamageTypeMagicAoe,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local boolean do = true
local Buff b
local integer lvl
local unit u
local real dmg
local real dmg2
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime and data.damageMod != 0 then
set b = GetUnitBuff(data.target,SleepB.buff)
if b != 0 then
if data.dmgType == udg_DamageTypeAttack and data.source == b.owner then
set do = false
elseif data.codeDmg.codeName == "PhaseShift" and data.codeDmg != 0 then
set do = false
else
set do = true
endif
else
set do = false
endif
if do and SleepB[b.buffAllocIndex].asleep then
set lvl = b.level
set u = b.owner
set dmg2 = SleepB[b.buffAllocIndex].dmgBonus
set SleepB[b.buffAllocIndex].remove = true
set dmg = GetDmgInc(lvl)
set data.mult = data.mult + dmg + dmg2
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,data.target,"origin"))
if IsUnitAlly(data.target,GetOwningPlayer(u)) then
if GetHeroMasteryType(u) == 3 then
set data.dmgType = udg_DamageTypeHeal
endif
endif
set u = null
endif
endif
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b = GetUnitBuff(data.target,SleepB.buff)
if b != 0 then
if SleepB[b.buffAllocIndex].remove then
if IsUpgradeSuperior(b.owner,UPGRADE_ID) and data.damageMod > 0 then
call SleepDamageAoE(b.owner,b.target,data.damageMod)
endif
call b.remove()
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SleepB.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call DamageEvent.RegisterDamage(Filter(function OnDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Dreamweaver_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope PhaseShift initializer init
globals
private constant integer SPELL_ID = 'DEA3'
private constant integer UPGRADE_ID = 'DEI3'
private constant real DMG_BASE = 50.0
private constant real DMG_LVL = 25.0
private constant real MS_BASE = 0.20
private constant real MS_LVL = 0.10
private constant integer AS_BASE = 40
private constant integer AS_LVL = 10
private constant real DURATION = 2.00
private constant real BUFF_DURATION = 3.00
private constant real AOE_BASE = 250.00
private constant real UP_RANGE = 50.00
private constant real SUP_AOE = 200.00
private constant string MISSILE_SFX = "units\\nightelf\\FaerieDragon\\FaerieDragon.mdl"
private constant string AREA_SFX = "war3mapImported\\RainbowMissile.mdx"
endglobals
private function GetAS takes integer lvl returns integer
return AS_BASE + AS_LVL * lvl
endfunction
private function GetMS takes integer lvl returns real
return MS_BASE + MS_LVL * lvl
endfunction
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
struct PhaseShift extends array
integer as
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = GetAS(b.level)
set ms = Movespeed.create(b.target,-GetMS(b.level),0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0B2'
set BUFF_DATA.BuffID = 'B042'
set BUFF_DATA.Name = "PhaseShift"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct PhaseShiftAttack extends array
private static method onFinish takes Missile missile returns boolean
if UnitAlive(missile.target) then
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeMagicAoe,"PhaseShift",0,0)
call UnitAddBuff(missile.target,missile.source,3.0,PhaseShift.buff,missile.level,0)
endif
return true
endmethod
implement MissileStruct
endstruct
private function SetupAttack takes unit source, unit target, integer lvl returns nothing
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real a = Angle(xs,ys,GetUnitX(target),GetUnitY(target))
local Missile missile = Missile.create(xs,ys,75.00,a,20.00,75.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl)
set missile.speed = 40.00
set missile.level = lvl
set missile.model = AREA_SFX
set missile.scale = 1.0
call PhaseShiftAttack.launch(missile)
endfunction
struct PhaseShiftMissile extends array
unit vision
private static method onPeriod takes Missile missile returns boolean
local unit v = thistype[missile].vision
call SetUnitX(v,missile.x)
call SetUnitY(v,missile.y)
call SetUnitX(missile.source,missile.x)
call SetUnitY(missile.source,missile.y)
set v = null
return false
endmethod
private static method onFinish takes Missile missile returns boolean
local Buff b = GetUnitBuff(missile.source,EmeraldTrance.buff)
call Status.Remove(STATUS_HIDE,missile.source)
call Status.Remove(STATUS_INVULNERABLE,missile.source)
if missile.target != null then
call EmeraldTrance[b.buffAllocIndex].attachToAlly(missile.target)
else
call SelectUnitForPlayer(missile.source,missile.owner,true)
endif
call UnitRemoveAbility(missile.dummy,'A0B1')
call SetUnitScale(missile.dummy,0,0,0)
call RemoveUnit(thistype[missile].vision)
set thistype[missile].vision = null
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, unit target, real xc, real yc returns Missile
local real x = GetUnitX(source)
local real y = GetUnitY(source)
local real xt = GetUnitX(target)
local real yt = GetUnitY(target)
local integer lvl = GetUnitAbilityLevel(source,SPELL_ID)
local Missile missile
local group g = NewGroup()
local unit temp
local real aoe = AOE_BASE
if target == null then
set missile = Missile.create(x, y,150.0, Angle(x,y,xc,yc), Distance(x,y,xc,yc) * 0.60,150.0)
else
set missile = Missile.create(x,y,75.00,Angle(x,y,xt,yt),20.00,75.00)
set missile.target = target
endif
call Status.Add(STATUS_HIDE,source,0,0)
call Status.Add(STATUS_INVULNERABLE,source,0,0)
if IsUpgradeSuperior(source,UPGRADE_ID) then
set aoe = aoe + SUP_AOE
endif
set missile.source = source
set missile.level = lvl
set missile.owner = GetOwningPlayer(source)
set missile.speed = 25.00
set missile.model = MISSILE_SFX
set missile.scale = 1.2
call GroupEnumUnitsInRange(g,xc,yc,aoe,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) and not IsUnitMagicImmune(temp) then
call SetupAttack(source,temp,lvl)
endif
endloop
call ReleaseGroup(g)
set g = null
call UnitAddAbility(missile.dummy,'A0B1')
set PhaseShiftMissile[missile].vision = CreateUnit(GetOwningPlayer(source),'h00O',x,y,0)
call PhaseShiftMissile.launch(missile)
return missile
return 0
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local Ability a
if t == null then
call SetupMissile(u,null,GetSpellTargetX(),GetSpellTargetY())
else
if UnitHasBuff(u,EmeraldTrance.buff) then
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call a.addTempFlatCooldown(3.0)
call SetupMissile(u,t,0,0)
else
call SetupMissile(u,null,GetUnitX(t),GetUnitY(t))
endif
endif
set u = null
set t = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local ability ab
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
if up.level == 1 then
call a.addCastRange(UP_RANGE)
endif
call a.addCastRange(UP_RANGE)
if up.isSuperior then
call a.addAreaOfEffect(SUP_AOE)
endif
endif
if up.upID == 'DEI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 2 then
set ab = BlzGetUnitAbility(up.ownerHero.hero,'DEA3')
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,0,3)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,1,3)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,2,3)
call BlzSetAbilityIntegerLevelField(ab,ABILITY_ILF_TARGET_TYPE,3,3)
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call PhaseShift.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Dreamweaver_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope EmeraldTrance initializer init
globals
private constant integer SPELL_ID = 'DEA4'
private constant integer UPGRADE_ID = 'DEI4'
private constant integer BUFF_ID = 'A08A'
private constant integer DUMMY_ID = 'h00K'
private constant real AOE_BASE = 800.00
private constant real MC_BASE = 0.60
private constant real MC_LVL = 0.40
private constant real DRAIN_BASE = 15.00
private constant real BUFF_DURATION = 10.00
private constant real UP_DRAIN_DUR = 5.00
private constant integer MA_ARMOR = 50
private constant string TARGET_SFX = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl"
endglobals
private function GetManaCostFactor takes integer lvl returns real
return MC_BASE + MC_LVL * lvl
endfunction
private function GetDrain takes integer lvl returns real
return DRAIN_BASE + DRAIN_BASE * lvl
endfunction
struct EmeraldLightning extends array
implement Alloc
Lightning light
public static method create takes unit s,unit t, Buff b returns thistype
local thistype this = thistype.allocate()
set light = Lightning.create("WHSB",s,t,9999.0,0.10,100,175)
call light.setLightColor(50,205,50,255)
call UnitAddAbility(t,BUFF_ID)
call UnitMakeAbilityPermanent(t,true,BUFF_ID)
call SetUnitData(t,"ETBuff",b)
return this
endmethod
public method destroy takes nothing returns nothing
call UnitRemoveAbility(light.unitTarget,BUFF_ID)
call SetUnitData(light.unitTarget,"ETBuff",0)
call light.destroy()
call this.deallocate()
endmethod
endstruct
struct EmeraldTrance extends array
integer armor
real time
real drain
real manaPercent
unit dummy
boolean hiden
boolean wm
unit attachedUnit
real timeAtt
LinkedList list
public method attachToAlly takes unit target returns nothing
set attachedUnit = target
set timeAtt = 3.0
call UnitAddAbility(thisBuff.target,'Aloc')
call UnitRemoveAbility(thisBuff.target,'Aloc')
endmethod
private method CheckAffectedUnits takes real x, real y returns nothing
local Link h = list.head
local Link n
local EmeraldLightning l
loop
exitwhen h == 0
set l = h.data
set n = h.next
if Distance(x,y,l.light.xTarget,l.light.yTarget) > AOE_BASE or not UnitAlive(l.light.unitTarget) or (IsUnitMagicImmune(l.light.unitTarget) and not wm) then
call l.destroy()
call list.remove(h)
endif
if time >= 0.50 then
call UnitRemoveMp(l.light.unitTarget,drain)
if Status.UnitHasStatus(STATUS_SLEEP,l.light.unitTarget) then
call UnitAddHp(l.light.unitSource,drain)
endif
endif
set h = n
endloop
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local group g
local player p = GetOwningPlayer(b.target)
local unit temp
local real x
local real y
set time = time + 0.03125
if attachedUnit != null then
set timeAtt = timeAtt - 0.03125
if timeAtt <= 0 or not UnitAlive(attachedUnit) then
set attachedUnit = null
call ShowUnit(b.target,false)
call ShowUnit(b.target,true)
call SelectUnitForPlayer(b.target,GetOwningPlayer(b.target),true)
set x = GetUnitX(b.target)
set y = GetUnitY(b.target)
else
set x = GetUnitX(attachedUnit)
set y = GetUnitY(attachedUnit)
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
call SetUnitX(b.target,x)
call SetUnitY(b.target,y)
endif
else
set x = GetUnitX(b.target)
set y = GetUnitY(b.target)
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
endif
call CheckAffectedUnits(x,y)
if IsUnitHidden(b.target) then
if not hiden then
call UnitRemoveAbility(dummy,'Aloc')
call ShowUnit(dummy,false)
set hiden = true
endif
else
if hiden then
set hiden = false
call ShowUnit(dummy,true)
call UnitAddAbility(dummy,'Aloc')
endif
endif
if time >= 0.50 then
set time = 0.00
set g = NewGroup()
call GroupEnumUnitsInRange(g,x,y,AOE_BASE,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if GetUnitAbilityLevel(temp,BUFF_ID) == 0 and FILT_HERO_ENEMY(temp,p) then
if not IsUnitMagicImmune(temp) or wm then
call list.add(EmeraldLightning.create(b.target,temp,b))
endif
endif
endloop
call ReleaseGroup(g)
set g = null
endif
set p = null
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Link h = list.head
local EmeraldLightning l
loop
exitwhen h == 0
set l = h.data
call l.destroy()
set h = h.next
endloop
call list.destroy()
call RemoveUnit(dummy)
call SetUnitVertexColor(b.target,255,255,255,255)
call UnitRemoveAbility(b.target,'Bmfl')
call Status.Remove(STATUS_SPELL_IMMUNITY,b.target)
call Status.Remove(STATUS_UNTURN,b.target)
call BlzUnitDisableAbility(b.target,'Aatk',false,false)
call BlzUnitDisableAbility(b.target,'Amov',false,false)
if armor == 1 then
set armor = 0
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-MA_ARMOR,0,true)
endif
set dummy = null
if attachedUnit != null then
set timeAtt = 0.0
call ShowUnit(b.target,false)
call ShowUnit(b.target,true)
call SelectUnitForPlayer(b.target,GetOwningPlayer(b.target),true)
set attachedUnit = null
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set list = LinkedList.create()
set dummy = CreateUnit(GetOwningPlayer(b.target),DUMMY_ID,GetUnitX(b.target),GetUnitY(b.target),0)
call UnitAddAbility(dummy,'Aloc')
call SetUnitAnimation(dummy,"stand channel")
call SetUnitVertexColor(b.target,255,255,255,0)
call Status.Add(STATUS_SPELL_IMMUNITY,b.target,0,0)
call Status.Add(STATUS_UNTURN,b.target,0,0)
call BlzUnitDisableAbility(b.target,'Amov',true,false)
call BlzUnitDisableAbility(b.target,'Aatk',true,false)
set drain = GetDrain(b.level)
set manaPercent = GetManaCostFactor(b.level)
if GetHeroMasteryType(b.target) == 1 then
set armor = 1
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,MA_ARMOR,0,true)
endif
set wm = GetHeroMasteryType(b.target) == 3
set time = 0.00
set hiden = false
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "EmeraldTrance"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onOrder takes nothing returns nothing
local unit u = GetOrderedUnit()
local integer id = GetIssuedOrderId()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if id == ORDER_unimmolation and lvl != 0 then
call UnitRemoveBuff(u,EmeraldTrance.buff)
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = BUFF_DURATION
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set d = d + UP_DRAIN_DUR
endif
call UnitAddBuff(u,u,d,EmeraldTrance.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function onCastExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id = GetSpellAbilityId()
local DamageOptions op
local integer r
local real dmg
local Buff b
if GetUnitAbilityLevel(u,'B043') != 0 then
set r = BlzGetUnitAbilityManaCost(u,id,GetUnitAbilityLevel(u,id) - 1)
set b = GetUnitData(u,"ETBuff")
if b != 0 and r != 0 then
if not IsUnitMagicImmune(u) or EmeraldTrance[b.buffAllocIndex].wm then
set dmg = r * EmeraldTrance[b.buffAllocIndex].manaPercent
set op = DamageOptions.create()
if EmeraldTrance[b.buffAllocIndex].wm then
set op.pierceImmune = true
endif
call CodeDamage.Damage(b.owner,u,dmg,udg_DamageTypePure,"",op,0)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,u,"overhead"))
endif
endif
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call EmeraldTrance.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function onOrder)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function onCastExtra)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Dreamweaver_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library Warden initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HWD1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'WDI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Defensive Swirl"
set up.Text = "Reduces |c00b4b4b4Sharpstorm|r mana cost."
set up.SupText = "|c00b4b4b4Sharpstorm|r adds 100(15.6%) |c00ffff95Evasion|r rating bonus."
set up.LevelData1 = "-25 Mana Cost"
set up.LevelData2 = "-50 Mana Cost"
set up.LevelData3 = "-75 Mana Cost"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWisp.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'WDI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Bloddy Assault"
set up.Text = "Increases |c00ffff95Attack Speed|r after using |c00b4b4b4Riposte|r for 3s."
set up.SupText = "The attack of |c00b4b4b4Riposte|r is always a |c007fff00Critical|r strike."
set up.LevelData1 = "+20 Damage"
set up.LevelData2 = "+40 Damage"
set up.LevelData3 = "+60 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNWispSplode.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'WDI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Saw Blades"
set up.Text = "Increases |c00b4b4b4Splinter Blades|r area of effect."
set up.SupText = "Converts the damage of |c00b4b4b4Splinter Blades|r to |c00ee82eePure|r and when the blade returns deals the same amount of damage."
set up.LevelData1 = "+50 AoE"
set up.LevelData2 = "+100 AoE"
set up.LevelData3 = "+150 AoE"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNReplenishHealth.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'WDI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Hunt"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HWD1'
set d.Name = "Warden"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNpbv1.blp"
set d.WinAni = "spell"
set d.Block = 0
set d.Evasion = 40
set d.Resistance = 10
set d.LifeRegen = 1.5
set d.ManaRegen = 1.5
set d.Armor = 5
set d.AttackRange = 125
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'WDA1'
set d.HeroAbility2 = 'WDA2'
set d.HeroAbility3 = 'WDA3'
set d.HeroAbility4 = 'WDA4'
set d.ChooseIconID = 'c034'
set d.ChooseDummy = 'dh34'
set d.spellDamageLevel = 3
set d.attackDamageLevel = 8
set d.healingLevel = 0
set d.survivavilityLevel = 4
set d.movementLevel = 3
set d.crowdControlLevel = 1
set d.HeroFaction = Game.FACTION_NIGHTELF
set d.InfoID = 'HWDI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope Sharpstorm initializer init
globals
private constant integer SPELL_ID = 'WDA1'
private constant integer UPGRADE_ID = 'WDI1'
private constant integer EXTRA_ID = 'A02A'
private constant real DAMAGE_MIN = 5.00
private constant real SLOW_MIN = 0.05
private constant real DAMAGE_BASE = 20.00
private constant real DAMAGE_LEVEL = 5.00
private constant real SLOW_MAX = 0.40
private constant real AOE_MIN = 150.00
private constant real AOE_MAX = 300.00
private constant real BUFF_DURATION = 6.00
private constant integer UP_MANA = -25
private constant real SUP_EVASION = 100.00
private constant real MA_SRED = 0.75
private constant string AOE_SFX = "war3mapImported\\SentinelMissile.mdx"
private constant string PERIOD_SFX = "Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetDamageMin takes integer lvl returns real
return DAMAGE_MIN + DAMAGE_MIN * lvl
endfunction
struct SharpstormSlow extends array
Movespeed ms
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int == 1 then
set ms = Movespeed.create(b.target,-SLOW_MIN,0)
elseif b.int == 2 then
set ms = Movespeed.create(b.target,-SLOW_MAX,0)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A029'
set BUFF_DATA.BuffID = 'B051'
set BUFF_DATA.Name = "Sharpstorm"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct Sharpstorm extends array
effect sfx1
effect sfx2
effect sfx3
effect sfx4
real aoe
real ang
real size
integer mode
boolean isChanging
real cdmg
real dmg1
real dmg2
real time
boolean eva
boolean sr
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real xu = GetUnitX(b.target)
local real yu = GetUnitY(b.target)
local group g
local unit temp
local real x
local real y
local real z = GetLocZ(xu,yu)
local real a
local player p
if isChanging then
if mode == 2 then
set aoe = aoe + 9.375
set size = size + 0.03125
if aoe >= AOE_MAX then
set isChanging = false
set cdmg = dmg2
endif
else
set aoe = aoe - 9.375
set size = size - 0.03125
if aoe <= AOE_MIN then
set isChanging = false
set cdmg = dmg1
endif
endif
call BlzSetSpecialEffectScale(sfx1,size)
call BlzSetSpecialEffectScale(sfx2,size)
call BlzSetSpecialEffectScale(sfx3,size)
call BlzSetSpecialEffectScale(sfx4,size)
endif
set ang = ang + 9.0
set a = ang * bj_DEGTORAD
set x = xu + aoe * Cos(a)
set y = yu + aoe * Sin(a)
call BlzSetSpecialEffectX(sfx1,x)
call BlzSetSpecialEffectY(sfx1,y)
call BlzSetSpecialEffectYaw(sfx1,a + 1.5708)
call BlzSetSpecialEffectHeight(sfx1,z + 80)
set a = (ang + 90.00) * bj_DEGTORAD
set x = xu + aoe * Cos(a)
set y = yu + aoe * Sin(a)
call BlzSetSpecialEffectX(sfx2,x)
call BlzSetSpecialEffectY(sfx2,y)
call BlzSetSpecialEffectYaw(sfx2,a + 1.5708)
call BlzSetSpecialEffectHeight(sfx2,z + 80)
set a = (ang + 180.00) * bj_DEGTORAD
set x = xu + aoe * Cos(a)
set y = yu + aoe * Sin(a)
call BlzSetSpecialEffectX(sfx3,x)
call BlzSetSpecialEffectY(sfx3,y)
call BlzSetSpecialEffectYaw(sfx3,a + 1.5708)
call BlzSetSpecialEffectHeight(sfx3,z + 80)
set a = (ang + 270.00) * bj_DEGTORAD
set x = xu + aoe * Cos(a)
set y = yu + aoe * Sin(a)
call BlzSetSpecialEffectX(sfx4,x)
call BlzSetSpecialEffectY(sfx4,y)
call BlzSetSpecialEffectYaw(sfx4,a + 1.5708)
call BlzSetSpecialEffectHeight(sfx4,z + 80)
if not isChanging then
set time = time + 0.03125
if time >= 0.50 then
set time = 0.00
set g = NewGroup()
set p = GetOwningPlayer(b.target)
call GroupEnumUnitsInRange(g,xu,yu,aoe + 25.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
call CodeDamage.Damage(b.owner,temp,cdmg,udg_DamageTypePhysicalAoe,"",0,0)
call UnitAddBuff(temp,b.target,1.0,SharpstormSlow.buff,0,mode)
call DestroyEffect(AddSpecialEffectTarget(PERIOD_SFX,temp,"chest"))
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
endif
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
call DestroyEffect(sfx3)
call DestroyEffect(sfx4)
set sfx1 = null
set sfx2 = null
set sfx3 = null
set sfx4 = null
call UnitRemoveAbility(b.target,EXTRA_ID)
call BlzUnitHideAbility(b.target,SPELL_ID,false)
if eva then
set eva = false
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,-SUP_EVASION,0)
endif
if sr then
set sr = false
call AddUnitNegativeStatusReduction(b.target,-MA_SRED,false)
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real xu = GetUnitX(b.target)
local real yu = GetUnitY(b.target)
local real x
local real y
local real a = 0
local real z = GetLocZ(xu,yu)
set mode = 1
set dmg1 = GetDamage(b.level)
set dmg2 = GetDamageMin(b.level)
set isChanging = false
set aoe = AOE_MIN
set ang = 0
set x = xu + aoe * Cos(0)
set y = yu + aoe * Sin(0)
set sfx1 = AddSpecialEffect(AOE_SFX,x,y)
call BlzSetSpecialEffectYaw(sfx1,90.00 * bj_DEGTORAD)
call BlzSetSpecialEffectHeight(sfx1,z + 80)
call BlzSetSpecialEffectScale(sfx1,1.00)
call BlzSetSpecialEffectTimeScale(sfx1,0.60)
set x = xu + aoe * Cos(1.5708)
set y = yu + aoe * Sin(1.5708)
set sfx2 = AddSpecialEffect(AOE_SFX,x,y)
call BlzSetSpecialEffectYaw(sfx2,180.00 * bj_DEGTORAD)
call BlzSetSpecialEffectHeight(sfx2,z + 80)
call BlzSetSpecialEffectScale(sfx2,1.00)
call BlzSetSpecialEffectTimeScale(sfx2,0.60)
set x = xu + aoe * Cos(3.14159)
set y = yu + aoe * Sin(3.14159)
set sfx3 = AddSpecialEffect(AOE_SFX,x,y)
call BlzSetSpecialEffectYaw(sfx3,270.00 * bj_DEGTORAD)
call BlzSetSpecialEffectHeight(sfx3,z + 80)
call BlzSetSpecialEffectScale(sfx3,1.00)
call BlzSetSpecialEffectTimeScale(sfx3,0.60)
set x = xu + aoe * Cos(4.71239)
set y = yu + aoe * Sin(4.71239)
set sfx4 = AddSpecialEffect(AOE_SFX,x,y)
call BlzSetSpecialEffectHeight(sfx4,z + 80)
call BlzSetSpecialEffectYaw(sfx4,0)
call BlzSetSpecialEffectScale(sfx4,1.00)
call BlzSetSpecialEffectTimeScale(sfx4,0.60)
set size = 1.00
set cdmg = dmg1
set time = 0
call BlzUnitHideAbility(b.target,SPELL_ID,true)
call UnitAddAbility(b.target,EXTRA_ID)
call UnitMakeAbilityPermanent(b.target,true,EXTRA_ID)
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set eva = true
call BonusStruct.AddSpecial(BONUS_TYPE_EVASION,b.target,SUP_EVASION,0)
endif
set sr = false
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Sharpstorm"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,BUFF_DURATION,Sharpstorm.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function callback takes nothing returns nothing
local timer t = GetExpiredTimer()
call UnitRemoveAbility(GetUnitByIndex(GetTimerData(t)),'BNms')
call ReleaseTimer(t)
set t = null
endfunction
private function OnOrder takes nothing returns nothing
local unit u = GetOrderedUnit()
local Sharpstorm b = GetUnitBuff(u,Sharpstorm.buff).buffAllocIndex
if b != 0 then
if GetIssuedOrderId() == ORDER_manashieldon then
call TimerStart(NewTimerEx(GetUnitUserData(u)),0,false,function callback)
if b.mode == 1 then
set b.mode = 2
set b.isChanging = true
if GetHeroMasteryType(u) == 1 then
set b.sr = true
call AddUnitNegativeStatusReduction(u,MA_SRED,false)
endif
else
set b.mode = 1
set b.isChanging = true
if b.sr then
call AddUnitNegativeStatusReduction(u,-MA_SRED,false)
set b.sr = false
endif
endif
endif
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local trigger t
if GetUnitAbilityLevel(u,SPELL_ID) == 1 then
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t,function OnOrder)
set t = null
endif
set u = null
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Sharpstorm b
if data.dmgType != udg_DamageTypeAttack and data.damageMod != 0 then
set b = GetUnitBuff(data.target,Sharpstorm.buff).buffAllocIndex
if b != 0 then
if b.mode == 1 then
call CodeDamage.Damage(data.target,data.source,data.damageMod * 0.25,data.dmgType,"",0,0)
endif
endif
endif
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
if a != 0 then
call a.addManaCost(UP_MANA,0)
endif
endif
if up.upID == 'WDI4' then
if up.level == 1 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,up.ownerHero.hero,5 * Players[GetPlayerId(GetOwningPlayer(up.ownerHero.hero))].kills,0,false)
endif
if GetHeroMasteryType(up.ownerHero.hero) == 1 then
call DamageEvent.RegisterDamage(Filter(function OnDamage))
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Sharpstorm.Initialize()
call SharpstormSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Warden_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(AOE_SFX)
endfunction
endscope
scope Riposte initializer init
globals
private constant integer SPELL_ID = 'WDA2'
private constant integer UPGRADE_ID = 'WDI2'
private constant integer DMG_BASE = 30
private constant integer DMG_LEVEL = 20
private constant real CD_BASE = 10.00
private constant real CD_LEVEL = 1.00
private constant integer UP_DMG = 20
private constant real MA_RANGE = 300.00
private constant string HIT_SFX = "war3mapImported\\Coup de Grace.mdx"
endglobals
private function GetDmg takes integer lvl returns integer
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private function GetCd takes integer lvl returns real
return CD_BASE - CD_LEVEL * lvl
endfunction
struct Riposte extends array
integer dmg
integer as
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int == 1 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
else
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
if GetUpgradeSkillLevel(b.target,UPGRADE_ID) != 0 then
call UnitAddBuff(b.target,b.target,3.00,Riposte.buff,b.level,1)
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int == 1 then
set as = 10 * GetUpgradeSkillLevel(b.target,UPGRADE_ID)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
else
set dmg = GetDmg(b.level) + UP_DMG * GetUpgradeSkillLevel(b.target,UPGRADE_ID)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Riposte"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType == udg_DamageTypeAttack and data.mainAttack then
set b = GetUnitBuff(data.source,Riposte.buff)
if b != 0 then
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
set data.trueCritical = true
endif
endif
endif
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType == udg_DamageTypeAttack and data.mainAttack then
set b = GetUnitBuff(data.source,Riposte.buff)
if b != 0 then
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,data.target,"chest"))
call UnitRemoveBuff(data.source,Riposte.buff)
endif
set b = GetUnitBuff(data.target,FierceWill.buff)
if b != 0 and not data.isMiss then
if data.source == b.owner then
call b.restart()
endif
endif
endif
endfunction
private function OnOrder takes nothing returns nothing
local unit u = GetOrderedUnit()
local unit t = GetOrderTargetUnit()
local integer id = GetIssuedOrderId()
local effect sfx
local real x
local real y
local real xt
local real yt
local real a
local real d
local real max
local real min
local real cd
local integer lvl
if id == ORDER_smart or id == ORDER_attack then
if IsUnitEnemy(t,GetTriggerPlayer()) and t != null and BlzGetUnitAbilityCooldownRemaining(u,SPELL_ID) == 0 then
set x = GetUnitX(u)
set y = GetUnitY(u)
set xt = GetUnitX(t)
set yt = GetUnitY(t)
set a = GetUnitFacing(t) * bj_DEGTORAD
set d = Distance(x,y,xt,yt)
set lvl = GetUnitAbilityLevel(u,SPELL_ID)
set cd = GetCd(lvl)
set max = 700.00
set min = 200.00
if GetHeroMasteryType(u) == 2 then
set max = max + MA_RANGE
endif
if d >= min and d <= max then
if UnitHasBuff(t,FierceWill.buff) and GetHeroMasteryType(u) == 2 then
call BlzStartUnitAbilityCooldown(u,SPELL_ID,1.50)
else
call BlzStartUnitAbilityCooldown(u,SPELL_ID,cd)
endif
set sfx = AddSpecialEffect("war3mapImported\\SFX_MotionBlur.mdx",x,y)
call BlzSetSpecialEffectScale(sfx,0.50)
call DestroyEffect(sfx)
set sfx = null
call SetUnitX(u,xt + 75 * Cos(a))
call SetUnitY(u,yt + 75 * Sin(a))
call BlzSetUnitFacingEx(u,(a * bj_RADTODEG) + 180)
call SetUnitAnimationByIndex(u,8)
call UnitAddBuff(u,u,3.00,Riposte.buff,lvl,0)
endif
endif
endif
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
local trigger t
if GetUnitAbilityLevel(u,SPELL_ID) == 1 then
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t,function OnOrder)
set t = null
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call RegisterSpellLearn(SPELL_ID, function onLearn)
call Riposte.Initialize()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Warden_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope SplinterBlades initializer init
globals
private constant integer SPELL_ID = 'WDA3'
private constant integer UPGRADE_ID = 'WDI3'
private constant real DMG_BASE = 80.00
private constant real DMG_LEVEL = 40.00
private constant real AOE = 500.00
private constant real BUFF_DURATION = 7.00
private constant real CD_REDUCTION = 1.50
private constant real UP_AOE = 50.00
private constant integer SUP_MS = 50
private constant real MA_DURATION = 1.5
private constant string MISSILE_SFX = "Abilities\\Spells\\NightElf\\FanOfKnives\\FanOfKnivesMissile.mdl"
private constant string TARGET_SFX = "war3mapImported\\VorpalMiniBlades.MDX"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
struct SplinterBlades extends array
effect sfx
real sx
real sy
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
if Distance(x,y,sx,sy) >= 400.00 then
set b.removeInside = true
call SplinterBlades_SetupMissile.evaluate(b.owner,b.target,b.owner,b.level,2)
call Status.Add(STATUS_STUN,b.target,0.75 + 0.25 * b.level,Status_EFFECT[STATUS_STUN])
if IsUpgradeSuperior(b.owner,UPGRADE_ID) then
call CodeDamage.Damage(b.target,b.owner,GetDamage(b.level),udg_DamageTypePure,"",0,0)
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set sfx = AddSpecialEffectTarget(TARGET_SFX,b.target,"chest")
set sx = GetUnitX(b.target)
set sy = GetUnitY(b.target)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Splinter Blades"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct EnvenomedDaggerMissile extends array
private static method onFinish takes Missile missile returns boolean
local Ability a
if missile.data == 1 then
if not TriggerSpellNegation(missile.target) then
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypePure,"",0,0)
else
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeMagicAoe,"",0,0)
endif
if IsUnitType(missile.target,UNIT_TYPE_HERO) and not UnitHasBuff(missile.target,SplinterBlades.buff) then
call UnitAddBuff(missile.target,missile.source,BUFF_DURATION,SplinterBlades.buff,missile.level,0)
endif
endif
else
set a = Ability.GetUnitAbilityByID(SPELL_ID,missile.source)
if a != 0 then
call a.addCooldownRemaining(-CD_REDUCTION)
endif
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit sourceM, unit target, integer lvl, integer op returns Missile
local real xs = GetUnitX(sourceM)
local real ys = GetUnitY(sourceM)
local real a = Angle(xs,ys,GetUnitX(target),GetUnitY(target))
local Missile missile = Missile.create(xs,ys,75.00,a,20.00,75.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl)
set missile.speed = 27.00
set missile.level = lvl
set missile.model = MISSILE_SFX
set missile.scale = 1.1
set missile.data = op
call EnvenomedDaggerMissile.launch(missile)
return missile
endfunction
public function SpellTrigger takes unit u returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local real aoe = AOE + UP_AOE * ulvl
local unit temp
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),aoe,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call SetupMissile(u,u,temp,lvl,1)
endif
endloop
call ReleaseGroup(g)
set g = null
set u = null
set p = null
endfunction
private function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SplinterBlades.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Warden_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope FierceWill initializer init
globals
private constant integer SPELL_ID = 'WDA4'
private constant integer UPGRADE_ID = 'WDI4'
private constant integer AS_BASE = 20
private constant integer AS_LEVEL = 10
private constant integer DMG_BASE = 30
private constant integer DMG_LVL = 10
private constant real BUFF_DURATION = 3.50
private constant real UP_DURATION = 1.00
private constant string AURA_SFX = "war3mapImported\\VoidSkullAura_v5.mdx"
endglobals
private function GetAS takes integer lvl returns integer
return AS_BASE + AS_LEVEL * lvl
endfunction
private function GetDmg takes integer lvl returns integer
return DMG_BASE + DMG_LVL * lvl
endfunction
struct FierceWill extends array
integer as
integer dmg
effect sfx1
effect sfx2
real time
boolean wm
Lightning light
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.owner,-dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.owner,-as,0,true)
call light.destroy()
call BlzSetSpecialEffectAlpha(sfx1,0)
call BlzSetSpecialEffectAlpha(sfx2,0)
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
call SetUnitData(b.owner,"FW_Buff",0)
set sfx1 = null
set sfx2 = null
set AIWD.RTarget = null
if not UnitAlive(b.target) and GetUpgradeSkillLevel(b.owner,UPGRADE_ID) != 0 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.owner,5,0,false)
endif
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if not UnitAlive(b.owner) then
set b.removeInside = true
endif
if wm then
set time = time + 0.03125
if time >= 1.75 then
set time = 0
call SplinterBlades_SpellTrigger.evaluate(b.owner)
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = GetAS(b.level)
set dmg = GetDmg(b.level)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.owner,dmg,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.owner,as,0,true)
set light = Lightning.create("WHCH",b.owner,b.target,99999,0.00,120,120)
call light.setLightColor(200,25,225,255)
set sfx1 = AddSpecialEffectTarget(AURA_SFX,b.target,"origin")
set sfx2 = AddSpecialEffectTarget(AURA_SFX,b.owner,"origin")
call SetUnitData(b.owner,"FW_Buff",b)
set AIWD.RTarget = b.target
set wm = GetHeroMasteryType(b.owner) == 3
set time = 0
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Fierce Will"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function OnPostDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if GetUnitAbilityLevel(data.target,SPELL_ID) != 0 and not data.isAbsorbed then
set b = GetUnitData(data.target,"FW_Buff")
if b != 0 then
if data.source != b.target then
set data.isAbsorbed = true
set data.damageMod = 0
endif
endif
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = BUFF_DURATION
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set d = d + UP_DURATION
endif
call UnitAddBuff(GetSpellTargetUnit(),u,d,FierceWill.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FierceWill.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPostCalculation(Filter(function OnPostDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,Warden_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library BanditChampion initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HBC1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'BCI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Stealth Assassin"
set up.Text = "|c00b4b4b4Shadow Chase|r also increases Attack Damage based on the proximity."
set up.SupText = "Increases |c00b4b4b4Shadow Chase|r duration by 1s."
set up.LevelData1 = "20 Max Damage"
set up.LevelData2 = "30 Max Damage"
set up.LevelData3 = "40 Max Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAbility_Stealth.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'BCI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Bandit Aim"
set up.Text = "Increases |c00b4b4b4Throw Dagger|r max stacks."
set up.SupText = "|c00b4b4b4Throw Dagger|r makes attack damage that apply on-attack effects."
set up.LevelData1 = "+1 Stack"
set up.LevelData2 = "+2 Stack"
set up.LevelData3 = "+3 Stack"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThoriumRanged.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'BCI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Killing Techniques"
set up.Text = "|cffb4b4b4Silent Rush|r stacks also adds a bonus |cffffff95Attack Strength|r rating."
set up.SupText = "Increases |cffb4b4b4Silent Rush|r max stacks by 5."
set up.LevelData1 = "10(1.5%) Attack Strength"
set up.LevelData2 = "15(2.3%) Attack Strength"
set up.LevelData3 = "20(3.1%) Attack Strength"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNCloakOfFlames.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'BCI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Deadly Assassin"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HBC1'
set d.Name = "Bandit Champion"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNBanditChamp.blp"
set d.WinAni = "stand first"
set d.Block = 0
set d.Evasion = 40
set d.Resistance = 10
set d.LifeRegen = 1.0
set d.ManaRegen = 1.0
set d.Armor = 4
set d.AttackRange = 125
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'BCA1'
set d.HeroAbility2 = 'BCA2'
set d.HeroAbility3 = 'BCA3'
set d.HeroAbility4 = 'BCA4'
set d.HeroAbility6 = 'A00D'
set d.ChooseIconID = 'c001'
set d.ChooseDummy = 'dh02'
set d.spellDamageLevel = 4
set d.attackDamageLevel = 8
set d.healingLevel = 0
set d.survivavilityLevel = 4
set d.movementLevel = 2
set d.crowdControlLevel = 2
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HBCI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ShadowChase initializer init
globals
private constant integer SPELL_ID = 'BCA1'
private constant integer UPGRADE_ID = 'BCI1'
private constant real BUFF_DURATION = 4.00
private constant integer MAX_MS_BASE = 50
private constant integer MAX_MS_LVL = 20
private constant real DMG_BASE = 60.00
private constant real DMG_INC = 40.00
private constant real STUN_DURATION = 1.00
private constant integer MAX_DMG_BASE = 10
private constant integer MAX_DMG_LVL = 10
private constant real SUP_DURATION = 1.00
private constant string HIT_EFFECT = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl"
private constant string BUFF_EFFECT = "war3mapImported\\BlackCloudOfFog.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_INC * lvl
endfunction
private function GetMsFactor takes integer lvl returns integer
return MAX_MS_BASE + MAX_MS_LVL * lvl
endfunction
private function GetDmgFactor takes integer lvl returns integer
return MAX_DMG_BASE + MAX_DMG_LVL * lvl
endfunction
struct ShadowChase extends array
Movespeed ms
integer dmg
integer msFactor
integer dmgFactor
boolean hit
effect sfx
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Remove(STATUS_GHOST,b.target)
if ms != 0 then
call ms.destroy()
endif
if dmg != 0 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endif
call DestroyEffect(sfx)
call UnitRemoveAbility(b.target,'Apiv')
call UnitMakeAbilityPermanent(b.target,true,'Apiv')
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local group g = NewGroup()
local unit temp
local player p = GetOwningPlayer(b.target)
local real r
local real dist = 1000.00
local integer c
local integer sw = 0
call BlzSetSpecialEffectX(sfx,x)
call BlzSetSpecialEffectY(sfx,y)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 100.00)
call GroupEnumUnitsInRange(g,x,y,1000.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ENEMY(temp,p) then
set r = Distance(x,y,GetUnitX(temp),GetUnitY(temp))
if r <= dist then
set dist = r
set sw = 1
endif
endif
endloop
call ReleaseGroup(g)
if dist == 1000 then
set c = 1
else
set c = (R2I(dist / 100) - 10)
set c = c * -1
endif
if c != 0 and c <= 10 then
if ms != 0 then
call ms.destroy()
endif
set ms = Movespeed.create(b.target,0,msFactor * c)
if dmgFactor != 0 then
if dmg != 0 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endif
set dmg = dmgFactor * c
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
endif
endif
if sw == 0 then
call ms.destroy()
set ms = 0
if dmgFactor != 0 then
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
set dmg = 0
endif
endif
set g = null
set p = null
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
set sfx = AddSpecialEffect(BUFF_EFFECT,GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectTimeScale(sfx,2.0)
set msFactor = GetMsFactor(b.level) / 10
if ulvl != 0 then
set dmgFactor = GetDmgFactor(ulvl) / 10
else
set dmgFactor = 0
endif
call Status.Add(STATUS_GHOST,b.target,0,0)
set ms = 0
set dmg = 0
set hit = false
call UnitAddAbility(b.target,'Apiv')
set b.int = GetHeroMasteryType(b.target)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'STB1'
set BUFF_DATA.BuffID = 'BSA1'
set BUFF_DATA.Name = "Shadow Chase"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.10
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onAttack takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local ShadowChase b
local SilentRush b2
local real dmg
if data.dmgType == udg_DamageTypeAttack and not data.isMiss and data.allowOrbs then
set b = GetUnitBuff(data.source,ShadowChase.buff).buffAllocIndex
if b != 0 then
if not b.hit then
if not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) and not IsUnitType(data.target,UNIT_TYPE_MECHANICAL) then
set lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
set dmg = GetDamage(lvl)
call DestroyEffect(AddSpecialEffectTarget(HIT_EFFECT,data.source,"weapon"))
call DestroyEffect(AddSpecialEffectTarget(HIT_EFFECT,data.target,"head"))
set b.hit = true
call CodeDamage.Damage(data.source,data.target,dmg,udg_DamageTypePhysical,"ShadowChase",0,0)
call Status.Add(STATUS_STUN,data.target,STUN_DURATION,Status_EFFECT[STATUS_STUN])
endif
endif
endif
endif
if data.dmgType == udg_DamageTypePhysical or data.dmgType == udg_DamageTypeAttack then
set lvl = GetUnitAbilityLevel(data.source,'BCA3')
if lvl != 0 then
if data.isCritical then
call UnitAddBuff(data.source,data.source,SilentRush_BUFF_DURATION,SilentRush.buff,lvl,0)
endif
call UnitAddBuff(data.source,data.source,SilentRush_BUFF_DURATION,SilentRush.buff,lvl,0)
endif
endif
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
local BuffData bd
if up.UpId == 'BCI4' then
if GetHeroMasteryType(up.ownerHero.hero) == 2 then
set a = Ability.GetUnitAbilityByID('A00D',up.ownerHero.hero)
call a.addFlatCooldown(-25)
endif
endif
if up.UpId == 'BCI2' then
set bd = ThrowDagger.buff
set bd.StackMax = bd.StackMax + 1
endif
if up.UpId == 'BCI3' and up.isSuperior then
set bd = SilentRush.buff
set bd.StackMax = bd.StackMax + 5
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = BUFF_DURATION
if IsUpgradeSuperior(u,UPGRADE_ID) then
set d = d + SUP_DURATION
endif
call UnitAddBuff(u,u,d,ShadowChase.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ShadowChase.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDamage(Filter(function onAttack))
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,BanditChampion_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('STB1',PRELOAD_SECOND)
call Preload(HIT_EFFECT)
endfunction
endscope
scope ThrowDagger initializer Init
globals
private constant integer SPELL_ID = 'BCA2'
private constant integer UPGRADE_ID = 'BCI2'
private constant real DAMAGE_BASE = 40.00
private constant real DAMAGE_LEVEL = 10.00
private constant string MISSILE_MODEL = "Models\\SpinningKnife.mdx"
private constant string MISSILE_IMPACT_SFX = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
private constant real MISSILE_HEIGHT = 45.00
private constant real MISSILE_SPEED = 31.00
private constant real MISSILE_SCALE = 1.25
private integer BUFF_MAX_STACK = 4
private real BUFF_DURATION = 8.00
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct ThrowDagger extends array
public static method onStackRemove takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,1,0,true)
endmethod
public static method onStackApply takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-1,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'TAB1'
set BUFF_DATA.BuffID = 'BTAA'
set BUFF_DATA.Name = "Throw Dagger"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = BUFF_MAX_STACK
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private struct ThrowWeaponMissile extends array
private static method onFinish takes Missile missile returns boolean
local DamageOptions op
if UnitAlive(missile.target) then
if not TriggerSpellNegation(missile.target) then
call DestroyEffect(AddSpecialEffectTarget(MISSILE_IMPACT_SFX,missile.target,"chest"))
call UnitAddBuff(missile.target,missile.source,BUFF_DURATION,ThrowDagger.buff,missile.level,0)
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
set op = DamageOptions.create()
set op.allowOrbs = true
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeAttack,"ThrowDagger",0,op)
else
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypePhysical,"ThrowDagger",0,0)
endif
endif
if TriggerSpellReflection(missile.target) then
call ThrowDagger_SetupMissile.evaluate(missile.target,missile.source,missile.level)
endif
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),MISSILE_HEIGHT,AngleBetweenUnits(source,target),0,MISSILE_HEIGHT)
local real agi = 0.7
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.target = target
if GetHeroMasteryType(source) == 3 then
set agi = 1.4
endif
set missile.damage = GetDamage(lvl) + GetHeroAgi(source,true) * agi
set missile.level = lvl
set missile.speed = MISSILE_SPEED
set missile.scale = MISSILE_SCALE
set missile.model = MISSILE_MODEL
call ThrowWeaponMissile.launch(missile)
return missile
endfunction
private function onDoubleCast takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
call SetupMissile(tb.unit[0],tb.unit[1],tb.integer[2])
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set t = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local timer tr
local Table tb
call SetupMissile(u,t,lvl)
if GetRandomInt(1,100) <= (20 + 10 * lvl) or GetHeroMasteryType(u) == 3 then
set tb = Table.create()
set tr = NewTimerEx(tb)
set tb.unit[0] = u
set tb.unit[1] = t
set tb.integer[2] = lvl
call TimerStart(tr,0.5,false,function onDoubleCast)
set tr = null
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ThrowDagger.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function Init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,'HBC1')
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('TAB1',PRELOAD_SECOND)
call Preload(MISSILE_MODEL)
call Preload(MISSILE_IMPACT_SFX)
endfunction
endscope
scope SilentRush initializer Init
globals
private constant integer SPELL_ID = 'BCA3'
private constant integer UPGRADE_ID = 'BCI3'
private constant integer ATC_SPEED_BASE = 2
private constant integer ATC_SPEED_LEVEL = 2
public constant real BUFF_DURATION = 5.00
private constant integer ST_BONUS_BASE = 5
endglobals
private function GetSurvivalBonus takes integer uplvl returns integer
return ST_BONUS_BASE + ST_BONUS_BASE * uplvl
endfunction
private function GetASBonus takes integer lvl returns integer
return ATC_SPEED_BASE + ATC_SPEED_LEVEL * lvl
endfunction
struct SilentRush extends array
integer as
real sbonus
boolean sbonuses
private static method onStackRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Ability a
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
if sbonuses then
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,-sbonus,0)
endif
set a = GetHeroAbilityById(b.target,SPELL_ID)
call a.abilityNumber.setValue(GetUnitBuff(b.target,SilentRush.buff).stacks - 1)
endmethod
private static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
local Ability a
set as = GetASBonus(b.level)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
if ulvl != 0 then
set sbonuses = true
set sbonus = GetSurvivalBonus(ulvl)
call BonusStruct.AddSpecial(BONUS_TYPE_ATTACK_STRENGTH,b.target,sbonus,0)
else
set sbonuses = false
endif
set a = GetHeroAbilityById(b.target,SPELL_ID)
call a.abilityNumber.setValue(GetUnitBuff(b.target,SilentRush.buff).stacks)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'SRBA'
set BUFF_DATA.BuffID = 'BSRA'
set BUFF_DATA.Name = "Silent Rush"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_INDEPENDENT
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 15
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local integer lvl = GetLearnedSkillLevel()
local Ability a
if lvl == 1 then
set a = GetHeroAbilityById(u,SPELL_ID)
set a.abilityNumber = AbilityNumber.create(a.objectID,u)
call a.abilityNumber.setValue(0)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call SilentRush.Initialize()
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function Init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,'HBC1')
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('SRBA',PRELOAD_SECOND)
call PreloadGen.Add('ABST',PRELOAD_SECOND)
endfunction
endscope
scope MarkedForDeath initializer Init
globals
private constant integer SPELL_ID = 'BCA4'
private constant integer UPGRADE_ID = 'BCI4'
private constant real CRIT_BASE = 10.00
private constant real CRITAT_BASE = 0.06
private constant real CRITAT_LEVEL = 0.02
private constant real BUFF_DURATION = 15.00
endglobals
private function GetCriticalAttack takes integer lvl returns real
return CRITAT_BASE + CRITAT_LEVEL * lvl
endfunction
private function GetCriticalFactor takes integer lvl returns real
return CRIT_BASE * lvl
endfunction
struct MarkedForDeath extends array
real criticalA
real critical
public static method onRemove takes Buff b returns nothing
call Status.Remove(STATUS_SPY,b.target)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call Status.Add(STATUS_SPY,b.target,BUFF_DURATION,0)
set criticalA = GetCriticalAttack(b.level)
set critical = GetCriticalFactor(b.level)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A025'
set BUFF_DATA.BuffID = 'BPA1'
set BUFF_DATA.Name = "Marked for Death"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.PierceImmune = true
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onDamage takes nothing returns nothing
local DamageData d = DamageEvent.EventData
local MarkedForDeath b = GetUnitBuff(d.target,MarkedForDeath.buff).buffAllocIndex
local Buff b2
local real a1
local real a2
local real c
if b != 0 then
if d.dmgType == udg_DamageTypePhysical or d.dmgType == udg_DamageTypePhysicalAoe or d.dmgType == udg_DamageTypePhysicalOverTime then
set d.criticalChanceAdd = d.criticalChanceAdd + b.critical
elseif d.dmgType == udg_DamageTypeAttack then
set d.criticalChanceAdd = d.criticalChanceAdd + b.criticalA
endif
endif
set b2 = GetUnitBuff(d.source,ShadowChase.buff)
if b2 != 0 then
if b2.int == 1 then
set a1 = Angle(GetUnitX(d.source),GetUnitY(d.source),GetUnitX(d.target),GetUnitY(d.target))
set a2 = GetUnitFacing(d.target) * bj_DEGTORAD
if Acos(Cos(a1 - a2)) * bj_RADTODEG <= 90 then
set d.mult = d.mult + 0.10
endif
endif
endif
set b2 = GetUnitBuff(d.target,ShadowChase.buff)
if b2 != 0 then
if b2.int == 1 then
set a1 = Angle(GetUnitX(d.target),GetUnitY(d.target),GetUnitX(d.source),GetUnitY(d.source))
set a2 = GetUnitFacing(d.target) * bj_DEGTORAD
if Acos(Cos(a1 - a2)) * bj_RADTODEG <= 90 then
set d.mult = d.mult - 0.20
endif
endif
endif
endfunction
private function SpellTrigger takes unit u, unit t, integer lvl returns nothing
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
call UnitAddBuff(t,u,9999999,MarkedForDeath.buff,lvl,0)
else
call UnitAddBuff(t,u,BUFF_DURATION,MarkedForDeath.buff,lvl,0)
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local integer lvl = GetLearnedSkillLevel()
local Ability a
if lvl == 1 then
call UnitAddAbility(u,'A00D')
call UnitMakeAbilityPermanent(u,true,'A00D')
set a = Ability.GetUnitAbilityByID('A00D',u)
if a != 0 then
call a.updateTooltip(true)
endif
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call MarkedForDeath.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call DamageEvent.RegisterPreCalculation(Filter(function onDamage))
endfunction
private function Init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,'HBC1')
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('PBA1',PRELOAD_SECOND)
call PreloadGen.Add('A025',PRELOAD_SECOND)
endfunction
endscope
scope Assault initializer init
globals
private constant integer SPELL_ID = 'A00D'
private constant string BT_EFFECT = "Abilities\\Spells\\Items\\AIil\\AIilTarget.mdl"
endglobals
private function SpellTrigger takes unit u, unit t, boolean ally returns nothing
local real a = GetUnitFacing(t) - 180
local real x
local real y
set x = GetUnitX(t) + 75 * Cos(a * bj_DEGTORAD)
set y = GetUnitY(t) + 75 * Sin(a * bj_DEGTORAD)
call SetUnitX(u,x)
call SetUnitY(u,y)
call DestroyEffect(AddSpecialEffect(BT_EFFECT,x,y))
if not ally then
call IssueTargetOrder(u,"attack",t)
endif
if GetHeroMasteryType(u) == 2 then
call DispelMovilityStatus(u)
call UnitDispelAllBuffsType(u,EFFECT_TYPE_SLOW)
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local boolean ally = IsUnitAlly(t,GetTriggerPlayer())
if not TriggerSpellNegation(t) and not ally then
call SpellTrigger(u,t,ally)
else
call SpellTrigger(u,t,ally)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "D"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,BanditChampion_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(BT_EFFECT)
endfunction
endscope
library DemonGuard initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HDG1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'DGI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Infernal Steel"
set up.Text = "Reduces |c00b4b4b4Doom Blade|r cooldown."
set up.SupText = "Increases |c00b4b4b4Doom Blade|r Cast Range/Distance by 300."
set up.LevelData1 = "-1s Cooldown"
set up.LevelData2 = "-2s Cooldown"
set up.LevelData3 = "-3s Cooldown"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNShockWave.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'DGI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Incineration"
set up.Text = "Increases the area of effect of |c00b4b4b4Flaming Cuirass|r."
set up.SupText = "Adds 2 seconds duration to |c00b4b4b4Flaming Cuirass|r"
set up.LevelData1 = "100 AoE"
set up.LevelData2 = "150 AoE"
set up.LevelData3 = "200 AoE"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNFlare.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'DGI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Demon Edict"
set up.Text = "|c00b4b4b4Demonic Hand|r also reduces the |c0000ff00Healing|r that the enemies do by a %."
set up.SupText = "Increases |c00b4b4b4Demonic Hand|r max count by 1."
set up.LevelData1 = "10% Healing Reduction"
set up.LevelData2 = "20% Healing Reduction"
set up.LevelData3 = "30% Healing Reduction"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNGuldanSkull.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'DGI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Evil Stratagems"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HDG1'
set d.Name = "Demon Guard"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNKazzakIon.blp"
set d.WinAni = "stand victory"
set d.Block = 40
set d.Evasion = 0
set d.Resistance = 40
set d.LifeRegen = 2.5
set d.ManaRegen = 1.0
set d.Armor = 4
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'DGA1'
set d.HeroAbility2 = 'DGA2'
set d.HeroAbility3 = 'DGA3'
set d.HeroAbility4 = 'DGA4'
set d.ChooseIconID = 'c003'
set d.ChooseDummy = 'dh05'
set d.spellDamageLevel = 7
set d.attackDamageLevel = 1
set d.healingLevel = 0
set d.survivavilityLevel = 6
set d.movementLevel = 1
set d.crowdControlLevel = 2
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HDGI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope DoomBlade initializer init
globals
private constant integer SPELL_ID = 'DGA1'
private constant integer SPELL_DUMMY_ID = 'A027'
private constant integer UPGRADE_ID = 'DGI1'
private constant real DMG_BASE = 70.00
private constant real DMG_LVL = 40.00
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local unit h
local real d
local integer lvl
local integer dhlvl
local integer count
local integer max
if GetUnitAbilityLevel(data.source,SPELL_DUMMY_ID) > 0 then
set h = GetUnitByIndex(GetDummyData(data.source,"caster"))
set lvl = GetUnitAbilityLevel(h,SPELL_ID)
set dhlvl = GetUnitAbilityLevel(h,'DGA3')
set d = GetDamage(lvl)
if dhlvl != 0 and IsUnitType(data.target,UNIT_TYPE_HERO)then
call DemonicHand_SetupMissile.evaluate(h,data.target,dhlvl)
endif
call CodeDamage.Damage(h,data.target,d,udg_DamageTypeMagicAoe,"DoomBlade",0,0)
set h = null
endif
endfunction
private function SpellTrigger takes unit u, real x, real y returns nothing
local unit d = Ability.GetUnitAbilityByID(SPELL_ID,u).auxDummy
call SetUnitX(d,GetUnitX(u))
call SetUnitY(d,GetUnitY(u))
call UnitAddAbility(d,SPELL_DUMMY_ID)
if IsUpgradeSuperior(u,UPGRADE_ID) then
call SetUnitAbilityLevel(d,SPELL_DUMMY_ID,2)
endif
call SetDummyData(d,"caster",GetUnitUserData(u))
call CastDummyWave(d,ORDER_carrionswarm,x,y)
set d = null
endfunction
public function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.activationType = ACTIVATION_TYPE_POINT
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.UseAuxDummy = true
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DemonGuard_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(SPELL_DUMMY_ID,PRELOAD_FIRST)
call PreloadGen.Add('A00O',PRELOAD_SECOND)
endfunction
endscope
scope FlamingCuirass initializer init
globals
private constant integer SPELL_ID = 'DGA2'
private constant integer UPGRADE_ID = 'DGI2'
private constant real DMG_BASE = 35.00
private constant real DMG_LVL = 15.00
private constant real SLOW_PERCENT = 0.40
private constant integer ARMOR_BONUS = 8
private constant integer ARMOR_BONUS_LVL = 2
private constant real BUFF_DURATION = 4.00
private constant string CASTER_SFX = "Abilities\\Spells\\Other\\ImmolationRed\\ImmolationRedTarget.mdl"
private constant string AREA_SFX = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
private constant string CAST_SFX = "war3mapImported\\HellonEarth.mdx"
endglobals
private function GetArmor takes integer lvl returns integer
return ARMOR_BONUS + ARMOR_BONUS_LVL * lvl
endfunction
public function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == 'DGI1' then
set a = Ability.GetUnitAbilityByID('DGA1',up.ownerHero.hero)
call a.addFlatCooldown(-1)
if up.isSuperior then
call a.addCastRange(300)
endif
endif
endfunction
struct FlamingCuirassSlow extends array
Movespeed m
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call m.destroy()
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,40,0,true)
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real ms = SLOW_PERCENT
set m = Movespeed.create(b.target,-ms,0)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-40,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00S'
set BUFF_DATA.BuffID = 'B006'
set BUFF_DATA.Name = "FlamingCuirass"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct FlamingCuirass extends array
group g
integer armor
real area
effect sfx
boolean cm
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ReleaseGroup(g)
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-armor,0,true)
call DestroyEffect(sfx)
if cm then
call AddUnitNegativeStatusReduction(b.target,0,false)
endif
set g = null
set sfx = null
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local player p = GetOwningPlayer(b.owner)
local integer c = 12
local real a = 0
local real dmg = GetDamage(b.level)
local real xoff
local real yoff
local unit temp
local real ar = area
local boolean h = false
loop
exitwhen c == 0
loop
exitwhen ar <= 0
set xoff = x + ar * Cos(a * bj_DEGTORAD)
set yoff = y + ar * Sin(a * bj_DEGTORAD)
call DestroyEffect(AddSpecialEffect(AREA_SFX,xoff,yoff))
set ar = ar - 100
endloop
set ar = area
set a = a + 30
set c = c - 1
endloop
call GroupEnumUnitsInRange(g,x,y,area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(b.owner,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
if UnitHasBuff(temp,DemonicHand.buff) then
call UnitAddBuff(temp,b.owner,3.0,FlamingCuirassSlow.buff,0,0)
endif
if IsUnitType(temp,UNIT_TYPE_HERO) then
set h = true
endif
endif
endloop
if h and cm then
set b.elapsedTime = b.elapsedTime - 1.0
endif
set p = null
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local effect sfxf = AddSpecialEffect(CAST_SFX,GetUnitX(b.target),GetUnitY(b.target))
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
call BlzSetSpecialEffectScale(sfxf,2.5)
call DestroyEffect(sfxf)
set g = NewGroup()
set armor = GetArmor(b.level)
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,armor,0,true)
set sfx = AddSpecialEffectTarget(CASTER_SFX,b.target,"chest")
if ulvl != 0 then
set area = 300 + (50 + 50 * ulvl)
else
set area = 300
endif
set cm = false
if GetHeroMasteryType(b.owner) == 1 then
call AddUnitNegativeStatusReduction(b.target,0,false)
set cm = true
endif
set sfxf = null
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0B7'
set BUFF_DATA.BuffID = 'B046'
set BUFF_DATA.Name = "FlamingCuirass"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u returns nothing
if IsUpgradeSuperior(u,UPGRADE_ID) then
call UnitAddBuff(u,u,BUFF_DURATION + 2,FlamingCuirass.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
else
call UnitAddBuff(u,u,BUFF_DURATION,FlamingCuirass.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
endif
endfunction
public function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FlamingCuirass.Initialize()
call FlamingCuirassSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DemonGuard_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(CASTER_SFX)
call Preload(AREA_SFX)
endfunction
endscope
scope DemonicHand initializer init
globals
private constant integer SPELL_ID = 'DGA3'
private constant integer DUMMY_ID = 'A00N'
private constant integer UPGRADE_ID = 'DGI3'
private constant real BUFF_DURATION = 7.00
private constant integer DMG_BASE = 20
private constant real SPELL_BASE = 0.10
private constant string TARGET_SFX = "Abilities\\Spells\\Other\\ImmolationRed\\ImmolationRedTarget.mdl"
endglobals
private function GetDamageReduction takes integer lvl returns integer
return DMG_BASE + DMG_BASE * lvl
endfunction
private function GetSpellReduction takes integer lvl returns real
return SPELL_BASE + SPELL_BASE * lvl
endfunction
struct DemonicHand extends array
integer dmg
Link h
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LinkedList list = b.int
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,dmg,0,true)
if list != 0 then
call list.remove(h)
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local LinkedList list = b.int
set h = list.add(b)
set dmg = GetDamageReduction(b.level)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.target,-dmg,0,true)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00Q'
set BUFF_DATA.BuffID = 'B004'
set BUFF_DATA.Name = "Demonic Hand"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private struct DemonicHandMissile extends array
private static method onFinish takes Missile missile returns boolean
local integer max = 3
local LinkedList list
local Buff b
if UnitAlive(missile.target) then
if not TriggerSpellNegation(missile.target) then
set list = GetUnitData(missile.source,"DemonicHandIns")
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
set max = 4
endif
set b = GetUnitBuff(missile.target,DemonicHand.buff)
if b != 0 then
set b.elapsedTime = 0
endif
if list.size < max then
call UnitAddBuff(missile.target,missile.source,BUFF_DURATION,DemonicHand.buff,missile.level,list)
endif
endif
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),50,AngleBetweenUnits(source,target),0,50)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.target = target
set missile.level = lvl
set missile.speed = 30.00
set missile.scale = 1.20
set missile.model = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
call DemonicHandMissile.launch(missile)
return missile
endfunction
private function OnSpellDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local Buff b
if data.dmgType == 1 or data.dmgType == 2 or data.dmgType == 5 or data.dmgType == 6 then
set lvl = GetUnitAbilityLevel(data.target,SPELL_ID)
if lvl != 0 and UnitHasBuff(data.source,DemonicHand.buff) then
set data.mult = data.mult - GetSpellReduction(lvl)
endif
endif
if data.dmgType == udg_DamageTypeHeal or data.dmgType == udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.source,DemonicHand.buff)
set lvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
if b != 0 and lvl != 0 then
set data.mult = data.mult - (0.10 * lvl)
endif
endif
endfunction
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local LinkedList list = GetUnitData(u,"DemonicHandIns")
local Link h = list.head
local Link n
local Buff b
local group g = NewGroup()
local unit temp
local player p = GetOwningPlayer(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
loop
exitwhen h == 0
set b = h.data
set n = h.next
set b.int = 0
call b.remove()
call list.remove(h)
set h = n
endloop
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),600.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call SetupMissile(u,temp,lvl)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local integer lvl = GetLearnedSkillLevel()
if lvl == 1 then
call SetUnitData(u,"DemonicHandIns",LinkedList.create())
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DemonicHand.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call DamageEvent.RegisterPreCalculation(Filter(function OnSpellDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DemonGuard_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A00Q',PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
scope InfernoEruption initializer init
globals
private constant integer SPELL_ID = 'DGA4'
private constant integer UPGRADE_ID = 'DGI4'
private constant real AREA_EFFECT = 300.00
private constant real FIRST_DELAY = 1.20
private constant real SECOND_DELAY = 2.00
private constant real DMG_BASE = 75.00
private constant real DMG_LVL = 75.00
private constant string AREA_SFX = "war3mapImported\\Holy_Fire_Slam.mdx"
private constant string AREA_SFX2 = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function Sfx takes real x, real y returns nothing
local effect sfx = AddSpecialEffect(AREA_SFX2,x,y)
call BlzSetSpecialEffectScale(sfx,1.5)
call BlzSetSpecialEffectColor(sfx,255,0,0)
call DestroyEffect(sfx)
call DestroyEffect(AddSpecialEffect(AREA_SFX,x,y))
set sfx = null
endfunction
private function AoeEffect takes unit u, real x, real y, integer op returns nothing
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local player p = GetOwningPlayer(u)
local group g = NewGroup()
local real dmg = GetDamage(lvl)
local unit temp
local real dist
local real xt
local real yt
local real sd = 0
call Sfx(x,y)
if op == 2 then
set sd = 2.0
elseif op == 3 then
set sd = 1.0
set dmg = dmg / 2
endif
call GroupEnumUnitsInRange(g,x,y,AREA_EFFECT,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
set xt = GetUnitX(temp)
set yt = GetUnitY(temp)
set dist = Distance(xt,yt,x,y)
call KPJUnit.create(temp,245,Angle(x,y,xt,yt),0.40,125,KPJDefaultConfig,KPJ_TYPE_JUMP)
if sd != 0 then
call Status.Add(STATUS_STUN,temp,1.2,Status_EFFECT[STATUS_STUN])
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endfunction
private function Callback2 takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local Link node = DemonicHand.DATAS.head
local Buff b
local integer chance = tb.integer[4]
set AIDG.Ractive = false
loop
exitwhen node == 0
set b = node.data
if b.owner == u then
call AoeEffect(u,GetUnitX(b.target),GetUnitY(b.target),2)
endif
set node = node.next
endloop
if chance != 0 and GetRandomInt(1,100) <= chance then
set tb.integer[4] = chance / 2
call TimerStart(t,SECOND_DELAY,false,function Callback2)
else
call ReleaseTimer(t)
call tb.flush()
call tb.destroy()
endif
set t = null
set u = null
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real x = tb.real[1]
local real y = tb.real[2]
local AoE aoe = tb.integer[3]
call aoe.destroy()
call AoeEffect(u,x,y,1)
call TimerStart(t,SECOND_DELAY,false,function Callback2)
set AIDG.Ractive = true
set u = null
set t = null
endfunction
private function SpellTrigger takes unit u returns nothing
local Table tb = Table.create()
local AoE aoe
local timer t = NewTimerEx(tb)
set aoe = AoE.create(GetSpellTargetX(),GetSpellTargetY(),null,AREA_EFFECT)
call BlzSetSpecialEffectColor(aoe.sfx,255,0,0)
set tb.unit[0] = u
set tb.real[1] = GetSpellTargetX()
set tb.real[2] = GetSpellTargetY()
set tb.integer[3] = aoe
if GetHeroMasteryType(u) == 3 then
set tb.integer[4] = 60
else
set tb.integer[4] = 0
endif
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
call TimerStart(t,0.00,false,function Callback)
if GetHeroMasteryType(u) == 2 then
call SetUnitX(u,tb.real[1])
call SetUnitY(u,tb.real[2])
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl",tb.real[1],tb.real[2]))
endif
else
call TimerStart(t,FIRST_DELAY,false,function Callback)
endif
set t = null
endfunction
public function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DemonGuard_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library DeathSting initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HDS1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'DSI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Furious Clamps"
set up.Text = "Increases the duration of |c00b4b4b4Poisonous Glands|r effect."
set up.SupText = "|c00b4b4b4Poisonous Glands |rgrants 45% |c00ffff95Attack Speed|r bonus."
set up.LevelData1 = "+1 second"
set up.LevelData2 = "+2 seconds"
set up.LevelData3 = "+3 seconds"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAdvancedCreatureCarapace.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'DSI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Acid Venom"
set up.Text = "Increases |c00b4b4b4Corrosive Venom|r Cast Range."
set up.SupText = "|c00b4b4b4Corrosive Venom|r remains in the enemy for 3 seconds additionally."
set up.LevelData1 = "+75 Cast Range"
set up.LevelData2 = "+150 Cast Range"
set up.LevelData3 = "+225 Cast Range"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNPoisonArrow.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'DSI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Underground Attacks"
set up.Text = "Increases |c00b4b4b4Scorpid Attack|r area of effect."
set up.SupText = "Reduces |c00b4b4b4Tunnels|r cooldown by 6 seconds."
set up.LevelData1 = "+50 AoE"
set up.LevelData2 = "+100 AoE"
set up.LevelData3 = "+150 AoE"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNEarthquake.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'DSI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Elite Scorpids"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HDS1'
set d.Name = "Death Sting"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNArachnathid.blp"
set d.WinAni = "spell"
set d.Block = 0
set d.Evasion = 30
set d.Resistance = 30
set d.LifeRegen = 1.5
set d.ManaRegen = 1.5
set d.Armor = 2
set d.AttackRange = 125
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'DSA1'
set d.HeroAbility2 = 'DSA2'
set d.HeroAbility3 = 'DSA5'
set d.HeroAbility4 = 'DSA4'
set d.HeroAbility5 = 'DSA3'
set d.ChooseIconID = 'c004'
set d.ChooseDummy = 'dh03'
set d.spellDamageLevel = 5
set d.attackDamageLevel = 6
set d.healingLevel = 0
set d.survivavilityLevel = 1
set d.movementLevel = 2
set d.crowdControlLevel = 1
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HDSI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope PoisonousGlands initializer init
globals
private constant integer SPELL_ID = 'DSA1'
private constant integer UPGRADE_ID = 'DSI1'
private constant real BUFF_DURATION = 9.00
private constant real BUFF_INTERVAL_DMG = 1.00
private constant integer RESIST_BONUS_BASE = 60
private constant integer RESIST_BONUS_LVL = 20
private constant real DMG_BASE = 8.00
private constant integer MA_AS = 45
endglobals
private function GetDebuffDuration takes integer lvl returns real
return 7.00 + lvl
endfunction
private function GetResistance takes integer lvl returns integer
return RESIST_BONUS_BASE + RESIST_BONUS_LVL * lvl
endfunction
struct PoisonousGlandsDmg extends array
real dmg
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b == GetUnitBuff(b.target,thistype.buff) then
call CodeDamage.Damage(b.owner,b.target,dmg * b.stacks,udg_DamageTypeMagicOverTime,"PoisonousGlands",0,0)
endif
endmethod
public static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Buff b2 = b.prev
set dmg = DMG_BASE
if b2 != 0 then
set b.count = b2.count
set b2.count = 0
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00W'
set BUFF_DATA.BuffID = 'B008'
set BUFF_DATA.Name = "Poisonous Glands Damage"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 9999
set BUFF_DATA.Period = 1.00
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct PoisonousGlands extends array
integer as
integer res
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-res,0)
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
set as = 0
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set res = GetResistance(b.level)
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,res,0)
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set as = MA_AS
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00V'
set BUFF_DATA.BuffID = 'B007'
set BUFF_DATA.Name = "Poisonous Glands"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local boolean st
if data.dmgType == udg_DamageTypeAttack and not data.isMiss then
if data.allowOrbs or data.codeDmg.codeName == "ScorpidAttack" then
set st = not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) and not IsUnitType(data.target,UNIT_TYPE_MECHANICAL)
set b = GetUnitBuff(data.source,PoisonousGlands.buff)
if b != 0 and st then
call UnitAddBuff(data.target,data.source,GetDebuffDuration(b.level),PoisonousGlandsDmg.buff,b.level,0)
endif
endif
set b = GetUnitBuff(data.target,PoisonousGlands.buff)
if b != 0 then
set st = not IsUnitType(data.source,UNIT_TYPE_STRUCTURE) and not IsUnitType(data.source,UNIT_TYPE_MECHANICAL)
if GetHeroMasteryType(data.target) == 1 and st then
call UnitAddBuff(data.source,data.target,GetDebuffDuration(b.level),PoisonousGlandsDmg.buff,b.level,0)
endif
endif
endif
endfunction
private function SpellTrigger takes unit u returns nothing
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local real d = BUFF_DURATION + ulvl
call UnitAddBuff(u,u,d,PoisonousGlands.buff,lvl,0)
endfunction
public function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit())
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call PoisonousGlands.Initialize()
call PoisonousGlandsDmg.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDamage(Filter(function onDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DeathSting_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A00V',PRELOAD_SECOND)
call PreloadGen.Add('A00W',PRELOAD_SECOND)
endfunction
endscope
scope CorrosiveVenom initializer init
globals
private constant integer SPELL_ID = 'DSA2'
private constant integer UPGRADE_ID = 'DSI2'
private constant integer MAX_TICKS = 6
private constant real BUFF_INTERVAL = 0.50
private constant real BUFF_DURATION = 3.00
private constant real DMG_BASE = 10.00
private constant real DMG_LVL = 10.00
private constant real SLOW_PERCENT = 0.12
private constant real SUP_DURATION = 3.00
private constant integer ARMOR = 2
private constant integer MA_AGILITY = 25
private constant string LOOP_SFX = "Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private struct CorrosiveVenomMissile extends array
private static method onFinish takes Missile missile returns boolean
if UnitAlive(missile.target) then
if not TriggerSpellNegation(missile.target) then
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
call UnitAddBuff(missile.target,missile.source,BUFF_DURATION + SUP_DURATION,CorrosiveVenom.buff,missile.level,1)
else
call UnitAddBuff(missile.target,missile.source,BUFF_DURATION,CorrosiveVenom.buff,missile.level,0)
endif
endif
if TriggerSpellReflection(missile.target) and not IsUnitMagicImmune(missile.source) then
call CorrosiveVenom_SpellTrigger.evaluate(missile.target,missile.source,missile.level)
endif
endif
return true
endmethod
implement MissileStruct
endstruct
private function SetupMissile takes unit source, unit target, integer lvl returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),115.00,AngleBetweenUnits(source,target),0,25.00)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.target = target
set missile.level = lvl
set missile.speed = 15.00
set missile.model = LOOP_SFX
set missile.scale = 0.80
call CorrosiveVenomMissile.launch(missile)
return missile
endfunction
struct CorrosiveVenom extends array
real dmg
Movespeed ms
integer agi
integer count
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if count < MAX_TICKS then
set count = count + 1
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,-ARMOR,0,true)
if ms == 0 then
set ms = Movespeed.create(b.target,-SLOW_PERCENT,0)
else
call ms.change(-SLOW_PERCENT * count,0)
endif
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypeMagicOverTime,"CorrosiveVenom",0,0)
call DestroyEffect(AddSpecialEffectTarget(LOOP_SFX,b.target,"chest"))
endif
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ARMOR,b.target,ARMOR * count,0,true)
if agi != 0 then
call BonusStruct.Add(BONUS_TYPE_AGILITY,b.owner,-agi,0,true)
set agi = 0
endif
call ms.destroy()
set ms = 0
set count = 0
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer ulvl = GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
set dmg = GetDamage(b.level)
if GetHeroMasteryType(b.owner) == 2 then
set agi = MA_AGILITY
call BonusStruct.Add(BONUS_TYPE_AGILITY,b.owner,agi,0,true)
endif
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A00X'
set BUFF_DATA.BuffID = 'B009'
set BUFF_DATA.Name = "Corrosive Venom"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = BUFF_INTERVAL
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
public function SpellTrigger takes unit u, unit t, integer lvl returns nothing
call SetupMissile(u,t,lvl)
endfunction
public function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
if not TriggerSpellNegation(t) then
call SpellTrigger(u,t,lvl)
endif
if TriggerSpellReflection(t) and not IsUnitMagicImmune(u) then
call SpellTrigger(t,u,lvl)
endif
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call CorrosiveVenom.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DeathSting_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A00X',PRELOAD_SECOND)
call Preload(LOOP_SFX)
endfunction
endscope
scope ScorpionAmbush initializer init
globals
private constant integer SPELL_ID = 'DSA3'
private constant string HIT_TUNNEL_SFX = "Doodads\\Dungeon\\Terrain\\EggSack\\EggSack0.mdl"
private constant string HIT_TARGET_SFX = "Abilities\\Spells\\Undead\\Impale\\ImpaleHitTarget.mdl"
private constant string AREA_SFX = "Abilities\\Spells\\Undead\\Impale\\ImpaleMissTarget.mdl"
private constant real DAMAGE_BASE = 60
private constant real DAMAGE_LVL = 40
private constant real HEIGHT = 470.00
private constant real AREA = 150.00
private constant real UP_AREA = 50.00
private KPJConfig KPJCONFIG
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LVL * lvl
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local group g = NewGroup()
local unit temp
local player p = GetOwningPlayer(u)
local integer lvl = GetUnitAbilityLevel(u,'DSA2')
local integer ulvl = GetUpgradeSkillLevel(u,'DSI3')
local boolean b = UnitHasBuff(u,Tunnels.buff)
local real dmg = GetDamage(lvl)
local real aoe = AREA + (UP_AREA * ulvl)
local real st
local real a = 0
local real d = aoe / 3
local real xe
local real ye
if b then
call UnitRemoveBuff(u,Tunnels.buff)
call DestroyEffect(AddSpecialEffect(HIT_TUNNEL_SFX,x,y))
call SetUnitAnimation(u,"morph alternate")
endif
loop
exitwhen d >= aoe
loop
exitwhen a >= 360
set xe = x + d * Cos(a*bj_DEGTORAD)
set ye = y + d * Sin(a*bj_DEGTORAD)
call DestroyEffect(AddSpecialEffect(AREA_SFX,xe,ye))
set a = a + 30
endloop
set a = 0
set d = d + d
endloop
call GroupEnumUnitsInRange(g,x,y,aoe,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
set st = Status.Add(STATUS_STUN,temp,1.2,Status_EFFECT[STATUS_STUN])
if st != 0 then
call KPJUnit.create(temp,0,0,0.70,HEIGHT,KPJCONFIG,KPJ_TYPE_JUMP)
endif
if IsUnitType(temp,UNIT_TYPE_HERO) then
if b and lvl != 0 then
call CorrosiveVenom_SpellTrigger(u,temp,lvl)
endif
else
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
call DestroyEffect(AddSpecialEffect(HIT_TARGET_SFX,GetUnitX(temp),GetUnitY(temp)))
endif
endloop
call ReleaseGroup(g)
set g = null
set temp = null
set p = null
set u = null
endfunction
private function ConfigKnock takes nothing returns nothing
set KPJCONFIG = KPJConfig.create()
set KPJCONFIG.friction = 0
set KPJCONFIG.gravity = 0.5
set KPJCONFIG.disable = false
set KPJCONFIG.hardDisable = false
set KPJCONFIG.killTrees = false
set KPJCONFIG.sfxModel = ""
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "D"
set d.activationType = ACTIVATION_TYPE_INSTANT
set d.UseAuxDummy = false
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ConfigKnock()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DeathSting_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(HIT_TUNNEL_SFX)
call Preload(HIT_TARGET_SFX)
endfunction
endscope
scope Tunnels initializer init
globals
private constant integer SPELL_ID = 'DSA5'
private constant integer UPGRADE_ID = 'DSI3'
private constant string PATH_SFX = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl"
private constant real SPEED = 29.00
endglobals
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID and up.isSuperior then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(-6)
endif
if up.upID == 'DSI2' then
set a = Ability.GetUnitAbilityByID('DSA2',up.ownerHero.hero)
call a.addCastRange(75)
endif
endfunction
struct Tunnels extends array
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Table ht = b.int
local real x = GetUnitX(b.target) + SPEED * ht.real[3]
local real y = GetUnitY(b.target) + SPEED * ht.real[4]
call DestroyEffect(AddSpecialEffect(PATH_SFX,x,y))
call SetUnitX(b.target,x)
call SetUnitY(b.target,y)
if b.elapsedTime <= 0.50 then
call SetUnitAnimationByIndex(b.target,10)
endif
set ht.real[2] = ht.real[2] - SPEED
if ht.real[2] <= 0. then
set b.removeInside = true
endif
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Table ht = b.int
call Status.Remove(STATUS_DISARM,b.target)
call Status.Remove(STATUS_UNTURN,b.target)
call Status.Remove(STATUS_UNPATH,b.target)
call Status.Remove(STATUS_INVULNERABLE,b.target)
call SetUnitAnimation(b.target,"morph alternate")
call SetUnitTimeScale(b.target,1)
call BlzUnitDisableAbility(b.target,'DSA3',true,false)
call BlzUnitDisableAbility(b.target,'DSA1',false,false)
call BlzUnitDisableAbility(b.target,'DSA2',false,false)
call BlzUnitDisableAbility(b.target,'DSA4',false,false)
call ht.flush()
call ht.destroy()
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local Table ht = b.int
call Status.Add(STATUS_DISARM,b.target,0,0)
call Status.Add(STATUS_UNTURN,b.target,0,0)
call Status.Add(STATUS_UNPATH,b.target,0,0)
call Status.Add(STATUS_INVULNERABLE,b.target,0,0)
call BlzUnitDisableAbility(b.target,'DSA3',false,false)
call SetUnitTimeScale(b.target,2)
call BlzUnitDisableAbility(b.target,'DSA1',true,false)
call BlzUnitDisableAbility(b.target,'DSA2',true,false)
call BlzUnitDisableAbility(b.target,'DSA4',true,false)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Tunnels"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function SpellTrigger takes unit u, real x, real y returns nothing
local Table ht
if not UnitHasBuff(u,Tunnels.buff) then
set ht = Table.create()
set ht.real[1] = Angle(GetUnitX(u),GetUnitY(u),x,y)
set ht.real[2] = Distance(GetUnitX(u),GetUnitY(u),x,y)
set ht.real[3] = Cos(ht.real[1])
set ht.real[4] = Sin(ht.real[1])
call UnitAddBuff(u,u,99.,Tunnels.buff,0,ht)
endif
endfunction
private function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit(),GetSpellTargetX(),GetSpellTargetY())
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
if GetLearnedSkillLevel() == 1 then
call UnitAddAbility(u,'DSA3')
call UnitMakeAbilityPermanent(u,true,'DSA3')
call BlzUnitDisableAbility(u,'DSA3',true,false)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Tunnels.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DeathSting_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(PATH_SFX)
endfunction
endscope
scope ScorpidHatchlings initializer init
globals
private constant integer SPELL_ID = 'DSA4'
private constant integer UPGRADE_ID = 'DSI4'
private constant integer DUMMY_ID = 'h00H'
private constant real DMG_BASE = 60.00
private constant real DMG_LVL = 30.00
private constant real AGIX_BASE = 0.50
private constant integer MAX_ATTACKS = 2
private constant integer MAX_ATTACKS_LVL= 2
private constant real MAX_DISTANCE = 2000.00
private constant real AOE = 250.00
private constant real BUFF_INTERVAL = 1.00
private constant string TARGET_SFX = "Abilities\\Spells\\Other\\Parasite\\ParasiteTarget.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function GetMaxAttacks takes integer lvl returns integer
return MAX_ATTACKS + MAX_ATTACKS_LVL * lvl
endfunction
private function onDummyDmg takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local ScorpidTarget st
local Buff b
local DamageOptions op = 0
if UnitHasBuff(data.source,ScorpidTarget.buff) then
set b = GetUnitBuff(data.source,ScorpidTarget.buff)
set st = b.buffAllocIndex
set st.count = st.count - 1
if b.int == 3 then
set op = DamageOptions.create()
set op.allowOrbs = true
endif
call CodeDamage.Damage(b.owner,data.target,(GetHeroAgi(b.owner,true) * st.damageMult) + st.damage,udg_DamageTypeAttack,"ScorpidAttack",0,op)
if st.count == 0 then
call UnitRemoveBuff(data.source,ScorpidTarget.buff)
endif
endif
endfunction
struct ScorpidTarget extends array
integer count
unit target
player owner
boolean burrowed
real damage
real damageMult
effect sfx
private method burrow takes Buff b returns nothing
call PauseUnit(b.target,true)
call SetUnitAnimation(b.target,"morph")
set burrowed = true
endmethod
private method unburrow takes Buff b returns nothing
call SetUnitAnimation(b.target,"Morph ALTERNATE")
call PauseUnit(b.target,false)
set burrowed = false
endmethod
public static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if burrowed then
call unburrow(b)
else
call SetUnitAnimation(b.target,"morph")
endif
call BlzUnitDisableAbility(b.target,'Aatk',true,false)
call UnitApplyTimedLife(b.target,'BTLF',1.0)
call DestroyEffect(sfx)
set sfx = null
set owner = null
set target = null
endmethod
public static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local boolean b1
set b1 = DistanceBetweenUnits(b.target,b.owner) >= MAX_DISTANCE
if b1 or count == 0 or not UnitAlive(target) then
set b.removeInside = true
else
if IsUnitVisible(target,owner) and not IsUnitHidden(target) then
if not burrowed then
call IssueTargetOrderById(b.target,ORDER_attack,target)
else
call SetUnitX(b.target,GetUnitX(target))
call SetUnitY(b.target,GetUnitY(target))
call unburrow(b)
endif
elseif not burrowed then
call burrow(b)
endif
endif
endmethod
public static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set count = GetMaxAttacks(b.level)
set target = GetUnitByIndex(b.int)
set damageMult = AGIX_BASE
set damage = GetDamage(b.level)
set owner = GetOwningPlayer(b.target)
set burrowed = false
call UnitAddAbility(b.target,'Aloc')
call unburrow(b)
set sfx = AddSpecialEffectTarget(TARGET_SFX,target,"overhead")
if GetUpgradeSkillLevel(b.owner,UPGRADE_ID) != 0 then
set count = count + 2
endif
set b.int = GetHeroMasteryType(b.owner)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Hatchling"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = BUFF_INTERVAL
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real xu = GetUnitX(u)
local real yu = GetUnitY(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local real ua = GetUnitFacing(u)
local real d
local unit temp
local unit dummy
local real xc
local real yc
local real a
call GroupEnumUnitsInRange(g,x,y,AOE,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and IsUnitType(temp,UNIT_TYPE_HERO) then
set xu = GetUnitX(temp)
set yu = GetUnitY(temp)
set a = GetRandomReal(1,360)
set d = GetRandomReal(80,120)
set xc = xu + d * Cos(a)
set yc = yu + d * Sin(a)
set dummy = CreateUnit(p,DUMMY_ID,xc,yc,ua)
call SetUnitColor(dummy,PLAYER_COLOR_GREEN)
call UnitAddBuff(dummy,u,999,ScorpidTarget.buff,lvl,GetUnitUserData(temp))
endif
endloop
set u = null
call ReleaseGroup(g)
set g = null
set p = null
set dummy = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_TARGET
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ScorpidTarget.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterDummyDamage(Filter(function onDummyDmg))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,DeathSting_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A00Y',PRELOAD_SECOND)
call Preload(TARGET_SFX)
endfunction
endscope
library GnollWarden initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HGW1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'GWI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Territory Control"
set up.Text = "|c00b4b4b4Expel Intruder|r deals |c000080ffMagical Damage|r."
set up.SupText = "Attacks made to |c00b4b4b4Expel Intruder|r target has |c007fff00True Strike|r."
set up.LevelData1 = "50 Damage"
set up.LevelData2 = "100 Damage"
set up.LevelData3 = "150 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNCrystalBall.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'GWI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Savage Rage"
set up.Text = "Increases |c00b4b4b4Scare Fangs|r area of effect."
set up.SupText = "|c00b4b4b4Scare Fangs|r also reduces enemies |c00ffff95Attack Speed|r by 60% for 5 seconds."
set up.LevelData1 = "+100 AoE"
set up.LevelData2 = "+200 AoE"
set up.LevelData3 = "+300 AoE"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNGnoll.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'GWI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Storm Strikes"
set up.Text = "Increases |c00b4b4b4Overcharge|r damage on enemies with less than 40% of Hp."
set up.SupText = "|c00b4b4b4Overcharge|r applied to enemies with less than 40% Hp |c0000ced1Stuns|r them for 0.50 seconds."
set up.LevelData1 = "+20 Damage"
set up.LevelData2 = "+40 Damage"
set up.LevelData3 = "+60 Damage"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNGolemThunderclap.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'GWI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Absolute Command"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HGW1'
set d.Name = "Gnoll Warden"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNGnollWarden.blp"
set d.WinAni = "spell"
set d.Block = 0
set d.Evasion = 40
set d.Resistance = 20
set d.LifeRegen = 1.2
set d.ManaRegen = 0.6
set d.Armor = 2
set d.AttackRange = 320
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'GWA1'
set d.HeroAbility2 = 'GWA2'
set d.HeroAbility3 = 'GWA3'
set d.HeroAbility4 = 'GWA4'
set d.ChooseIconID = 'c013'
set d.ChooseDummy = 'dh06'
set d.spellDamageLevel = 5
set d.attackDamageLevel = 6
set d.healingLevel = 2
set d.survivavilityLevel = 2
set d.movementLevel = 4
set d.crowdControlLevel = 3
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HGWI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ExpelIntruder initializer init
globals
private constant integer SPELL_ID = 'GWA1'
private constant integer UPGRADE_ID = 'GWI1'
private constant integer DAMAGE_BASE = 30
private constant integer DAMAGE_LEVEL = 5
private constant integer RANGE_BASE = 300
private constant integer RANGE_LEVEL = 50
private constant real SPEED_BASE = 0.20
private constant real SLOW_BASE = 0.30
private constant real SLOW_LEVEL = 0.05
private constant real BUFF_DURATION = 6
private constant real UP_DAMAGE_BASE = 50.00
private constant string BONUS_SFX = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
private constant real MISSILE_SPEED = 43.00
private constant real MISSILE_SCALE = 1.50
private constant string MISSILE_SFX = "war3mapImported\\Lightning Bolt.mdx"
private trigger ATTACK_ORDER_TRIGGER
private trigger BEGIN_ATTACK_TRIGGER
endglobals
private function GetDamage takes integer lvl returns integer
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function GetRange takes integer lvl returns integer
return RANGE_BASE + RANGE_LEVEL * lvl
endfunction
private function GetSlow takes integer lvl returns real
return SLOW_BASE + SLOW_LEVEL * lvl
endfunction
struct ExpelIntruderMissile extends array
private static method onFinish takes Missile missile returns boolean
local integer ulvl
if UnitAlive(missile.target) then
if not TriggerSpellNegation(missile.target) then
set ulvl = GetUpgradeSkillLevel(missile.source,UPGRADE_ID)
if ulvl != 0 then
call CodeDamage.Damage(missile.source,missile.target,UP_DAMAGE_BASE * ulvl,udg_DamageTypeMagic,"",0,0)
endif
call UnitAddBuff(missile.target,missile.source,BUFF_DURATION,ExpelIntruder.buff,missile.level,0)
endif
if TriggerSpellReflection(missile.target) then
call ExpelIntruder_SetupMissile.evaluate(missile.target,missile.source,missile.level)
endif
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl returns Missile
local real a = AngleBetweenUnits(source,target)
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),25.00,a,0,25.00)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.target = target
set missile.level = lvl
set missile.speed = MISSILE_SPEED
set missile.model = MISSILE_SFX
set missile.scale = MISSILE_SCALE
call ExpelIntruderMissile.launch(missile)
return missile
endfunction
private function onBeginAttack takes nothing returns nothing
local unit u = GetAttacker()
local unit t = GetTriggerUnit()
local Buff b = GetUnitBuff(t,ExpelIntruder.buff)
if b != 0 then
if u == b.owner then
if not ExpelIntruder[b.buffAllocIndex].attack then
set ExpelIntruder[b.buffAllocIndex].attack = true
call ExpelIntruder[b.buffAllocIndex].Bonuses(true)
endif
else
if ExpelIntruder[b.buffAllocIndex].attack then
set ExpelIntruder[b.buffAllocIndex].attack = false
call ExpelIntruder[b.buffAllocIndex].Bonuses(false)
endif
endif
endif
set u = null
set t = null
endfunction
private function onAttack takes nothing returns nothing
local unit u = GetOrderedUnit()
local unit t = GetOrderTargetUnit()
local Buff b = GetUnitBuff(t,ExpelIntruder.buff)
if b != 0 and GetIssuedOrderId() == ORDER_attack or GetIssuedOrderId() == ORDER_smart then
if u == b.owner then
if not ExpelIntruder[b.buffAllocIndex].attack then
set ExpelIntruder[b.buffAllocIndex].attack = true
call ExpelIntruder[b.buffAllocIndex].Bonuses(true)
endif
else
if ExpelIntruder[b.buffAllocIndex].attack then
set ExpelIntruder[b.buffAllocIndex].attack = false
call ExpelIntruder[b.buffAllocIndex].Bonuses(false)
endif
endif
endif
set u = null
set t = null
endfunction
struct ExpelIntruder extends array
Movespeed ms
trigger t1
boolean attack
integer range
integer damage
effect sfx
Movespeed ms2
static integer count = 1
public method Bonuses takes boolean flag returns nothing
local Buff b = thisBuff
if flag then
call AddHeroAttackRange(b.owner,range/25)
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.owner,damage,0,true)
set sfx = AddSpecialEffectTarget(BONUS_SFX,b.owner,"hand right")
else
call AddHeroAttackRange(b.owner,-(range/25))
call BonusStruct.Add(BONUS_TYPE_DAMAGE,b.owner,-damage,0,true)
call DestroyEffect(sfx)
set sfx = null
endif
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
call Status.Remove(STATUS_SPY,b.target)
call DestroyTrigger(t1)
set t1 = null
if attack then
set attack = false
call Bonuses(false)
endif
call ms2.destroy()
set thistype.count = thistype.count - 1
if thistype.count == 0 then
call DisableTrigger(ATTACK_ORDER_TRIGGER)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-GetSlow(b.level),0)
call Status.Add(STATUS_SPY,b.target,0,0)
set t1 = CreateTrigger()
call TriggerRegisterUnitEvent(t1,b.owner,EVENT_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddCondition(t1,function onAttack)
set damage = GetDamage(b.level)
set range = GetRange(b.level)
set attack = false
set ms2 = Movespeed.create(b.owner,SPEED_BASE,0)
set thistype.count = thistype.count + 1
if thistype.count == 1 then
call EnableTrigger(ATTACK_ORDER_TRIGGER)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01V'
set BUFF_DATA.BuffID = 'B00V'
set BUFF_DATA.Name = "Expel Intruder"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
set thistype.count = 0
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local unit r = null
call SetupMissile(u,t,lvl)
if GetHeroMasteryType(u) == 3 then
set r = GetRandomEnemyInAreaExcept(GetOwningPlayer(u),GetUnitX(t),GetUnitY(t),300.00,t)
if r != null then
call SetupMissile(u,r,lvl)
endif
endif
set u = null
set t = null
set r = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_POINT
endfunction
private function SPELL_INIT takes nothing returns nothing
set ATTACK_ORDER_TRIGGER = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(ATTACK_ORDER_TRIGGER,EVENT_PLAYER_UNIT_ATTACKED)
call TriggerAddCondition(ATTACK_ORDER_TRIGGER,function onBeginAttack)
call DisableTrigger(ATTACK_ORDER_TRIGGER)
call SPELL_DATA()
call ExpelIntruder.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GnollWarden_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
call Preload(BONUS_SFX)
endfunction
endscope
scope ScareFangs initializer init
globals
private constant integer SPELL_ID = 'GWA2'
private constant integer UPGRADE_ID = 'GWI2'
private constant integer ATT_SPEED_BASE = 15
private constant integer ATT_SPEED_LEVEL = 5
private constant integer ATT_SPEED_PER_HERO = 10
private constant real AREA_EFFECT = 600.00
private constant real UP_AREA = 100.00
private constant real BUFF_DURATION = 12.00
private constant real FEAR_DURATION = 1.50
private constant string AREA_SFX = "war3mapImported\\Encourage.mdx"
private RSound ABILITY_SOUND
endglobals
private function GetAttackSpeed takes integer lvl returns integer
return ATT_SPEED_BASE + ATT_SPEED_LEVEL * lvl
endfunction
struct ScareFangsReduction extends array
private static method onRemove takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,60,0,true)
endmethod
private static method onApply takes Buff b returns nothing
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-60,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A049'
set BUFF_DATA.BuffID = 'B01K'
set BUFF_DATA.Name = "Scare Fangs Reduction"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct ScareFangs extends array
integer as
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set as = GetAttackSpeed(b.level) + ATT_SPEED_PER_HERO * b.int
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01W'
set BUFF_DATA.BuffID = 'B00W'
set BUFF_DATA.Name = "Grood Land Fury"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local integer c = 0
local boolean sup = IsUpgradeSuperior(u,UPGRADE_ID)
local real area = AREA_EFFECT
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local unit temp
//call ABILITY_SOUND.play(x,y,0,100)
if ulvl != 0 then
set area = area + UP_AREA * ulvl
endif
call GroupEnumUnitsInRange(g,x,y,area,null)
call DestroyEffect(AddSpecialEffectTarget(AREA_SFX,u,"origin"))
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ENEMY(temp,p) and not IsUnitIllusion(temp) then
set c = c + 1
call Status.Add(STATUS_FEAR,temp,FEAR_DURATION,Status_EFFECT[STATUS_FEAR])
if sup then
call UnitAddBuff(temp,u,7.0,ScareFangsReduction.buff,0,0)
endif
endif
endloop
call UnitAddBuff(u,u,BUFF_DURATION,ScareFangs.buff,GetUnitAbilityLevel(u,SPELL_ID),c)
call ReleaseGroup(g)
set g = null
set p = null
set u = null
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
if GetUnitAbilityLevel(data.source,'GWA1') != 0 then
if UnitHasBuff(data.target,ExpelIntruder.buff) and IsUpgradeSuperior(data.source,'GWI1') then
set data.trueAttack = true
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ScareFangs.Initialize()
call ScareFangsReduction.Initialize()
//
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GnollWarden_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01W',PRELOAD_SECOND)
call PreloadGen.Add('A049',PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
scope Overcharge initializer init
globals
private constant integer SPELL_ID = 'GWA3'
private constant integer UPGRADE_ID = 'GWI3'
private constant real DAMAGE_LEVEL = 50.00
private constant real DAMAGE_BASE = 40.00
private constant real UP_DAMAGE_BASE = 20.00
private constant real SUP_STUN = 0.50
private constant real AREA_EFFECT = 170.00
private constant string AREA_SFX = "war3mapImported\\LightningNova.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
public function CastOvercharge takes unit source, unit target returns nothing
local group g = NewGroup()
local player p = GetOwningPlayer(source)
local real dmg = GetDamage(GetUnitAbilityLevel(source,SPELL_ID))
local real area = AREA_EFFECT
local real x = GetUnitX(target)
local real y = GetUnitY(target)
local integer ulvl = GetUpgradeSkillLevel(source,UPGRADE_ID)
local boolean b = IsUpgradeSuperior(source,UPGRADE_ID)
local boolean less = GetUnitStatePercent(target,UNIT_STATE_LIFE,UNIT_STATE_MAX_LIFE) <= 40
local unit temp
local effect sfx = AddSpecialEffect(AREA_SFX,x,y)
local real scale = 0.20
if less and ulvl != 0 then
set dmg = dmg + UP_DAMAGE_BASE * ulvl
endif
call BlzSetSpecialEffectScale(sfx,scale)
call DestroyEffect(sfx)
call GroupEnumUnitsInRange(g,x,y,area,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(source,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
if b and less then
call Status.Add(STATUS_STUN,temp,SUP_STUN,Status_EFFECT[STATUS_STUN])
endif
endif
endloop
if GetHeroMasteryType(source) == 1 then
call CodeDamage.Damage(source,source,100.00,udg_DamageTypeHeal,"",0,0)
endif
call ReleaseGroup(g)
set sfx = null
set g = null
set p = null
endfunction
private function OnDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer c
local Ability a
if GetUnitAbilityLevel(data.source,SPELL_ID) != 0 then
if data.dmgType == udg_DamageTypeAttack and not data.isMiss and data.mainAttack then
if not IsUnitType(data.target,UNIT_TYPE_STRUCTURE) and not IsUnitType(data.target,UNIT_TYPE_MECHANICAL) then
set a = GetHeroAbilityById(data.source,SPELL_ID)
set c = GetUnitData(data.source,"Overcharge") + 1
if c >= 5 then
call SetUnitData(data.source,"Overcharge",0)
call CastOvercharge(data.source,data.target)
set c = 0
else
call SetUnitData(data.source,"Overcharge",c)
endif
call a.abilityNumber.setValue(c)
endif
endif
endif
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local Ability a
if GetLearnedSkillLevel() == 1 then
set a = GetHeroAbilityById(u,SPELL_ID)
set a.abilityNumber = AbilityNumber.create(a.objectID,u)
call a.abilityNumber.setValue(0)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Passive"
set d.activationType = ACTIVATION_TYPE_NONE
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DamageEvent.RegisterDamage(Filter(function OnDamage))
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GnollWarden_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
scope ThunderAwaken initializer init
globals
private constant integer SPELL_ID = 'GWA4'
private constant integer UPGRADE_ID = 'GWI4'
private constant integer HITS_BASE = 2
private constant integer HITS_LEVEL = 1
private constant real AREA_OF_EFFECT = 700.00
private constant real PERIOD = 2.00
private constant real MA_PERIOD = 1.50
private constant string CASTER_SFX = "Abilities\\Spells\\Undead\\UnholyFrenzy\\UnholyFrenzyTarget.mdl"
endglobals
private function GetHitsCount takes integer lvl returns integer
return HITS_BASE + HITS_LEVEL * lvl
endfunction
struct ThunderAwaken extends array
group g
effect sfx
real count
real interval
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ReleaseGroup(g)
call DestroyEffect(sfx)
set g = null
set sfx = null
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local integer ulvl = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
local real a = AREA_OF_EFFECT
local Link head
local Buff bei
local player p
local unit temp
if GetUpgradeSkillLevel(b.target,UPGRADE_ID) != 0 then
set a = a + 100.00
endif
set count = count + 0.03125
call BlzSetSpecialEffectPosition(sfx,x,y,GetLocZ(x,y) + 150)
if count >= PERIOD then
set count = 0
set p = GetOwningPlayer(b.target)
call GroupEnumUnitsInRange(g,x,y,a,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and IsUnitType(temp,UNIT_TYPE_HERO) then
call Lightning.create("WHNL",b.target,temp,0.4,0.2,200,0)
call Overcharge_CastOvercharge.evaluate(b.target,temp)
endif
endloop
set head = ExpelIntruder.DATAS.head
loop
exitwhen head == null
set bei = head.data
if bei.owner == b.target then
call Lightning.create("WHNL",b.target,bei.target,0.4,0.2,200,0)
call Overcharge_CastOvercharge.evaluate(b.target,bei.target)
endif
set head = head.next
endloop
set p = null
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
set g = NewGroup()
set count = 0
if GetHeroMasteryType(b.target) == 2 then
set interval = MA_PERIOD
else
set interval = PERIOD
endif
set sfx = AddSpecialEffect(CASTER_SFX,x,y)
call BlzSetSpecialEffectPosition(sfx,x,y,GetLocZ(x,y) + 150)
call BlzSetSpecialEffectScale(sfx,1.4)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A01X'
set BUFF_DATA.BuffID = 'B00X'
set BUFF_DATA.Name = "Thunder Awaken"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local integer h = GetHitsCount(lvl)
local real interval
if GetHeroMasteryType(u) == 2 then
set interval = MA_PERIOD
else
set interval = PERIOD
endif
call UnitAddBuff(u,u,interval * h,ThunderAwaken.buff,lvl,0)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ThunderAwaken.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GnollWarden_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add('A01X',PRELOAD_SECOND)
call Preload(CASTER_SFX)
endfunction
endscope
library GoblinGrenadier initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HGG1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'GGI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Improved Searching"
set up.Text = "Increases |c00b4b4b4Fragmented Bullet|r secondary effect radius."
set up.SupText = "Increases |c00b4b4b4Fragmented Bullet|r damage base by 100."
set up.LevelData1 = "+75 radius"
set up.LevelData2 = "+150 radius"
set up.LevelData3 = "+225 radius"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'GGI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Boosters"
set up.Text = "Increases |c00b4b4b4Rocket Jump|r |c007fff00Critical|r chance bonus."
set up.SupText = "|c00b4b4b4Rocket Jump|r gives 40% bonus |c00ffff95Attack Speed|r for 3.5 seconds."
set up.LevelData1 = "+4% Critical"
set up.LevelData2 = "+8% Critical"
set up.LevelData3 = "+12% Critical"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'GGI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Improved Grenades"
set up.Text = "Increases |c00b4b4b4Shock Grenade|r cast range."
set up.SupText = "Increases |c00b4b4b4Shock Grenade|r shock count by 1 and |c0000ced1Ensnare|r duration by 1s."
set up.LevelData1 = "+75 cast range"
set up.LevelData2 = "+150 cast range"
set up.LevelData3 = "+225 cast range"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'GGI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Engineering Improvements"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HGG1'
set d.Name = "Goblin Grenadier"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNBombardier.blp"
set d.WinAni = "spell slam"
set d.Block = 0
set d.Evasion = 40
set d.Resistance = 20
set d.LifeRegen = 1.0
set d.ManaRegen = 1.5
set d.Armor = 0
set d.AttackRange = 600
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'GGA1'
set d.HeroAbility2 = 'GGA2'
set d.HeroAbility3 = 'GGA3'
set d.HeroAbility4 = 'GGA4'
set d.ChooseIconID = 'c017'
set d.ChooseDummy = 'dh17'
set d.spellDamageLevel = 4
set d.attackDamageLevel = 6
set d.healingLevel = 0
set d.survivavilityLevel = 4
set d.movementLevel = 5
set d.crowdControlLevel = 5
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HGGI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope FragmentedBullet initializer init
globals
private constant integer SPELL_ID = 'GGA1'
private constant integer EXTRA_ID = 'A08L'
private constant integer UPGRADE_ID = 'GGI1'
private constant real DMG_BASE = 40.00
private constant real DMG_LEVEL = 30.00
private constant real STUN_BASE = 1.10
private constant real STUN_LEVEL = 0.10
private constant integer EXTRA_TARGETS = 2
private constant real AREA = 250.00
private constant real UP_AREA = 75.00
private constant real SUP_DAMAGE = 100.00
private constant string SHOT_SFX = "Abilities\\Weapons\\GyroCopter\\GyroCopterImpact.mdl"
private constant string MISSILE_SFX = "war3mapImported\\Airstrike Rocket.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private function GetStun takes integer lvl returns real
return STUN_BASE + STUN_LEVEL * lvl
endfunction
struct FragmentedBulletMissile2 extends array
private static method onFinish takes Missile missile returns boolean
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeMagicAoe,"",0,0)
call Status.Add(STATUS_STUN,missile.target,GetStun(missile.level) * 2,Status_EFFECT[STATUS_STUN])
call DestroyEffect(AddSpecialEffectTarget(SHOT_SFX,missile.target,"chest"))
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile2 takes unit sourceLaunch, unit source, unit target, real damage, integer lvl returns Missile
local real xs = GetUnitX(sourceLaunch)
local real ys = GetUnitY(sourceLaunch)
local real a = Angle(xs,ys,GetUnitX(target),GetUnitY(target))
local Missile missile = Missile.create(xs,ys,75.00,a,20.00,75.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.damage = damage
set missile.speed = 20
set missile.level = lvl
set missile.model = MISSILE_SFX
set missile.scale = 1.0
call FragmentedBulletMissile2.launch(missile)
return missile
endfunction
struct FragmentedBulletMissile extends array
private static method onFinish takes Missile missile returns boolean
local unit temp
local group g
local real a
local real a2
local real x
local real y
local real xt
local real yt
local integer max
local real s
local real area
if not TriggerSpellNegation(missile.target) then
set g = NewGroup()
if GetHeroMasteryType(missile.source) == 1 then
set max = EXTRA_TARGETS + 2
else
set max = EXTRA_TARGETS
endif
set s = GetStun(missile.level)
set area = AREA + UP_AREA * GetUpgradeSkillLevel(missile.source,UPGRADE_ID)
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeMagic,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(SHOT_SFX,missile.target,"chest"))
call Status.Add(STATUS_STUN,missile.target,s,Status_EFFECT[STATUS_STUN])
call GroupEnumUnitsInRange(g,GetUnitX(missile.target),GetUnitY(missile.target),area,null)
set a = (AngleBetweenUnits(missile.source,missile.target) * bj_RADTODEG) + 180
set x = GetUnitX(missile.target)
set y = GetUnitY(missile.target)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) and temp != missile.target and not IsUnitMagicImmune(temp) then
set xt = GetUnitX(temp)
set yt = GetUnitY(temp)
set a2 = Angle(xt,yt,x,y) * bj_RADTODEG
if max != 0 then
if not (RAbsBJ(a - a2) > 45 and RAbsBJ(a - a2 - 360.) > 45) then
call SetupMissile2(missile.target,missile.source,temp,missile.damage / 2,missile.level)
set max = max - 1
endif
endif
endif
endloop
call ReleaseGroup(g)
set g = null
set temp = null
endif
if TriggerSpellReflection(missile.target) then
call FragmentedBullet_SetupMissile.evaluate(missile.target,missile.source,missile.level,1)
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl, integer op returns Missile
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real a = Angle(xs,ys,GetUnitX(target),GetUnitY(target))
local Missile missile
if op == 1 then
set missile = Missile.create(xs,ys,75.00,a,20.00,75.00)
else
set missile = Missile.create(xs,ys,300.00,a,20.00,75.00)
endif
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl)
if IsUpgradeSuperior(source,UPGRADE_ID) then
set missile.damage = missile.damage + SUP_DAMAGE
endif
set missile.speed = 35
set missile.level = lvl
set missile.model = MISSILE_SFX
set missile.scale = 1.2
call FragmentedBulletMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Ability a
call SetupMissile(u,t,lvl,1)
set t = null
set u = null
endfunction
private function onCast2 takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer idc = GetUnitTypeId(u)
local integer lvl
local integer id
local Ability a
if idc == 'N01E' or idc == 'n002' then
set id = GetUnitData(u,"Owner")
if id != 0 then
set u = GetUnitByIndex(id)
set lvl = GetUnitAbilityLevel(u,SPELL_ID)
if idc == 'N01E' then
call SetupMissile(u,t,lvl,1)
else
call SetupMissile(u,t,lvl,2)
endif
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call a.forceCooldown()
endif
endif
set t = null
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCast2)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GoblinGrenadier_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope RocketJump initializer init
globals
private constant integer SPELL_ID = 'GGA2'
private constant integer UPGRADE_ID = 'GGI2'
private constant real DMG_BASE = 60.00
private constant real DMG_LEVEL = 40.00
private constant real CRITICAL_BASE = 5.00
private constant real DISTANCE = 450.00
private constant real UP_CRIT = 4.00
private constant string TARGET_SFX = "Abilities\\Weapons\\Mortar\\MortarMissile.mdl"
private constant string MISSILE_SFX = "war3mapImported\\Incendiary Bullet Red.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
struct RocketJumpBonus extends array
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int == 1 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-40,0,true)
elseif b.int == 2 then
call AddHeroAttackRange(b.target,-16)
elseif b.int == 3 then
call AddHeroAttackRange(b.target,-16)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-40,0,true)
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int == 1 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,40,0,true)
elseif b.int == 2 then
call AddHeroAttackRange(b.target,16)
elseif b.int == 3 then
call AddHeroAttackRange(b.target,16)
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,40,0,true)
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A08M'
set BUFF_DATA.BuffID = 'B034'
set BUFF_DATA.Name = "Rocket Jump Bonus"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == 'GGI3' then
set a = Ability.GetUnitAbilityByID('GGA3',up.ownerHero.hero)
call a.addCastRange(75)
endif
endfunction
struct RocketJumpMissile extends array
private static method onFinish takes Missile missile returns boolean
local DamageOptions op = DamageOptions.create()
set op.allowOrbs = true
call CodeDamage.Damage(missile.source,missile.target,missile.damage,udg_DamageTypeAttack,"RocketJump",0,op)
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl returns Missile
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local real a = Angle(xs,ys,GetUnitX(target),GetUnitY(target))
local Missile missile = Missile.create(xs,ys,GetUnitFlyHeight(source),a,20.00,75.00)
set missile.source = source
set missile.target = target
set missile.owner = GetOwningPlayer(source)
set missile.damage = GetDamage(lvl) + (GetHeroAgi(source,true) * 0.30)
set missile.speed = 42.80
set missile.level = lvl
set missile.model = MISSILE_SFX
set missile.scale = 1.0
call RocketJumpMissile.launch(missile)
return missile
endfunction
struct RocketJump extends array
integer c
private static method onRemove takes Buff b returns nothing
call SetUnitTimeScale(b.owner,1.0)
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if c != 3 then
if b.target != b.owner then
set c = c + 1
call SetUnitAnimationByIndex(b.owner,7)
call SetupMissile(b.owner,b.target,b.level)
endif
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real a = (GetUnitFacing(b.owner) + 180) * bj_DEGTORAD
call KPJUnit.create(b.owner,DISTANCE,a,0.80,250,KPJDefaultConfig,KPJ_TYPE_JUMP)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,b.owner,"origin"))
if b.target != b.owner then
call SetUnitTimeScale(b.owner,1.50)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,b.target,"chest"))
else
call SetUnitAnimationByIndex(b.owner,3)
endif
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
call UnitDispelAllBuffs(b.target,BUFF_TYPE_NEGATIVE)
endif
set c = 0
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Rocket Jump"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.20
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local boolean b
local boolean b2
local Ability a
if t != null then
if not TriggerSpellNegation(t) then
call UnitAddBuff(t,u,0.90,RocketJump.buff,lvl,0)
set b = IsUpgradeSuperior(u,UPGRADE_ID)
set b2 = GetHeroMasteryType(u) == 2
if b and b2 then
call UnitAddBuff(u,u,3.50,RocketJumpBonus.buff,0,3)
elseif b then
call UnitAddBuff(u,u,3.50,RocketJumpBonus.buff,0,1)
elseif b2 then
call UnitAddBuff(u,u,3.50,RocketJumpBonus.buff,0,2)
endif
endif
else
call UnitAddBuff(u,u,0.90,RocketJump.buff,lvl,GetUnitUserData(t))
call DestroyEffect(AddSpecialEffect(TARGET_SFX,GetSpellTargetX(),GetSpellTargetY()))
set a = Ability.GetUnitAbilityByID(SPELL_ID,u)
call a.addTempPercentCooldown(-0.50)
set b = IsUpgradeSuperior(u,UPGRADE_ID)
set b2 = GetHeroMasteryType(u) == 2
if b and b2 then
call UnitAddBuff(u,u,3.50,RocketJumpBonus.buff,0,3)
elseif b then
call UnitAddBuff(u,u,3.50,RocketJumpBonus.buff,0,1)
elseif b2 then
call UnitAddBuff(u,u,3.50,RocketJumpBonus.buff,0,2)
endif
endif
set t = null
set u = null
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local real crit
if data.codeDmg.codeName == "RocketJump" then
set crit = CRITICAL_BASE * GetUnitAbilityLevel(data.source,SPELL_ID) + UP_CRIT * GetUpgradeSkillLevel(data.source,UPGRADE_ID)
set data.criticalChanceAdd = data.criticalChanceAdd + crit
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RocketJump.Initialize()
call RocketJumpBonus.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GoblinGrenadier_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope ShockGrenade initializer init
globals
private constant integer SPELL_ID = 'GGA3'
private constant integer UPGRADE_ID = 'GGI3'
private constant real DMG_BASE = 50.00
private constant real DMG_LEVEL = 20.00
private constant real AREA = 200.00
private constant string MISSILE_SFX = "war3mapImported\\Chain Grenade Blue.mdx"
private constant string TARGET_SFX = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
private Effect SG_SFX
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
struct ShockGrenadeMissile extends array
private static method onFinish takes Missile missile returns boolean
local group g = NewGroup()
local unit temp
local real dur = 4.0
local integer sup = 0
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
set dur = 6.0
set sup = 1
endif
call GroupEnumUnitsInRange(g,missile.x,missile.y,AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(missile.source,temp,missile.damage,udg_DamageTypeMagicAoe,"",0,0)
if IsUnitType(temp,UNIT_TYPE_HERO) then
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,temp,"chest"))
call Lightning.createEx("CLPB",missile.x,missile.y,25,GetUnitX(temp),GetUnitY(temp),50,0.75,0.25)
call UnitAddBuff(temp,missile.source,dur,ShockGrenade.buff,missile.level,sup)
endif
endif
endloop
call ReleaseGroup(g)
set g = null
return true
endmethod
implement MissileStruct
endstruct
struct ShockGrenade extends array
private static method onFinish takes Buff b returns nothing
if b.int == 1 then
call Status.Add(STATUS_ENSNARE,b.target,3.0,SG_SFX)
else
call Status.Add(STATUS_ENSNARE,b.target,2.0,SG_SFX)
endif
endmethod
private static method onPeriodic takes Buff b returns nothing
call CodeDamage.Damage(b.owner,b.target,GetDamage(b.level),udg_DamageTypeMagicAoe,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(TARGET_SFX,b.target,"chest"))
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "ShockGrenade"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 2.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real xs = GetUnitX(u)
local real ys = GetUnitY(u)
local Missile missile = Missile.createXYZ(xs,ys,75.00,x,y,50)
local Ability a
set missile.source = u
set missile.owner = GetOwningPlayer(u)
set missile.damage = GetDamage(lvl)
set missile.arc = 45.00 * bj_DEGTORAD
set missile.speed = 27.00
set missile.level = lvl
set missile.model = MISSILE_SFX
set missile.scale = 1.0
call ShockGrenadeMissile.launch(missile)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set SG_SFX = Effect.create("war3mapImported\\ShockBuff.mdl","chest")
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ShockGrenade.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GoblinGrenadier_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope DeploysFalco initializer init
globals
private constant integer SPELL_ID = 'GGA4'
private constant integer UPGRADE_ID = 'GGI4'
private constant integer VEHICLE_ID = 'N01E'
private constant integer VEHICLE2_ID = 'n002'
private constant integer CANCEL_ID = 'A030'
private constant string TRANSFORMATION_SFX = "Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl"
endglobals
struct CobraK300 extends array
real x
real y
unit ve
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set x = GetUnitX(ve)
set y = GetUnitY(ve)
call SetUnitX(b.target,x)
call SetUnitY(b.target,y)
call SetUnitFacing(b.target,GetUnitFacing(ve))
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local effect sfx
call Status.Remove(STATUS_HIDE,b.target)
call Status.Remove(STATUS_DISABLE,b.target)
call Status.Remove(STATUS_INVULNERABLE,b.target)
call Status.Remove(STATUS_UNPATH,b.target)
call IssueImmediateOrder(b.target,"stop")
call RemoveUnit(ve)
set sfx = AddSpecialEffect(TRANSFORMATION_SFX,x,y)
call BlzSetSpecialEffectScale(sfx,2.5)
call DestroyEffect(sfx)
set sfx = null
call SetUnitData(b.target,"CobraK300",0)
call SelectUnitForPlayer(b.target,GetOwningPlayer(b.target),true)
call DestroyUnitIndex(ve)
set ve = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local real x = GetUnitX(b.target)
local real y = GetUnitY(b.target)
local integer vid = GetUnitData(b.target,"CobraK300")
local integer ac = (2 + 1 * b.level) * 2
local effect sfx
local integer qlvl = GetUnitAbilityLevel(b.target,'GGA1')
local Ability a
if GetUpgradeSkillLevel(b.target,UPGRADE_ID) != 0 then
set ac = ac + 4
endif
call Status.Add(STATUS_DISABLE,b.target,0,0)
call Status.Add(STATUS_HIDE,b.target,0,0)
call Status.Add(STATUS_INVULNERABLE,b.target,0,0)
set sfx = AddSpecialEffect(TRANSFORMATION_SFX,x,y)
call BlzSetSpecialEffectScale(sfx,2.5)
call DestroyEffect(sfx)
set sfx = null
if GetHeroMasteryType(b.target) == 3 then
set ve = CreateUnit(GetOwningPlayer(b.target),VEHICLE2_ID,x,y,GetUnitFacing(b.target))
else
set ve = CreateUnit(GetOwningPlayer(b.target),VEHICLE_ID,x,y,GetUnitFacing(b.target))
endif
call SetUnitData(b.target,"CobraK300",GetUnitUserData(ve))
call SetUnitData(ve,"Owner",GetUnitUserData(b.target))
call LockIndex(ve,true)
call BlzSetUnitMaxHP(ve,ac)
call SuspendHeroXP(ve,true)
call SetUnitAbilityLevel(ve,'A08L',qlvl)
set a = Ability.GetUnitAbilityByID('GGA1',b.target)
call BlzSetUnitAbilityCooldown(ve,'A08L',qlvl - 1,a.finalCooldown)
if a.isOnCooldown() then
call BlzStartUnitAbilityCooldown(ve,'A08L',a.cdTime)
endif
call SetUnitState(ve,UNIT_STATE_LIFE,1000)
call SelectUnitForPlayer(ve,GetOwningPlayer(b.target),true)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Cobra K300"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCastCancel takes nothing returns nothing
local unit u = GetUnitByIndex(GetUnitData(GetTriggerUnit(),"Owner"))
if u != null then
call UnitRemoveBuff(u,CobraK300.buff)
endif
set u = null
endfunction
private function onDeath takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id = GetUnitTypeId(u)
local unit o
local CobraK300 b
if id == VEHICLE_ID or id == VEHICLE2_ID then
set o = GetUnitByIndex(GetUnitData(u,"Owner"))
set b = GetUnitBuff(o,CobraK300.buff).buffAllocIndex
set b.x = GetUnitX(u)
set b.y = GetUnitY(u)
call UnitRemoveBuff(o,CobraK300.buff)
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local Ability a
call UnitAddBuff(u,u,3600,CobraK300.buff,GetUnitAbilityLevel(u,SPELL_ID),0)
set u = null
endfunction
private function onCast2 takes nothing returns nothing
local unit u = GetTriggerUnit()
local Ability a
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call CobraK300.Initialize()
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function onDeath)
call RegisterSpellFinishCastEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(SPELL_ID, function onCast2)
call RegisterSpellEffectEvent(CANCEL_ID, function onCastCancel)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,GoblinGrenadier_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call PreloadGen.Add(VEHICLE_ID,PRELOAD_UNIT)
endfunction
endscope
library TheHermit initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HTH1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'THI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Endless Fire"
set up.Text = "Increases |c00b4b4b4Throw Dynamite|r ignite duration."
set up.SupText = "Increases |c00b4b4b4Throw Dynamite|r |c0000ced1Stun|r duration by 0.4s."
set up.LevelData1 = "+1s Duration"
set up.LevelData2 = "+2s Duration"
set up.LevelData3 = "+3s Duration"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'THI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Prospect"
set up.Text = "Increases the duration of |c00b4b4b4Diamond Armor|r if the hero is burrowed."
set up.SupText = "|c00b4b4b4Diamond Armor|r is applied to all allied heroes around for 1.2s. (300 AOE)"
set up.LevelData1 = "+0.50s Duration"
set up.LevelData2 = "+0.75s Duration"
set up.LevelData3 = "+1s Duration"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'THI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Emergency Provisions"
set up.Text = "Gives a bonus |c00ffff95Resistance|r while burrowed."
set up.SupText = "|c0099b4d1Unburrow|r dispels all debuffs upon casting."
set up.LevelData1 = "+40(6.2%) Resistance"
set up.LevelData2 = "+60(9.3%) Resistance"
set up.LevelData3 = "+80(12.5%) Resistance"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'THI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Seismic Wave"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HTH1'
set d.Name = "The Hermit"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNKoboldGeomancer.blp"
set d.WinAni = "attack"
set d.Block = 20
set d.Evasion = 0
set d.Resistance = 40
set d.LifeRegen = 1.0
set d.ManaRegen = 1.0
set d.Armor = 2
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'THA1'
set d.HeroAbility2 = 'THA2'
set d.HeroAbility3 = 'THA3'
set d.HeroAbility4 = 'THA4'
set d.ChooseIconID = 'c029'
set d.ChooseDummy = 'dh29'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 1
set d.healingLevel = 3
set d.survivavilityLevel = 5
set d.movementLevel = 2
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HTHI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ThrowDynamite initializer init
globals
private constant integer SPELL_ID = 'THA1'
private constant integer UPGRADE_ID = 'THI1'
private constant real DPS_BASE = 5.00
private constant real DMG_BASE = 20.00
private constant real DMG_LEVEL = 20.00
private constant real DPS_DURATION = 5.00
private constant real DPS_AREA = 200.00
private constant real AREA = 300.00
private constant real SUP_STUN = 0.40
private constant string EXP_SFX = "war3mapImported\\NewDirtEXNofire.mdx"
private constant string MISSILE_SFX = "war3mapImported\\TNT.MDX"
private constant string GROUND_SFX = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
endglobals
private function GetDps takes integer lvl returns real
return DPS_BASE + DPS_BASE * lvl
endfunction
struct ThrowDynamite extends array
real dmg
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dmg,udg_DamageTypeMagicOverTime,"",0,0)
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmg = GetDps(b.level)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0BP'
set BUFF_DATA.BuffID = 'B04B'
set BUFF_DATA.Name = "Throw Dynamite"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct ThrowDynamiteMissile extends array
private static method onFinish takes Missile missile returns boolean
local group g = NewGroup()
local effect sfx
local unit temp
local real d = DPS_DURATION + GetUpgradeSkillLevel(missile.source,UPGRADE_ID)
local real stun = 1.00
set sfx = AddSpecialEffect(GROUND_SFX,missile.x,missile.y)
call BlzSetSpecialEffectScale(sfx,0.50)
call DestroyEffect(sfx)
set sfx = null
if IsUpgradeSuperior(missile.source,UPGRADE_ID) then
set stun = stun + SUP_STUN
endif
call GroupEnumUnitsInRange(g,missile.x,missile.y,DPS_AREA,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,missile.owner) and not IsUnitMagicImmune(temp) then
call CodeDamage.Damage(missile.source,temp,DMG_BASE + DMG_LEVEL * missile.level,udg_DamageTypeMagic,"",0,0)
call UnitAddBuff(temp,missile.source,d,ThrowDynamite.buff,missile.level,0)
if missile.data == 1 then
call Status.Add(STATUS_STUN,temp,stun,Status_EFFECT[STATUS_STUN])
endif
endif
endloop
call ReleaseGroup(g)
set g = null
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, real x, real y, boolean b returns Missile
local real xs = GetUnitX(source)
local real ys = GetUnitY(source)
local Missile missile = Missile.createXYZ(xs,ys,75.00,x,y,10.00)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.level = GetUnitAbilityLevel(source,SPELL_ID)
set missile.speed = 36
set missile.model = MISSILE_SFX
set missile.scale = 0.80
call SetUnitTimeScale(missile.dummy,1.5)
set missile.arc = 45.00 * bj_DEGTORAD
if b then
set missile.data = 1
endif
call ThrowDynamiteMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local real a
local real d
local real xs
local real ys
local boolean b = UnitHasBuff(u,Burrow.buff)
call SetupMissile(u,x,y,b)
set a = GetRandomReal(1,360) * bj_DEGTORAD
set d = GetRandomReal(1,AREA)
set xs = x + d * Cos(a)
set ys = y + d * Sin(a)
call SetupMissile(u,xs,ys,b)
set a = GetRandomReal(1,360) * bj_DEGTORAD
set d = GetRandomReal(1,AREA)
set xs = x + d * Cos(a)
set ys = y + d * Sin(a)
call SetupMissile(u,xs,ys,b)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ThrowDynamite.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TheHermit_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope DiamondArmor initializer init
globals
private constant integer SPELL_ID = 'THA2'
private constant integer UPGRADE_ID = 'THI2'
private constant real DURATION_BASE = 0.75
private constant real DURATION_LVL = 0.25
private constant real UP_TIME = 0.25
private constant real SUP_DUR = 1.20
private constant real MA_PERCENT = 0.75
private constant string EXP_SFX = "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
private constant string MISSILE_SFX = "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
private constant string ARMOR_SFX = "war3mapImported\\DiamondArmor.mdx"
private RSound ABILITY_SOUND
endglobals
private function GetDuration takes integer lvl returns real
return DURATION_BASE + DURATION_LVL * lvl
endfunction
struct DiamondArmor extends array
integer br
effect sfx
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if br == 1 then
call Status.Remove(STATUS_STUN,b.target)
call SetUnitTimeScale(b.target,1)
set br = 0
endif
//call DestroyEffect(sfx)
set sfx = null
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if not UnitHasBuff(b.target,Burrow.buff) then
set br = 1
call SetUnitTimeScale(b.target,0)
call Status.Add(STATUS_STUN,b.target,0,0)
endif
//set sfx = AddSpecialEffectTarget(ARMOR_SFX,b.target,"origin")
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0BQ'
set BUFF_DATA.BuffID = 'B04C'
set BUFF_DATA.Name = "Diamond Armor"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local real d = GetDuration(lvl)
local group g
local unit temp
local player p
if ulvl != 0 then
if UnitHasBuff(u,Burrow.buff) then
set d = d + (UP_TIME + UP_TIME * ulvl)
endif
endif
call UnitAddBuff(u,u,d,DiamondArmor.buff,lvl,0)
if IsUpgradeSuperior(u,UPGRADE_ID) then
set g = NewGroup()
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),300,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ALLIED(temp,p) and temp != u then
call UnitAddBuff(temp,u,SUP_DUR,DiamondArmor.buff,lvl,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
call ABILITY_SOUND.play(GetUnitX(u),GetUnitY(u),0,100)
set u = null
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,DiamondArmor.buff)
if b != 0 then
set data.mult = data.mult - 0.90
if GetHeroMasteryType(b.owner) == 1 then
call UnitAddHp(b.target,data.damageMod * MA_PERCENT)
call UnitAddMp(b.target,data.damageMod * MA_PERCENT)
endif
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DiamondArmor.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
set ABILITY_SOUND = RSound.create("Abilities\\Spells\\UndeadFreezingBreath\\FreezingBreathTarget.mp3", true, false, 12700, 12700)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TheHermit_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope Burrow initializer init
globals
private constant integer SPELL_ID = 'THA3'
private constant integer EXTRA_ID = 'A0BH'
private constant integer UPGRADE_ID = 'THI3'
public constant integer MORPH_ID = 'A0BN'
public constant integer UNMORPH_ID = 'A0BO'
private constant integer REGEN_BASE = 5
private constant integer REGEN_LVL = 5
private constant integer MS_BASE = 20
private constant integer MS_LVL = 20
private constant real BUFF_DURATION = 8.00
private constant integer UP_RES = 20
private constant string UNBURROW_SFX = "war3mapImported\\NewDirtEXNofire.mdx"
private constant string PERIOD_SFX = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl"
endglobals
private function GetRegen takes integer lvl returns integer
return REGEN_BASE + REGEN_LVL * lvl
endfunction
private function GetMs takes integer lvl returns integer
return MS_BASE + MS_LVL * lvl
endfunction
struct Burrow extends array
integer r
Movespeed ms
integer res
real x
real y
real d
boolean dm
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local effect sfx
local real xu
local real yu
if IsUnitMoving(b.target) then
set xu = GetUnitX(b.target)
set yu = GetUnitY(b.target)
set sfx = AddSpecialEffect(PERIOD_SFX,xu,yu)
call BlzSetSpecialEffectScale(sfx,0.50)
call BlzSetSpecialEffectTimeScale(sfx,2.0)
call DestroyEffect(sfx)
set sfx = null
if dm then
set d = d + Distance(x,y,xu,yu)
if d >= 450 then
set d = 0
if GetUnitAbilityLevel(b.target,'THA4') != 0 then
call EarthTremble_SpellTrigger.evaluate(b.target)
endif
endif
set x = xu
set y = yu
endif
endif
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local effect sfx
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,-r,0)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,-r,0)
call UnitRemoveAbility(b.target,EXTRA_ID)
if UnitAlive(b.target) then
call UnitAddAbility(b.target,UNMORPH_ID)
call UnitRemoveAbility(b.target,UNMORPH_ID)
call Upgrade.SetHeroTittle(b.target,GetHeroMasteryType(b.target))
else
call SetUnitData(b.target,"UnMorph",UNMORPH_ID)
set sfx = AddSpecialEffect("units\\creeps\\KoboldGeomancer\\KoboldGeomancer.mdl",GetUnitX(b.target),GetUnitY(b.target))
call BlzSetSpecialEffectColorByPlayer(sfx,GetOwningPlayer(b.target))
call BlzSetSpecialEffectScale(sfx,1.3)
call DestroyEffect(sfx)
set sfx = null
endif
call ms.destroy()
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,-res,0)
set res = 0
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
local integer mov = GetMs(b.level)
local integer m = GetHeroMasteryType(b.target)
set r = GetRegen(b.level)
if m == 3 then
set r = r * 2
set b.duration = b.duration + 3.0
endif
call BonusStruct.AddSpecial(BONUS_TYPE_LIFE_REGEN,b.target,r,0)
call BonusStruct.AddSpecial(BONUS_TYPE_MANA_REGEN,b.target,r,0)
call UnitAddAbility(b.target,MORPH_ID)
call UnitRemoveAbility(b.target,MORPH_ID)
call UnitAddAbility(b.target,EXTRA_ID)
call UnitMakeAbilityPermanent(b.target,true,EXTRA_ID)
set ms = Movespeed.create(b.target,0,mov)
if b.int != 0 then
set res = UP_RES + UP_RES * b.int
call BonusStruct.AddSpecial(BONUS_TYPE_RESISTANCE,b.target,res,0)
endif
call Upgrade.SetHeroTittle(b.target,m)
if m == 2 then
set dm = true
set x = GetUnitX(b.target)
set y = GetUnitY(b.target)
set d = 0
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Burrow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 0.15
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Ability a
call UnitAddBuff(u,u,BUFF_DURATION,Burrow.buff,lvl,GetUpgradeSkillLevel(u,UPGRADE_ID))
set u = null
endfunction
private function onCast2 takes nothing returns nothing
local unit u = GetTriggerUnit()
local Buff b = GetUnitBuff(u,Burrow.buff)
local group g
local player p
local unit temp
local effect sfx
if b != 0 then
call b.remove()
set sfx = AddSpecialEffectTarget(UNBURROW_SFX,u,"origin")
call BlzSetSpecialEffectScale(sfx,0.60)
call DestroyEffect(sfx)
set sfx = null
call KPJUnit.create(u,0,0,0.40,150,KPJDefaultConfig4,KPJ_TYPE_JUMP)
if IsUpgradeSuperior(u,UPGRADE_ID) then
call UnitDispelAllBuffs(u,BUFF_TYPE_NEGATIVE)
endif
if GetUnitAbilityLevel(u,'THA1') != 0 then
set p = GetOwningPlayer(u)
set g = NewGroup()
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),600.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_HERO_ENEMY(temp,p) then
call ThrowDynamite_SetupMissile(u,GetUnitX(temp),GetUnitY(temp),true)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call Burrow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCast2)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TheHermit_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope EarthTremble initializer init
globals
private constant integer SPELL_ID = 'THA4'
private constant integer UPGRADE_ID = 'THI4'
private constant real DMG_BASE = 60
private constant real DMG_LVL = 30
private constant real STACK_DMG_BASE = 10
private constant real STACK_DMG_LVL = 10
private constant real AOE_BASE = 300
private constant real SLOW_BASE = 0.06
private constant real SLOW_LVL = 0.02
private constant real SLOW_DURATION = 10.00
private constant string AOE_SFX = "war3mapImported\\Explosion.mdx"
endglobals
private function GetBaseDmg takes integer lvl returns real
return DMG_BASE + DMG_LVL * lvl
endfunction
private function GetStackDmg takes integer lvl returns real
return STACK_DMG_BASE + STACK_DMG_LVL * lvl
endfunction
struct EarthTrembleSlow extends array
Movespeed ms
private static method onStackRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onStackApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-(SLOW_BASE + SLOW_LVL * b.level),0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0BR'
set BUFF_DATA.BuffID = 'B04D'
set BUFF_DATA.Name = "Earth Tremble Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NORMAL
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.StackMax = 5
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
public function SpellTrigger takes unit u returns nothing
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real dmg = GetBaseDmg(lvl)
local group g = NewGroup()
local player p = GetOwningPlayer(u)
local real aoe = AOE_BASE
local unit temp
local Buff b
local real sdmg = GetStackDmg(lvl)
local effect sfx = AddSpecialEffect(AOE_SFX,GetUnitX(u),GetUnitY(u))
if UnitHasBuff(u,Burrow.buff) then
set aoe = aoe * 2
call BlzSetSpecialEffectScale(sfx,1.2)
else
call BlzSetSpecialEffectScale(sfx,0.9)
endif
call BlzSetSpecialEffectTime(sfx,0.25)
call BlzSetSpecialEffectTimeScale(sfx,1.5)
call DestroyEffect(sfx)
set sfx = null
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),aoe,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
set b = UnitAddBuff(temp,u,SLOW_DURATION,EarthTrembleSlow.buff,lvl,0)
if b == 0 then
set b = GetUnitBuff(temp,EarthTrembleSlow.buff)
endif
call CodeDamage.Damage(u,temp,dmg + sdmg * b.stacks,udg_DamageTypeMagicAoe,"",0,0)
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endfunction
private function onCast takes nothing returns nothing
call SpellTrigger(GetTriggerUnit())
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
if up.upID == UPGRADE_ID and up.level == 1 then
set EarthTrembleSlow.buff.StackMax = EarthTrembleSlow.buff.StackMax + 2
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call EarthTrembleSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TheHermit_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library FireReaver initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HFI1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'FII1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Vivid Flames"
set up.Text = "Increases |c00b4b4b4Fire Nova|r area of effect."
set up.SupText = "|c00b4b4b4Fire Nova|r |c0000ced1Silences|r affected enemies for 2s."
set up.LevelData1 = "+100 AoE"
set up.LevelData2 = "+150 AoE"
set up.LevelData3 = "+200 AoE"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'FII2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Rapid Fire"
set up.Text = "Reduces|c00b4b4b4Burning Attacks|r mana cost."
set up.SupText = "|c00b4b4b4Burning Attacks|r adds 40% |c00ffff95Attack Speed|r bonus while activated (autocast)."
set up.LevelData1 = "-10 Mana Cost"
set up.LevelData2 = "-20 Mana Cost"
set up.LevelData3 = "-30 Mana Cost"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'FII3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Ashes"
set up.Text = "|c00b4b4b4Molten Shield|r adds |c00ffff95Spell Strength|r."
set up.SupText = "Reduces |c0099b4d1Molten Shield|r cooldown by 5 seconds."
set up.LevelData1 = "+25(3.9%) Spell Strength"
set up.LevelData2 = "+50(7.8%) Spell Strength"
set up.LevelData3 = "+75(11.7%) Spell Strength"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'FII4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Melt"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HFI1'
set d.Name = "Fire Reaver"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNHeroAvatarOfFlame.blp"
set d.WinAni = "spell channeling"
set d.Block = 0
set d.Evasion = 10
set d.Resistance = 40
set d.LifeRegen = 1.0
set d.ManaRegen = 3.0
set d.Armor = 1
set d.AttackRange = 450
set d.PrimaryAttribute = 2
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'FIA1'
set d.HeroAbility2 = 'FIA2'
set d.HeroAbility3 = 'FIA3'
set d.HeroAbility4 = 'FIA4'
set d.ChooseIconID = 'c033'
set d.ChooseDummy = 'dh33'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 5
set d.healingLevel = 0
set d.survivavilityLevel = 1
set d.movementLevel = 1
set d.crowdControlLevel = 2
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HFII'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope FireNova initializer init
globals
private constant integer SPELL_ID = 'FIA1'
private constant integer UPGRADE_ID = 'FII1'
private constant real DMG_BASE = 80.00
private constant real DMG_LEVEL = 60.00
private constant real BUFF_DURATION = 2.00
private constant real SLOW = 0.50
private constant real AOE_BASE = 400.00
private constant real UP_AOE = 50.00
private constant string NOVA_SFX = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private struct Flame extends array
implement Alloc
effect sfx
real cos
real sin
real angle
public method update takes real x, real y, real z, real p, real aoe returns nothing
call BlzSetSpecialEffectX(sfx,x + (50.0 + aoe) * cos)
call BlzSetSpecialEffectY(sfx,y + (50.0 + aoe) * sin)
call BlzSetSpecialEffectZ(sfx,z)
call BlzSetSpecialEffectScale(sfx,0.20 + (p / 100))
endmethod
public static method create takes real x, real y, real a returns thistype
local thistype this = thistype.allocate()
set sfx = AddSpecialEffect(NOVA_SFX,x,y)
set angle = a
set cos = Cos(a)
set sin = Sin(a)
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectScale(sfx,0.20)
return this
endmethod
public method destroy takes nothing returns nothing
call DestroyEffect(sfx)
set sfx = null
call this.deallocate()
endmethod
endstruct
struct FireNova extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,50,0,true)
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-50,0,true)
set ms = Movespeed.create(b.target,-SLOW,0)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CE'
set BUFF_DATA.BuffID = 'B04U'
set BUFF_DATA.Name = "Fire Nova"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real dmg = tb.real[1]
local real aoe = tb.real[2]
local LinkedList list = tb.integer[3]
local group g = tb.group[4]
local real aoeMax = tb.real[5]
local boolean sup = tb.boolean[6]
local Link h = list.head
local real percent
local group g2 = NewGroup()
local unit temp
local Flame f
local player p
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real z = GetLocZ(x,y) + 50.00
set aoe = aoe + 20
set tb.real[2] = aoe
set percent = aoe / aoeMax * 100
if aoe < aoeMax then
loop
exitwhen h == 0
set f = h.data
call f.update(x,y,z,percent,aoe)
set h = h.next
endloop
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g2,x,y,aoe,null)
loop
set temp = FirstOfGroup(g2)
exitwhen temp == null
call GroupRemoveUnit(g2,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and not IsUnitInGroup(temp,g) then
call GroupAddUnit(g,temp)
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call UnitAddBuff(temp,u,BUFF_DURATION,FireNova.buff,0,0)
if sup then
call Status.Add(STATUS_SILENCE,temp,BUFF_DURATION,Status_EFFECT[STATUS_SILENCE])
endif
endif
endloop
call ReleaseGroup(g2)
else
call ReleaseTimer(t)
call ReleaseGroup(g)
set h = list.head
loop
exitwhen h == 0
set f = h.data
call f.destroy()
set h = h.next
endloop
call list.destroy()
call tb.flush()
call tb.destroy()
endif
set t = null
set g = null
set g2 = null
set p = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local Table tb = Table.create()
local LinkedList list = LinkedList.create()
local real i = 0.0
local real a = 0.0
local real aoe = AOE_BASE
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local Flame f
if ulvl != 0 then
set aoe = aoe + (UP_AOE + UP_AOE * ulvl)
endif
set tb.unit[0] = u
set tb.real[1] = GetDamage(lvl)
set tb.real[2] = 0.0
set tb.integer[3] = list
set tb.group[4] = NewGroup()
set tb.real[5] = aoe
set tb.boolean[6] = IsUpgradeSuperior(u,UPGRADE_ID)
loop
exitwhen i == 360.0
set a = i * bj_DEGTORAD
set f = Flame.create(x + 50 * Cos(a),y + 50 * Sin(a),a)
call list.add(f)
set i = i + 10.0
endloop
call TimerStart(NewTimerEx(tb),0.03125,true,function Callback)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call FireNova.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FireReaver_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope BurningAttacks initializer init
globals
private constant integer SPELL_ID = 'FIA2'
private constant integer UPGRADE_ID = 'FII2'
private constant real DMG_BASE = 20
private constant real DMG_LEVEL = 10
private constant real BUFF_DURATION = 5.00
private constant real DPS_BASE = 5.00
private constant real DPS_LEVEL = 5.00
private constant real UP_MANA = 10.00
private constant integer SUP_AS = 40
private constant integer MA_RANGE = 200
private constant string HIT_SFX = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private function GetDps takes integer lvl returns real
return DPS_BASE + DPS_LEVEL * lvl
endfunction
struct BurningAttacksBonuses extends array
integer as
integer range
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
set as = 0
endif
if range != 0 then
call AddHeroAttackRange(b.target,-(range/25))
endif
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if IsUpgradeSuperior(b.target,UPGRADE_ID) then
set as = SUP_AS
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endif
if GetHeroMasteryType(b.target) == 2 then
set range = MA_RANGE
call AddHeroAttackRange(b.target,(range/25))
set b.int = 1
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 0
set BUFF_DATA.BuffID = 0
set BUFF_DATA.Name = "Burning Attacks Bonuses"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = true
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
struct BurningAttacks extends array
real dps
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call CodeDamage.Damage(b.owner,b.target,dps,udg_DamageTypeMagicOverTime,"",0,0)
endmethod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dps = GetDps(b.level)
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CG'
set BUFF_DATA.BuffID = 'B04W'
set BUFF_DATA.Name = "Burning Attacks"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function onDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local real st
if data.dmgType == udg_DamageTypeAttack then
if GetUnitAbilityLevel(data.target,'Bpsd') != 0 then
call UnitRemoveAbility(data.target,'Bpsd')
if not data.isMiss then
set lvl = GetUnitAbilityLevel(data.source,SPELL_ID)
call CodeDamage.Damage(data.source,data.target,GetDamage(lvl),udg_DamageTypeMagic,"",0,0)
call UnitAddBuff(data.target,data.source,BUFF_DURATION,BurningAttacks.buff,lvl,0)
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,data.target,"overhead"))
endif
endif
endif
if data.codeDmg.codeName == "Lava Strike" and data.damageMod > 0 and not data.isAbsorbed then
if GetUpgradeSkillLevel(data.source,'FII4') != 0 then
set st = (data.damageMod / 100) * 0.50
if st < 0.5 then
set st = 0.5
elseif st > 2.5 then
set st = 2.5
endif
call Status.Add(STATUS_STUN,data.target ,st,Status_EFFECT[STATUS_STUN])
endif
endif
endfunction
private function onOrder takes nothing returns nothing
local unit u = GetOrderedUnit()
if GetIssuedOrderId() == ORDER_poisonarrows then
call UnitAddBuff(u,u,999999,BurningAttacksBonuses.buff,0,0)
elseif GetIssuedOrderId() == ORDER_unpoisonarrows then
call UnitRemoveBuff(u,BurningAttacksBonuses.buff)
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local player p = GetTriggerPlayer()
local trigger t
if GetLearnedSkillLevel() == 1 then
set t = CreateTrigger()
call TriggerRegisterUnitEvent(t,u,EVENT_UNIT_ISSUED_ORDER)
call TriggerAddCondition(t,function onOrder)
set t = null
if GetPlayerController(p) == MAP_CONTROL_COMPUTER then
call BlzUnitDisableAbility(u,SPELL_ID,true,false)
endif
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call BurningAttacks.Initialize()
call BurningAttacksBonuses.Initialize()
call RegisterSpellLearn(SPELL_ID, function onLearn)
call DamageEvent.RegisterDamage(Filter(function onDamage))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FireReaver_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope MoltenShield initializer init
globals
private constant integer SPELL_ID = 'FIA3'
private constant integer UPGRADE_ID = 'FII3'
private constant real REFLECT_BASE = 0.13
private constant real REFLECT_LEVEL = 0.03
private constant real AREA_OF_EFFECT = 900.00
private constant real UP_RESISTANCE = 25.00
private constant real SUP_COOLDOWN = 5.00
private constant string REFLECT_SFX = "war3mapImported\\ImmolationRedModified.mdx"
endglobals
private function GetReflectPercent takes integer lvl returns real
return REFLECT_BASE + REFLECT_LEVEL * lvl
endfunction
struct MoltenShield extends array
real reflect
real res
boolean cm
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,-res,0)
endif
set cm = false
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set reflect = GetReflectPercent(b.level)
set res = UP_RESISTANCE * GetUpgradeSkillLevel(b.owner,UPGRADE_ID)
if res != 0 then
call BonusStruct.AddSpecial(BONUS_TYPE_SPELL_STRENGTH,b.target,res,0)
endif
if GetHeroMasteryType(b.owner) == 1 then
set cm = true
endif
endmethod
private static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0CF'
set BUFF_DATA.BuffID = 'B04V'
set BUFF_DATA.Name = "Molten Shield"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
local DamageOptions op
local real dmg
local group g
local player p
local unit temp
local Ability a
if not data.isAbsorbed and data.damageMod > 0 and data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
set b = GetUnitBuff(data.target,MoltenShield.buff)
if b != 0 then
set data.mult = data.mult - MoltenShield[b.buffAllocIndex].reflect
if not IsUnitType(data.source,UNIT_TYPE_HERO) then
return
endif
set g = NewGroup()
set p = GetOwningPlayer(b.owner)
call GroupEnumUnitsInRange(g,GetUnitX(b.target),GetUnitY(b.target),AREA_OF_EFFECT,null)
set dmg = data.damageMod * MoltenShield[b.buffAllocIndex].reflect
set data.mult = data.mult - MoltenShield[b.buffAllocIndex].reflect
if MoltenShield[b.buffAllocIndex].cm then
call UnitAddHp(b.owner,dmg/2)
endif
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
set op = DamageOptions.create()
set op.notCritical = true
call CodeDamage.Damage(b.owner,temp,dmg,udg_DamageTypePure,"Returned",0,op)
call DestroyEffect(AddSpecialEffectTarget(REFLECT_SFX,temp,"overhead"))
endif
endloop
call ReleaseGroup(g)
set g = null
set p = null
endif
if data.codeDmg.codeName == "Lava Strike" then
set a = Ability.GetUnitAbilityByID('FIA4',data.source)
call a.addCooldownRemaining(-(data.damageMod * 0.10))
endif
if data.dmgType != udg_DamageTypeAttack then
set b = GetUnitBuff(data.source,BurningAttacksBonuses.buff)
if b != 0 and b.int == 1 then
set data.trueAttack = true
endif
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real d = 3 + 3 * lvl
if GetHeroMasteryType(u) == 1 and u != t then
call UnitAddBuff(u,u,d,MoltenShield.buff,lvl,0)
endif
call UnitAddBuff(t,u,d,MoltenShield.buff,lvl,0)
set u = null
set t = null
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID and up.isSuperior then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
call a.addFlatCooldown(-SUP_COOLDOWN)
endif
if up.upID == 'FII2' then
set a = Ability.GetUnitAbilityByID('FIA2',up.ownerHero.hero)
call a.addManaCost(-10,0)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call MoltenShield.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPreCalculation(Filter(function onDamage))
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,FireReaver_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope LavaStrike initializer Init
globals
private constant integer SPELL_ID = 'FIA4'
private constant integer UPGRADE_ID = 'FII4'
private constant real DAMAGE_BASE = 180.00
private constant real DAMAGE_LEVEL = 120.00
private constant string MISSILE_SFX = "war3mapImported\\Fireball Major.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private struct LavaStrikeMissile extends array
private static method onFinish takes Missile missile returns boolean
local real dmg
local DamageOptions op
if UnitAlive(missile.target) then
if not TriggerSpellNegation(missile.target) then
set dmg = GetDamage(missile.level)
set op = DamageOptions.create()
set op.trueCritical = true
call CodeDamage.Damage(missile.source,missile.target,dmg,udg_DamageTypeMagic,"Lava Strike",0,op)
endif
if TriggerSpellReflection(missile.target) then
call LavaStrike_SetupMissile.evaluate(missile.target,missile.source,missile.level)
endif
endif
return true
endmethod
implement MissileStruct
endstruct
public function SetupMissile takes unit source, unit target, integer lvl returns Missile
local Missile missile = Missile.create(GetUnitX(source),GetUnitY(source),50,AngleBetweenUnits(source,target),0,50)
set missile.source = source
set missile.owner = GetOwningPlayer(source)
set missile.target = target
set missile.level = lvl
set missile.speed = 25.00
set missile.scale = 1.2
set missile.model = MISSILE_SFX
call LavaStrikeMissile.launch(missile)
return missile
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
call SetupMissile(u,t,lvl)
set u = null
set t = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function Init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,'HFI1')
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
library IronAssembly initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HIA1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'IAI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Death Way"
set up.Text = "Increases |c00b4b4b4Ravager Wheel|r cast range/distance traveled."
set up.SupText = "Increases |c00b4b4b4Ravager Wheel|r area of effect by 60."
set up.LevelData1 = "+100 Cast Range"
set up.LevelData2 = "+150 Cast Range"
set up.LevelData3 = "+200 Cast Range"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'IAI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Static Field"
set up.Text = "Increases |c00b4b4b4Dynamic Shock|r Area of Effect."
set up.SupText = "Reduces |c00b4b4b4Dynamic Shock|r Cooldown by 4s."
set up.LevelData1 = "+50 Area of Effect"
set up.LevelData2 = "+75 Area of Effect"
set up.LevelData3 = "+100 Area of Effect"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'IAI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Titanium Alloy"
set up.Text = "Increases |c00b4b4b4Platinum Alloy|r |c0000ff00Heal|r factor."
set up.SupText = "Increases |c00b4b4b4Platinum Alloy|r duration by 2 seconds."
set up.LevelData1 = "+10% Heal Factor"
set up.LevelData2 = "+15% Heal Factor"
set up.LevelData3 = "+20% Heal Factor"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'IAI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Unstable Core"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HIA1'
set d.Name = "Iron Assembly"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNJunkGolem.blp"
set d.WinAni = "attack"
set d.Block = 0
set d.Evasion = 0
set d.Resistance = 0
set d.LifeRegen = 0.0
set d.ManaRegen = 0.0
set d.Armor = 4
set d.AttackRange = 125
set d.PrimaryAttribute = 3
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'IAA1'
set d.HeroAbility2 = 'IAA2'
set d.HeroAbility3 = 'IAA3'
set d.HeroAbility4 = 'IAA4'
set d.ChooseIconID = 'c035'
set d.ChooseDummy = 'dh35'
set d.spellDamageLevel = 5
set d.attackDamageLevel = 1
set d.healingLevel = 5
set d.survivavilityLevel = 7
set d.movementLevel = 1
set d.crowdControlLevel = 4
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HIAI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope RavagerWheel initializer Init
globals
private constant integer SPELL_ID = 'IAA1'
private constant integer UPGRADE_ID = 'IAI1'
private constant integer EXTRA_ID = 'A02B'
private constant real DAMAGE_BASE = 20.00
private constant real DAMAGE_LEVEL = 20.00
private constant real DISTANCE = 600.00
private constant real AOE = 180.00
private constant real SLOW_MS = 0.50
private constant real SLOW_DURATION = 1.50
private constant real UP_DIST = 50.00
private constant string MISSILE_SFX = "war3mapImported\\Missile_ECM_Beta.mdx"
private constant string HIT_SFX = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct RWheelSlow extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-SLOW_MS,0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02C'
set BUFF_DATA.BuffID = 'B052'
set BUFF_DATA.Name = "Ravager Wheel Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real a = tb.real[2]
local real d = tb.real[3]
local real dmg = tb.real[5]
local effect sfx = tb.effect[6]
local real x = tb.real[7]
local real y = tb.real[8]
local real speed = tb.real[9]
local real time = tb.real[13]
local group g = NewGroup()
local unit temp
local player p = GetOwningPlayer(u)
set d = d - speed
set x = x + speed * Cos(a)
set y = y + speed * Sin(a)
set tb.real[7] = x
set tb.real[8] = y
set tb.real[3] = d
if tb.boolean[20] and d <= 100.00 then
call AIIA.RavagerWheelSecondCast(u)
endif
call BlzSetSpecialEffectX(sfx,x)
call BlzSetSpecialEffectY(sfx,y)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(x,y) + 25.00)
call GroupEnumUnitsInRange(g,x,y,tb.real[15],null)
set time = time + 0.03125
if time >= 0.25 then
set time = 0.00
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,temp,"chest"))
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call UnitAddBuff(temp,u,SLOW_DURATION,RWheelSlow.buff,0,0)
endif
endloop
call ReleaseGroup(g)
endif
set tb.real[13] = time
if d <= 0 then
call BlzSetSpecialEffectScale(sfx,1.0)
call DestroyEffect(sfx)
call DestroyEffect(tb.effect[12])
call DestroyEffect(tb.effect[19])
call UnitRemoveAbility(u,EXTRA_ID)
call BlzUnitHideAbility(u,SPELL_ID,false)
call SetUnitData(u,"RWheel_Inst",0)
call ReleaseTimer(t)
call tb.flush()
call tb.destroy()
endif
set g = null
set u = null
set t = null
set p = null
set sfx = null
endfunction
private function onCastExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local Table tb = GetUnitData(u,"RWheel_Inst")
if tb != 0 then
if BlzGetUnitAbilityCooldown(u,EXTRA_ID,0) == 20.00 then
set tb.boolean[4] = true
set tb.real[10] = x
set tb.real[11] = y
set tb.real[2] = Angle(tb.real[7],tb.real[8],x,y)
set tb.real[3] = DISTANCE + tb.real[14]
set tb.effect[12] = AddSpecialEffect("Abilities\\Spells\\Other\\GeneralAuraTarget\\GeneralAuraTarget.mdl",x,y)
call BlzSetSpecialEffectYaw(tb.effect[6],tb.real[2])
if GetHeroMasteryType(u) == 2 then
call BlzSetUnitAbilityCooldown(u,EXTRA_ID,0,0.5)
endif
else
set tb.boolean[16] = true
set tb.real[17] = x
set tb.real[18] = y
set tb.real[2] = Angle(tb.real[7],tb.real[8],x,y)
set tb.real[3] = DISTANCE + tb.real[14]
set tb.effect[19] = AddSpecialEffect("Abilities\\Spells\\Other\\GeneralAuraTarget\\GeneralAuraTarget.mdl",x,y)
call BlzSetSpecialEffectYaw(tb.effect[6],tb.real[2])
call BlzSetUnitAbilityCooldown(u,EXTRA_ID,0,3600.00)
endif
endif
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real xu = GetUnitX(u)
local real yu = GetUnitY(u)
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Table tb = Table.create()
local effect sfx
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local real updist = 0
if ulvl != 0 then
set updist = UP_DIST + UP_DIST * ulvl
set tb.real[14] = updist
endif
set tb.unit[0] = u
set tb.integer[1] = lvl
set tb.real[2] = Angle(xu,yu,x,y)
set tb.real[3] = DISTANCE + updist
set tb.boolean[4] = false
set tb.real[5] = GetDamage(lvl)
set sfx = AddSpecialEffect(MISSILE_SFX,xu,yu)
call BlzSetSpecialEffectHeight(sfx,GetLocZ(xu,yu) + 25)
call BlzSetSpecialEffectTimeScale(sfx,1.6)
call BlzSetSpecialEffectYaw(sfx,tb.real[2])
set tb.effect[6] = sfx
set tb.real[7] = xu
set tb.real[8] = yu
set tb.real[9] = 14.00
set tb.real[13] = 0.00
if IsUpgradeSuperior(u,UPGRADE_ID) then
set tb.real[15] = AOE + 60
call BlzSetSpecialEffectScale(sfx,2.3)
else
set tb.real[15] = AOE
call BlzSetSpecialEffectScale(sfx,2.0)
endif
set tb.boolean[20] = GetPlayerController(GetOwningPlayer(u)) == MAP_CONTROL_COMPUTER
call SetUnitData(u,"RWheel_Inst",tb)
set sfx = null
call UnitAddAbility(u,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
call BlzUnitHideAbility(u,SPELL_ID,true)
call TimerStart(NewTimerEx(tb),0.03125,true,function Callback)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RWheelSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCastExtra)
endfunction
private function Init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,'HIA1')
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(MISSILE_SFX)
endfunction
endscope
scope DynamicShock initializer Init
globals
private constant integer SPELL_ID = 'IAA2'
private constant integer UPGRADE_ID = 'IAI2'
private constant integer EXTRA_ID = 'A02D'
private constant real DAMAGE_BASE = 50.00
private constant real DAMAGE_LEVEL = 40.00
private constant real AOE = 400.00
private constant integer SHOCK_COUNT = 4
private constant real UP_AOE = 25.00
private constant string DMG_SFX = "Abilities\\Weapons\\ChimaeraLightningMissile\\ChimaeraLightningMissile.mdl"
private constant string CHANNEL_SFX = "war3mapImported\\EtherealAura.mdl"
private constant string ICON_DRAG = "ReplaceableTextures\\CommandButtons\\BTNLoad.blp"
private constant string ICON_REPEL = "ReplaceableTextures\\CommandButtons\\BTNUnload.blp"
private KPJConfig DSKnockConfig
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetUnitByIndex(GetTimerData(t))
call UnitRemoveAbility(u,'BNms')
call ReleaseTimer(t)
set t = null
set u = null
endfunction
private function onCastExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer op = GetUnitData(u,"DS_option")
call TimerStart(NewTimerEx(GetUnitUserData(u)),0.00,false,function Callback)
if op == 1 then
set op = 2
call BlzSetAbilityIcon(EXTRA_ID,ICON_DRAG)
else
set op = 1
call BlzSetAbilityIcon(EXTRA_ID,ICON_REPEL)
endif
call SetUnitData(u,"DS_option",op)
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetTriggerPlayer()
local group g = NewGroup()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local integer op = GetUnitData(u,"DS_option")
local real xt
local real yt
local real dmg = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
local unit temp
call GroupEnumUnitsInRange(g,x,y,AOE,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) then
set xt = GetUnitX(temp)
set yt = GetUnitY(temp)
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
call DestroyEffect(AddSpecialEffectTarget(DMG_SFX,temp,"origin"))
if op == 1 then
call KPJUnit.create(temp,300.00,Angle(x,y,xt,yt),1.2,130,DSKnockConfig,KPJ_TYPE_JUMP)
else
call KPJUnit.create(temp,Distance(x,y,xt,yt) - 50,Angle(xt,yt,x,y),1.2,130,DSKnockConfig,KPJ_TYPE_JUMP)
endif
call Lightning.create("CLPB",u,temp,1.2,0.6,75,75)
endif
endloop
if GetPlayerController(GetOwningPlayer(u)) == MAP_CONTROL_COMPUTER then
call BlzUnitDisableAbility(u,EXTRA_ID,true,false)
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetTriggerUnit()
if GetLearnedSkillLevel() == 1 then
call UnitAddAbility(u,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
call SetUnitData(u,"DS_option",1)
call BlzSetAbilityIcon(EXTRA_ID,ICON_REPEL)
endif
set u = null
endfunction
private function onChannel takes nothing returns nothing
local unit u = GetTriggerUnit()
local Table tb = Table.create()
local AoE aoe = AoE.create(GetUnitX(u),GetUnitY(u),null,AOE)
local effect sfx = AddSpecialEffect(CHANNEL_SFX,GetUnitX(u),GetUnitY(u))
local integer op = GetUnitData(u,"DS_option")
call BlzSetSpecialEffectColor(aoe.sfx,0,0,255)
call BlzSetSpecialEffectScale(sfx,2.0)
if op == 1 then
call BlzSetSpecialEffectTimeScale(sfx,2.5)
else
call BlzSetSpecialEffectTimeScale(sfx,-2.5)
endif
set tb.integer[0] = aoe
set tb.effect[1] = sfx
set tb.effect[2] = AddSpecialEffectTarget(DMG_SFX,u,"hand right")
set tb.effect[3] = AddSpecialEffectTarget(DMG_SFX,u,"hand left")
call SetUnitData(u,"DynamicShockChannel",tb)
set u = null
set sfx = null
endfunction
private function onEndChannel takes nothing returns nothing
local unit u = GetTriggerUnit()
local Table tb = GetUnitData(u,"DynamicShockChannel")
local AoE aoe = tb.integer[0]
local effect sfx = tb.effect[1]
call aoe.destroy()
call BlzSetSpecialEffectScale(sfx,0)
call DestroyEffect(sfx)
call DestroyEffect(tb.effect[2])
call DestroyEffect(tb.effect[3])
call tb.flush()
call tb.destroy()
set u = null
set sfx = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCastExtra)
call RegisterSpellChannelEvent(SPELL_ID, function onChannel)
call RegisterSpellEndCastEvent(SPELL_ID, function onEndChannel)
call RegisterSpellLearn(SPELL_ID, function onLearn)
set DSKnockConfig = KPJConfig.create()
set DSKnockConfig.friction = 0
set DSKnockConfig.gravity = 0.2
set DSKnockConfig.disable = true
set DSKnockConfig.hardDisable = false
set DSKnockConfig.killTrees = true
set DSKnockConfig.sfxModel = ""
set DSKnockConfig.sfxTime = 0.35
endfunction
private function Init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,'HIA1')
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(DMG_SFX)
endfunction
endscope
scope PlatinumAlloy initializer Init
globals
private constant integer SPELL_ID = 'IAA3'
private constant integer UPGRADE_ID = 'IAI3'
private constant integer CHANCE_BASE = 10
private constant integer CHANCE_LEVEL = 4
private constant real SLOW = 0.50
private constant real BUFF_DURATION = 4.00
private constant real SUP_DURATION = 2.00
private constant string EFFECT_SFX = "Abilities\\Spells\\Items\\StaffOfPurification\\PurificationTarget.mdl"
endglobals
private function GetChance takes integer lvl returns integer
return CHANCE_BASE + CHANCE_LEVEL * lvl
endfunction
struct PlatinumAlloy extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-SLOW,0)
set b.int = GetUpgradeSkillLevel(b.target,UPGRADE_ID)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A02K'
set BUFF_DATA.BuffID = 'B053'
set BUFF_DATA.Name = "Platinum Alloy"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.EffectType = EFFECT_TYPE_HEAL
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = BUFF_DURATION
if IsUpgradeSuperior(u,UPGRADE_ID) then
set d = d + SUP_DURATION
endif
call UnitAddBuff(u,u,d,PlatinumAlloy.buff,0,0)
set u = null
endfunction
private function onDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer lvl
local real factor
local Buff b
local Ability a
if data.dmgType != udg_DamageTypeHeal and data.dmgType != udg_DamageTypeHealOverTime then
if data.damageMod != 0 and not data.isAbsorbed then
set lvl = GetUnitAbilityLevel(data.target,SPELL_ID)
if lvl != 0 then
set b = GetUnitBuff(data.target,PlatinumAlloy.buff)
if b != 0 then
set factor = 0.50 + (0.05 + 0.05 * b.int)
set data.source = data.target
set data.dmgType = udg_DamageTypeHeal
set data.notCritical = true
set data.damageMod = data.damageMod * factor
call DestroyEffect(AddSpecialEffectTarget(EFFECT_SFX,data.target,"chest"))
else
if data.dmgType == udg_DamageTypeAttack then
if GetRandomInt(1,100) <= GetChance(lvl) then
set factor = 0.50 + (0.05 + 0.05 * GetUpgradeSkillLevel(data.target,UPGRADE_ID))
set data.source = data.target
set data.dmgType = udg_DamageTypeHeal
set data.notCritical = true
set data.damageMod = data.damageMod * factor
call DestroyEffect(AddSpecialEffectTarget(EFFECT_SFX,data.target,"chest"))
if GetHeroMasteryType(data.target) == 3 then
if BlzGetUnitAbilityCooldownRemaining(data.target,SPELL_ID) != 0 then
set a = Ability.GetUnitAbilityByID(SPELL_ID,data.target)
call a.addCooldownRemaining(-2.0)
endif
endif
endif
else
if GetHeroMasteryType(data.target) == 1 then
if GetRandomInt(1,100) <= 17 then
set factor = 0.50 + (0.05 + 0.05 * GetUpgradeSkillLevel(data.target,UPGRADE_ID))
set data.source = data.target
set data.dmgType = udg_DamageTypeHeal
set data.notCritical = true
set data.damageMod = data.damageMod * factor
call DestroyEffect(AddSpecialEffectTarget(EFFECT_SFX,data.target,"chest"))
endif
endif
endif
endif
endif
endif
endif
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == 'IAI1' then
set a = Ability.GetUnitAbilityByID('IAA1',up.ownerHero.hero)
if up.level == 1 then
call a.addCastRange(100)
else
call a.addCastRange(50)
endif
endif
if up.upID == 'IAI2' then
if up.isSuperior then
set a = Ability.GetUnitAbilityByID('IAA2',up.ownerHero.hero)
call a.addFlatCooldown(-4.0)
endif
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call PlatinumAlloy.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call DamageEvent.RegisterPostCalculation(Filter(function onDamage))
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
endfunction
private function Init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,'HIA1')
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
scope HeatWave initializer Init
globals
private constant integer SPELL_ID = 'IAA4'
private constant integer UPGRADE_ID = 'IAI4'
private constant real DMG_BASE = 200.00
private constant real DMG_LEVEL = 70.00
private constant real DELAY = 4.00
private constant real AREA_OF_EFFECT = 800.00
private constant string EFFECT_SFX = "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
private constant string FIRE_SFX = "war3mapImported\\FireModel.mdl"
endglobals
private function GetDamage takes integer lvl returns real
return DMG_BASE + DMG_LEVEL * lvl
endfunction
private struct HWEffect extends array
implement Alloc
effect sfx
real scale
real cos
real sin
public method destroy takes nothing returns nothing
call BlzSetSpecialEffectScale(sfx,0.0)
call DestroyEffect(sfx)
set sfx = null
call this.deallocate()
endmethod
public static method create takes real x, real y, real a returns thistype
local thistype this = thistype.allocate()
set sfx = AddSpecialEffect(FIRE_SFX,x,y)
set cos = Cos(a * bj_DEGTORAD)
set sin = Sin(a * bj_DEGTORAD)
call BlzSetSpecialEffectYaw(sfx,a * bj_DEGTORAD)
call BlzSetSpecialEffectAlpha(sfx,0)
call BlzSetSpecialEffectScale(sfx,0.0)
set scale = 0.0
return this
endmethod
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local real time = tb.real[1]
local texttag txt = tb.texttag[2]
local integer c = tb.integer[3]
local LinkedList list = tb.integer[4]
local real timedmg = tb.real[5]
local real dist = tb.real[6]
local group g2 = tb.group[7]
local Link h = list.head
local HWEffect hw
local group g
local real dmg
local player p
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real d
local unit temp
local AoE aoe1
local AoE aoe2
set time = time - 0.03125
set tb.real[1] = time
if time <= 0.00 or not UnitAlive(u) then
set AIIA.RActivated = false
set dmg = tb.real[8]
if dist == 0 then
set tb.real[9] = x
set tb.real[10] = y
call DestroyTextTag(txt)
call CodeDamage.Damage(u,u,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
loop
exitwhen h == 0
set hw = h.data
if dist == 0.00 then
call DestroyEffect(AddSpecialEffect(EFFECT_SFX,x,y))
call BlzSetSpecialEffectX(hw.sfx,x)
call BlzSetSpecialEffectY(hw.sfx,y)
call BlzSetSpecialEffectAlpha(hw.sfx,255)
endif
call BlzSetSpecialEffectX(hw.sfx,BlzGetLocalSpecialEffectX(hw.sfx) + 5.00 * hw.cos)
call BlzSetSpecialEffectY(hw.sfx,BlzGetLocalSpecialEffectY(hw.sfx) + 5.00 * hw.sin)
set hw.scale = hw.scale + 0.02
call BlzSetSpecialEffectScale(hw.sfx,hw.scale)
set h = h.next
endloop
set x = tb.real[9]
set y = tb.real[10]
set g = NewGroup()
set dmg = tb.real[8]
set p = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g,x,y,dist + 100.00,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) and not IsUnitMagicImmune(temp) and not IsUnitInGroup(temp,g2) then
set d = Distance(GetUnitX(temp),GetUnitY(temp),x,y)
if d >= dist - 100 and d <= dist + 100 then
call GroupAddUnit(g2,temp)
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypeMagicAoe,"",0,0)
endif
endif
endloop
call ReleaseGroup(g)
set timedmg = timedmg + 0.03125
set dist = dist + 5.00
set aoe1 = tb.integer[12]
call aoe1.move(x,y)
if dist >= 100 then
call aoe1.setSize(dist - 100)
endif
set aoe2 = tb.integer[13]
call aoe2.move(x,y)
call aoe2.setSize(dist + 100.00)
if timedmg >= 0.50 then
call DestroyGroup(g2)
set g2 = NewGroup()
set tb.group[7] = g2
set timedmg = 0.00
endif
set tb.real[5] = timedmg
set tb.real[6] = dist
if dist >= tb.real[11] then
set h = list.head
loop
exitwhen h == 0
set hw = h.data
call hw.destroy()
set h = h.next
endloop
call aoe1.destroy()
call aoe2.destroy()
call ReleaseGroup(g2)
call list.destroy()
call ReleaseTimer(t)
call SetUnitVertexColor(u,255,255,255,255)
call tb.flush()
call tb.destroy()
endif
set g = null
set p = null
else
set tb.integer[3] = c - 3
call SetTextTagPos(txt,x - 50.00,y,250.00)
call SetUnitVertexColor(u,255,c,c,255)
call SetTextTagText(txt,R2SW(time,2,1),TextTagSize2Height(20))
endif
set txt = null
set t = null
set u = null
set g2 = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local Table tb = Table.create()
local texttag txt = CreateTextTag()
local integer i = 360
local LinkedList list = LinkedList.create()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real a
local AoE aoe = AoE.create(x,y,null,1)
call BlzSetSpecialEffectColor(aoe.sfx,255,200,0)
set tb.unit[0] = u
set tb.real[1] = DELAY
set tb.texttag[2] = txt
set tb.integer[3] = 255
set tb.integer[4] = list
set tb.real[5] = 0.00
set tb.real[6] = 0.00
set tb.group[7] = NewGroup()
set tb.real[8] = GetDamage(GetUnitAbilityLevel(u,SPELL_ID))
if GetUpgradeSkillLevel(u,UPGRADE_ID) != 0 then
set tb.real[11] = AREA_OF_EFFECT + 200.00
else
set tb.real[11] = AREA_OF_EFFECT
endif
set tb.integer[12] = aoe
set aoe = AoE.create(x,y,null,1)
call BlzSetSpecialEffectColor(aoe.sfx,255,200,0)
set tb.integer[13] = aoe
call SetTextTagPermanent(txt,false)
call SetTextTagPos(txt,x - 50.00,y,250.00)
call SetTextTagText(txt,"3.0",TextTagSize2Height(20))
call SetTextTagVisibility(txt,true)
call SetTextTagColor(txt,255,0,0,255)
call TimerStart(NewTimerEx(tb),0.03125,true,function Callback)
loop
exitwhen i == 0
call list.add(HWEffect.create(x,y,i))
set i = i - 10
endloop
set txt = null
set u = null
endfunction
private function onLearn takes nothing returns nothing
if GetLearnedSkillLevel() == 1 and GetPlayerController(GetTriggerPlayer()) == MAP_CONTROL_COMPUTER then
call BlzUnitDisableAbility(GetLearningUnit(),SPELL_ID,true,false)
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellLearn(SPELL_ID, function onLearn)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
endfunction
private function Init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,'HIA1')
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
endfunction
endscope
library TheReaper initializer InitData uses HeroLibrary
globals
public constant integer HERO_ID = 'HTR1'
endglobals
private function UPGRADE_DATA takes HeroData d returns nothing
local UpgradeData up = UpgradeData.create()
set up.UpId = 'TRI1'
set up.UpIndex = UPGRADE_FIRST
set up.UpAbility = UPGRADE1_ID
set up.Name = "Life Gathering"
set up.Text = "Enemies hit by |c00b4b4b4Scythe Swing|r gives |c00b4b4b4Thanatos|r a % of their max Hp."
set up.SupText = "Increases |c00b4b4b4Scythe Swing|r damage by 10% of enemies missing Hp."
set up.LevelData1 = "6% of Enemies Max Hp"
set up.LevelData2 = "8% of Enemies Max Hp"
set up.LevelData3 = "10% of Enemies Max Hp"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNSerpentWard.blp"
set d.HeroUp1 = up
set up = UpgradeData.create()
set up.UpId = 'TRI2'
set up.UpIndex = UPGRADE_SECOND
set up.UpAbility = UPGRADE2_ID
set up.Name = "Darkness"
set up.Text = "Reduces |c00b4b4b4Death Gloom|r Cooldown."
set up.SupText = "|c00b4b4b4Death Gloom|r remains as long as there are heroes inside."
set up.LevelData1 = "-2s Cooldown"
set up.LevelData2 = "-3s Cooldown"
set up.LevelData3 = "-4s Cooldown"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNAnimalWarTraining.blp"
set d.HeroUp2 = up
set up = UpgradeData.create()
set up.UpId = 'TRI3'
set up.UpIndex = UPGRADE_THIRD
set up.UpAbility = UPGRADE3_ID
set up.Name = "Swift Execution"
set up.Text = "|c00b4b4b4Grim Cloak|r increases |c00ffff95Attack Speed|r."
set up.SupText = "Each attack while |c00b4b4b4Grim Cloak|r is active, reduces its cooldown by 1 second."
set up.LevelData1 = "+30% Attack Speed"
set up.LevelData2 = "+45% Attack Speed"
set up.LevelData3 = "+60% Attack Speed"
set up.Icon = "ReplaceableTextures\\CommandButtons\\BTNThunderLizardVizier.blp"
set d.HeroUp3 = up
set up = UpgradeData.create()
set up.UpId = 'TRI4'
set up.UpIndex = UPGRADE_FOURTH
set up.Name = "Vicious Destiny"
set d.HeroUp4 = up
endfunction
private function InitData takes nothing returns nothing
local HeroData d = HeroData.create()
set d.TypeID = 'HTR1'
set d.Name = "The Reaper"
set d.IconID = "ReplaceableTextures\\CommandButtons\\BTNWight.blp"
set d.WinAni = "attack walk stand spin"
set d.Block = 0
set d.Evasion = 15
set d.Resistance = 15
set d.LifeRegen = 2.0
set d.ManaRegen = 0.5
set d.Armor = 1
set d.AttackRange = 125
set d.PrimaryAttribute = 1
call UPGRADE_DATA(d)
set d.HeroAbility1 = 'TRA1'
set d.HeroAbility2 = 'TRA2'
set d.HeroAbility3 = 'TRA3'
set d.HeroAbility4 = 'TRA4'
set d.ChooseIconID = 'c035'
set d.ChooseDummy = 'dh37'
set d.spellDamageLevel = 6
set d.attackDamageLevel = 6
set d.healingLevel = 4
set d.survivavilityLevel = 4
set d.movementLevel = 2
set d.crowdControlLevel = 1
set d.HeroFaction = Game.FACTION_NEUTRAL
set d.InfoID = 'HTRI'
call HeroData.AddRandomData(d)
call PreloadGen.Add(d.TypeID,PRELOAD_UNIT)
call PreloadGen.Add(d.ChooseIconID,PRELOAD_SECOND)
endfunction
endlibrary
scope ScytheSwing initializer init
globals
private constant integer SPELL_ID = 'TRA1'
private constant integer UPGRADE_ID = 'TRI1'
private constant real DAMAGE_BASE = 60.00
private constant real DAMAGE_LEVEL = 30.00
private constant real SLOW_BASE = 0.75
private constant real AOE = 400.00
private constant real UP_HP = 0.04
private constant real UP_HP_LVL = 0.02
private constant real SUP_DMG = 0.10
private constant string EFFECT_SFX = "war3mapImported\\Culling Cleave.mdx"
endglobals
private function GetDamage takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct ScytheSwingSlow extends array
Movespeed ms
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
call ms.destroy()
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ms = Movespeed.create(b.target,-SLOW_BASE,0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A05U'
set BUFF_DATA.BuffID = 'B026'
set BUFF_DATA.Name = "Scythe Swing Slow"
set BUFF_DATA.BuffType = BUFF_TYPE_NEGATIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.EffectType = EFFECT_TYPE_SLOW
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local effect sfx2 = tb.effect[1]
local real time = tb.real[2]
local DeathThreat dt = tb.integer[3]
local integer ulvl = GetUpgradeSkillLevel(u,UPGRADE_ID)
local boolean sup = IsUpgradeSuperior(u,UPGRADE_ID)
local boolean b2
local real x
local real y
local real a
local integer lvl
local group g
local player p
local real dmg
local effect sfx
local unit temp
if dt == 0 then
set x = GetUnitX(u)
set y = GetUnitY(u)
set a = GetUnitFacing(u) * bj_DEGTORAD
else
set x = BlzGetLocalSpecialEffectX(dt.dummy)
set y = BlzGetLocalSpecialEffectY(dt.dummy)
set a = dt.angle
endif
set time = time + 0.03125
set tb.real[2] = time
call BlzSetSpecialEffectX(sfx2,x)
call BlzSetSpecialEffectY(sfx2,y)
call BlzSetSpecialEffectHeight(sfx2,GetLocZ(x,y))
call BlzSetSpecialEffectYaw(sfx2,a)
if time >= 0.5 then
set lvl = GetUnitAbilityLevel(u,SPELL_ID)
set g = NewGroup()
set p = GetOwningPlayer(u)
set dmg = GetDamage(lvl)
set sfx = AddSpecialEffect(EFFECT_SFX,x + 40 * Cos(a),y + 40 * Sin(a))
call BlzSetSpecialEffectScale(sfx,1.6)
call BlzSetSpecialEffectYaw(sfx,a)
call BlzSetSpecialEffectTimeScale(sfx,0.8)
call DestroyEffect(sfx)
call GroupEnumUnitsInRange(g,x,y,AOE,null)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_UNIT_ENEMY(temp,p) then
if dt != 0 then
set b2 = IsPointInSightOfAngle(dt.angle * bj_RADTODEG,BlzGetLocalSpecialEffectX(dt.dummy),BlzGetLocalSpecialEffectY(dt.dummy),GetUnitX(temp),GetUnitY(temp),110.00)
else
set b2 = IsUnitInSightOfUnit(u,temp,110.00)
endif
if b2 then
if sup then
call CodeDamage.Damage(u,temp,dmg + GetUnitMissingLife(temp) * SUP_DMG,udg_DamageTypePhysicalAoe,"",0,0)
else
call CodeDamage.Damage(u,temp,dmg,udg_DamageTypePhysicalAoe,"",0,0)
endif
call UnitAddBuff(temp,u,1.6,ScytheSwingSlow.buff,lvl,0)
if ulvl != 0 then
call UnitAddHp(u,BlzGetUnitMaxHP(temp) * (UP_HP + UP_HP_LVL * ulvl))
endif
endif
endif
endloop
set dt.qcast = false
call BlzSetSpecialEffectAlpha(sfx2,0)
call DestroyEffect(sfx2)
call ReleaseGroup(g)
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
set g = null
set p = null
set sfx = null
endif
set sfx2 = null
set t = null
set u = null
endfunction
private function CreateScytheSwing takes unit u, DeathThreat dt returns nothing
local Table tb = Table.create()
local effect sfx2
local real x
local real y
local real a
if dt == 0 then
set x = GetUnitX(u)
set y = GetUnitY(u)
set a = GetUnitFacing(u) * bj_DEGTORAD
else
set x = BlzGetLocalSpecialEffectX(dt.dummy)
set y = BlzGetLocalSpecialEffectY(dt.dummy)
set a = dt.angle
set dt.qcast = true
endif
set sfx2 = AddSpecialEffect("war3mapImported\\Wight.mdl",x,y)
call BlzSetSpecialEffectAlpha(sfx2,120)
call BlzSetSpecialEffectScale(sfx2,1.0)
call BlzSetSpecialEffectYaw(sfx2,a)
call BlzSetSpecialEffectColorByPlayer(sfx2,Player(PLAYER_NEUTRAL_PASSIVE))
call BlzSpecialEffectAddSubAnimation(sfx2,SUBANIM_TYPE_SLAM)
call BlzPlaySpecialEffectWithTimeScale(sfx2,ANIM_TYPE_ATTACK,0.9)
set tb.unit[0] = u
set tb.effect[1] = sfx2
set tb.real[2] = 0.00
set tb.integer[3] = dt
call TimerStart(NewTimerEx(tb),0.03125,true,function Callback)
set sfx2 = null
set u = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local Link h
call CreateScytheSwing(u,0)
if DeathThreat_INSTANCES.size != 0 then
set h = DeathThreat_INSTANCES.head
loop
exitwhen h == 0
if DeathThreat[h.data].source == u then
call CreateScytheSwing(u,h.data)
endif
set h = h.next
endloop
endif
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
if GetLearnedSkillLevel() == 1 then
if GetPlayerController(GetTriggerPlayer()) == MAP_CONTROL_COMPUTER then
call BlzUnitDisableAbility(u,SPELL_ID,true,false)
endif
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "Q"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call ScytheSwingSlow.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TheReaper_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(EFFECT_SFX)
endfunction
endscope
scope DeathGloom initializer init
globals
private constant integer SPELL_ID = 'TRA2'
private constant integer UPGRADE_ID = 'TRI2'
private constant real DAMAGE_BASE = 0.40
private constant real DAMAGE_LEVEL = 0.20
private constant real DURATION = 5.00
private constant real AOE = 250.00
private Effect SFX
private constant string AREA_SFX = "SharedModels\\UBirth.mdl"
endglobals
private function GetDamageModification takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct DeathGloom extends array
real dmgMod
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set dmgMod = GetDamageModification(b.level)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0D4'
set BUFF_DATA.BuffID = 'B05V'
set BUFF_DATA.Name = "Death Gloom"
set BUFF_DATA.BuffType = BUFF_TYPE_NEUTRAL
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = false
set BUFF_DATA.Stealable = false
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local Table tb = GetTimerData(t)
local unit u = tb.unit[0]
local effect sfx = tb.effect[1]
local real time = tb.real[2]
local real x = tb.real[4]
local real y = tb.real[5]
local integer lvl = tb.integer[6]
local player p = GetOwningPlayer(u)
local boolean sup = IsUpgradeSuperior(u,UPGRADE_ID)
local group g
local unit temp
local Buff b
local boolean flag = false
local effect sfx2
set time = time - 0.20
if time > 0 then
set g = NewGroup()
call GroupEnumUnitsInRange(g,x,y,AOE,null)
set p = GetOwningPlayer(u)
loop
set temp = FirstOfGroup(g)
exitwhen temp == null
call GroupRemoveUnit(g,temp)
if FILT_VALID_UNIT(temp) then
set flag = true
set b = GetUnitBuff(temp,DeathGloom.buff)
if b != 0 then
set b.elapsedTime = 0.00
else
call UnitAddBuff(temp,u,1.0,DeathGloom.buff,lvl,0)
set sfx2 = AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIso\\AIsoTarget.mdl",temp,"origin")
call BlzSetSpecialEffectTime(sfx2,1.5)
call BlzSetSpecialEffectTimeScale(sfx2,1.1)
call DestroyEffect(sfx2)
if IsUnitEnemy(temp,p) then
call Status.Add(STATUS_ENTANGLE,temp,1.0,SFX)
endif
endif
endif
endloop
call ReleaseGroup(g)
if sup and flag then
set time = time + 0.20
endif
set tb.real[2] = time
set sfx2 = null
else
call BlzSetSpecialEffectAlpha(sfx,0)
call DestroyEffect(sfx)
call tb.flush()
call tb.destroy()
call ReleaseTimer(t)
endif
set sfx = null
set t = null
set u = null
set p = null
set g = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local Table tb = Table.create()
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local effect sfx = AddSpecialEffect(AREA_SFX,x,y)
call BlzSetSpecialEffectTime(sfx,5.0)
call BlzSetSpecialEffectScale(sfx,1.0)
call BlzSetSpecialEffectTimeScale(sfx,0.8)
set tb.unit[0] = u
set tb.effect[1] = sfx
set tb.real[2] = DURATION
set tb.real[4] = x
set tb.real[5] = y
set tb.integer[6] = GetUnitAbilityLevel(u,SPELL_ID)
call TimerStart(NewTimerEx(tb),0.20,true,function Callback)
set sfx = null
set u = null
endfunction
private function onPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local Buff b
if data.dmgType == udg_DamageTypePhysical or data.dmgType == udg_DamageTypePhysicalAoe or data.dmgType == udg_DamageTypePhysicalOverTime then
set b = GetUnitBuff(data.target,DeathGloom.buff)
if b != 0 then
set data.mult = data.mult + DeathGloom[b.buffAllocIndex].dmgMod
endif
elseif data.dmgType == udg_DamageTypeMagic or data.dmgType == udg_DamageTypeMagicAoe or data.dmgType == udg_DamageTypeMagicOverTime then
set b = GetUnitBuff(data.target,DeathGloom.buff)
if b != 0 then
set data.mult = data.mult - DeathGloom[b.buffAllocIndex].dmgMod
endif
endif
endfunction
private function OnUpgrade takes nothing returns nothing
local Upgrade up = GetEventUpgrade()
local Ability a
if up.upID == UPGRADE_ID then
set a = Ability.GetUnitAbilityByID(SPELL_ID,up.ownerHero.hero)
if up.level == 1 then
call a.addFlatCooldown(-2.00)
else
call a.addFlatCooldown(-1.00)
endif
endif
if up.upID == 'TRI4' and up.level == 1 then
set a = Ability.GetUnitAbilityByID('TRA4',up.ownerHero.hero)
call a.addFlatCooldown(-(Players[GetPlayerId(GetOwningPlayer(up.ownerHero.hero))].kills * 3))
endif
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "W"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call DeathGloom.Initialize()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterUpgradeSkillEvent(Filter(function OnUpgrade))
call DamageEvent.RegisterPreCalculation(Filter(function onPreDamage))
set SFX = Effect.create("","origin")
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TheReaper_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
scope GrimCloak initializer init
globals
private constant integer SPELL_ID = 'TRA3'
private constant integer UPGRADE_ID = 'TRI3'
private constant real DAMAGE_LEVEL = 0.40
private constant real DAMAGE_BASE = 0.20
private constant real DURATION = 2.80
private constant integer UP_AS = 15
private constant string AREA_SFX = "war3mapImported\\LightningNova.mdx"
endglobals
private function GetDamageIncreased takes integer lvl returns real
return DAMAGE_BASE + DAMAGE_LEVEL * lvl
endfunction
struct GrimCloak extends array
integer as
integer ac
private static method onRemove takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if as != 0 then
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,-as,0,true)
set as = 0
endif
if GetHeroMasteryType(b.target) == 1 then
call SetUnitData(b.target,"GrimCloackCounter",ac)
endif
endmethod
private static method onPeriodic takes Buff b returns nothing
local thistype this = b.buffAllocIndex
set ac = ac + 1
endmethod
private static method onApply takes Buff b returns nothing
local thistype this = b.buffAllocIndex
if b.int != 0 then
set as = UP_AS + UP_AS * b.int
call BonusStruct.Add(BONUS_TYPE_ATTACK_SPEED,b.target,as,0,true)
endif
set ac = 0
call SetUnitData(b.target,"GrimCloackCounter",0)
endmethod
public static method ConfigData takes nothing returns nothing
set BUFF_DATA = BuffData.create()
set BUFF_DATA.AuraID = 'A0D5'
set BUFF_DATA.BuffID = 'B05W'
set BUFF_DATA.Name = "Grim Cloak"
set BUFF_DATA.BuffType = BUFF_TYPE_POSITIVE
set BUFF_DATA.StackType = STACK_TYPE_NOSTACK
set BUFF_DATA.StackRules = STACK_RULES_UNIQUE_SOURCE
set BUFF_DATA.StackMax = 0
set BUFF_DATA.Period = 1.00
set BUFF_DATA.Persistent = false
set BUFF_DATA.Dispelable = true
set BUFF_DATA.Stealable = true
endmethod
implement BuffCore
endstruct
private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = GetUnitByIndex(GetTimerData(t))
local real hp = GetUnitLifePercent(u)
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local real dmg = GetDamageIncreased(lvl) * 100.00
local real factor = 100 / dmg
local real x = (100 - hp) / factor
call SetUnitData(u,"GCnD",R2I(x))
set t = null
set u = null
endfunction
private function OnPreDamage takes nothing returns nothing
local DamageData data = DamageEvent.EventData
local integer c
local Ability a
local Buff b
if GetUnitAbilityLevel(data.source,SPELL_ID) != 0 then
if data.dmgType == udg_DamageTypeAttack then
set c = GetUnitData(data.source,"GCnD")
set data.mult = data.mult + (c / 100.00)
if IsUpgradeSuperior(data.source,UPGRADE_ID) then
set a = Ability.GetUnitAbilityByID(SPELL_ID,data.source)
if a != 0 then
call a.addCooldownRemaining(-1.0)
endif
endif
endif
endif
set b = GetUnitBuff(data.source,GrimCloak.buff)
if b != 0 then
if data.dmgType == udg_DamageTypeAttack and not data.isMiss then
set b.elapsedTime = 0
endif
endif
set b = GetUnitBuff(data.target,GrimCloak.buff)
if b != 0 and data.damageMod > 0 then
if GetWidgetLife(data.target) - data.damageMod <= 0.405 then
call SetUnitState(data.target,UNIT_STATE_LIFE,1.00)
set data.damageMod = 0
set data.isAbsorbed = true
endif
endif
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
call UnitAddBuff(u,u,DURATION,GrimCloak.buff,0,GetUpgradeSkillLevel(u,UPGRADE_ID))
set u = null
endfunction
private function onLearn takes nothing returns nothing
local unit u = GetLearningUnit()
local timer t
if GetLearnedSkillLevel() == 1 then
set t = NewTimerEx(GetUnitUserData(u))
call TimerStart(t,0.25,true,function Callback)
endif
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "E"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call GrimCloak.Initialize()
call DamageEvent.RegisterPreCalculation(Filter(function OnPreDamage))
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellLearn(SPELL_ID, function onLearn)
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TheReaper_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(AREA_SFX)
endfunction
endscope
scope DeathThreat initializer init
globals
private constant integer SPELL_ID = 'TRA4'
private constant integer EXTRA_ID = 'A0D6'
private constant integer UPGRADE_ID = 'TRI4'
private constant real DMG_BASE = 20
private constant real HP_DMG_BASE = 0.01
private constant real HP_DMG_LEVEL = 0.01
private constant real DURATION = 6.00
private constant string DUMMY_SFX = "war3mapImported\\Wight.mdl"
private constant string HIT_SFX = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"
public LinkedList INSTANCES
endglobals
private function GetHpDamage takes integer lvl returns real
return HP_DMG_BASE + HP_DMG_LEVEL * lvl
endfunction
struct DeathThreat extends array
implement Alloc
unit source
unit target
real angle
real dmg
real speed
boolean qcast
effect dummy
timer time
real duration
real interval
unit dummyVision
boolean reveal
Link node
private static method Callback takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local real x = BlzGetLocalSpecialEffectX(dummy)
local real y = BlzGetLocalSpecialEffectY(dummy)
local real xt = GetUnitX(target)
local real yt = GetUnitY(target)
local real d = Distance(x,y,xt,yt)
local real a
local boolean died
local Ability ab
if d > 150 then
set a = Angle(x,y,xt,yt)
set x = x + speed * Cos(a)
set y = y + speed * Sin(a)
call BlzSetSpecialEffectX(dummy,x)
call BlzSetSpecialEffectY(dummy,y)
call BlzSetSpecialEffectYaw(dummy,a)
set angle = a
else
if dummyVision == null then
set dummyVision = CreateUnit(GetOwningPlayer(source),'h005',xt,yt,0)
if GetUpgradeSkillLevel(source,UPGRADE_ID) != 0 then
set reveal = true
call Status.Add(STATUS_SPY,target,0,0)
endif
endif
if not qcast then
if interval == 0.00 then
call BlzPlaySpecialEffectWithTimeScale(dummy,ANIM_TYPE_ATTACK,0.8)
endif
set duration = duration - 0.03125
set interval = interval + 0.03125
endif
set a = GetUnitFacing(target) * bj_DEGTORAD
set angle = a
set x = xt - 75.00 * Cos(a)
set y = yt - 75.00 * Sin(a)
call BlzSetSpecialEffectX(dummy,x)
call BlzSetSpecialEffectY(dummy,y)
call BlzSetSpecialEffectYaw(dummy,a)
call BlzSetSpecialEffectHeight(dummy,GetLocZ(x,y))
call SetUnitX(dummyVision,xt)
call SetUnitY(dummyVision,yt)
if interval >= 1.0 then
set interval = 0
call DestroyEffect(AddSpecialEffectTarget(HIT_SFX,target,"chest"))
call CodeDamage.Damage(source,target,dmg,udg_DamageTypePhysical,"",0,0)
endif
endif
set died = not UnitAlive(target)
if duration <= 0 or died then
if GetUpgradeSkillLevel(source,UPGRADE_ID) != 0 and died then
set ab = Ability.GetUnitAbilityByID(SPELL_ID,source)
call ab.addFlatCooldown(-3.0)
endif
if reveal then
set reveal = false
call Status.Remove(STATUS_SPY,target)
endif
if died then
if GetHeroMasteryType(source) == 3 then
set ab = Ability.GetUnitAbilityByID(SPELL_ID,source)
call ab.addCooldownRemaining(-15.0)
endif
endif
call destroy()
endif
endmethod
public method destroy takes nothing returns nothing
call INSTANCES.remove(node)
call RemoveUnit(dummyVision)
call BlzSetSpecialEffectAlpha(dummy,0)
call DestroyEffect(dummy)
call ReleaseTimer(time)
call SetUnitData(target,"DT_Affected",0)
if INSTANCES.size == 0 then
call UnitRemoveAbility(source,EXTRA_ID)
endif
set source = null
set target = null
set dummyVision = null
set time = null
set dummy = null
call this.deallocate()
endmethod
public static method create takes unit u, unit t, integer lvl returns thistype
local thistype this = thistype.allocate()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
set source = u
set target = t
set qcast = false
set speed = DistanceBetweenUnits(u,t) / 32
set dmg = DMG_BASE * lvl + (BlzGetUnitMaxHP(target) * GetHpDamage(lvl))
set dummy = AddSpecialEffect(DUMMY_SFX,x,y)
call BlzSetSpecialEffectScale(dummy,0.6)
call BlzSetSpecialEffectAlpha(dummy,200)
call BlzSetSpecialEffectHeight(dummy,GetLocZ(x,y))
call BlzSetSpecialEffectColorByPlayer(dummy,Player(PLAYER_NEUTRAL_PASSIVE))
call SetUnitData(target,"DT_Affected",this)
set time = NewTimerEx(this)
set duration = DURATION
set node = INSTANCES.add(this)
call TimerStart(time,0.03125,true,function thistype.Callback)
return this
endmethod
endstruct
private function onCastExtra takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local DeathThreat dt = GetUnitData(t,"DT_Affected")
local real x
local real y
if dt != 0 then
set x = BlzGetLocalSpecialEffectX(dt.dummy)
set y = BlzGetLocalSpecialEffectY(dt.dummy)
call SetUnitX(u,x)
call SetUnitY(u,y)
call BlzSetUnitFacingEx(u,dt.angle)
call SetCameraPositionForPlayer(GetTriggerPlayer(),x,y)
call IssueTargetOrderById(u,ORDER_attack,t)
endif
set u = null
set t = null
endfunction
private function onCast takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(u,SPELL_ID)
local Team te = 2/GetUnitTeam(u)
local Hero h
local integer i
local integer j
if te == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
set h = GetPlayerHero(Player(i))
if IsPlayerSlotState(Player(i),PLAYER_SLOT_STATE_PLAYING) and UnitAlive(h.hero) then
call DeathThreat.create(u,h.hero,lvl)
endif
set i = i + 1
exitwhen i > j
endloop
call UnitAddAbility(u,EXTRA_ID)
call UnitMakeAbilityPermanent(u,true,EXTRA_ID)
if GetHeroMasteryType(u) == 2 then
call BlzSetUnitAbilityCooldown(u,EXTRA_ID,0,0)
endif
call DeathThreat.create(u,TEST_DUMMY,lvl)
call StartSound(gg_snd_DeathThreat)
set u = null
endfunction
private function SPELL_DATA takes nothing returns nothing
local AbilityData d = AbilityData.create()
set d.objectID = SPELL_ID
set d.hotkey = "R"
set d.activationType = ACTIVATION_TYPE_INSTANT
endfunction
private function SPELL_INIT takes nothing returns nothing
call SPELL_DATA()
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(EXTRA_ID, function onCastExtra)
set INSTANCES = LinkedList.create()
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function SPELL_INIT,TheReaper_HERO_ID)
call PreloadGen.Add(SPELL_ID,PRELOAD_SECOND)
call Preload(DUMMY_SFX)
endfunction
endscope
scope AIBanditChampion initializer init
struct AIBC extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local Ability a6 = AI.playerHero.Abilities.integer[6]
local boolean b = UnitHasBuff(AI.weakEnemy,MarkedForDeath.buff)
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MURDERER_ID) == 0
local real d
if AI.enemyHeroCount > 0 then
set d = DistanceBetweenUnits(u,AI.weakEnemy)
if not a4.isOnCooldown() and a4.level != 0 then
if d <= 700 + 100 * a4.level then
if IssueTargetOrderById(AI.playerHero.hero,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if IssueImmediateOrderById(u,ORDER_unwindwalk) then
set AI.busyTimes = 1
if AI.returnToBase then
set AI.riskAction = true
endif
set u = null
return
endif
elseif traitCD and not AI.retreating then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if d <= 1000 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if d <= 1000 and a1.isOnCooldown() and AI.weakEnemyHp <= 0.20 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if b and AI.retreating then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a6.isOnCooldown() and a6.level != 0 then
if UnitHasBuff(u,ShadowChase.buff) and not AI.danger and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if IssueTargetOrderById(u,ORDER_curse,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if not AI.danger and AI.weakEnemyHp <= 0.15 then
if IssueTargetOrderById(u,ORDER_curse,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.alliedHeroCount > 0 then
if not a6.isOnCooldown() and a6.level != 0 then
if AI.retreating or AI.returnToBase then
if DistanceBetweenUnits(u,AI.threatAlly) <= 600 then
if IssueTargetOrderById(u,ORDER_curse,AI.threatAlly) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.goldUnit != null then
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 400 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('BCA1')
call AI.abilityBuild.registerLearnSkill('BCA2')
call AI.abilityBuild.registerLearnSkill('BCA3')
call AI.abilityBuild.registerLearnSkill('BCA1')
call AI.abilityBuild.registerLearnSkill('BCA4')
call AI.abilityBuild.registerLearnSkill('A034') //perk
call AI.abilityBuild.registerLearnSkill('BCA3')
call AI.abilityBuild.registerLearnSkill('BCA1')
call AI.abilityBuild.registerLearnSkill('BCA2')
call AI.abilityBuild.registerLearnSkill('BCA4')
call AI.abilityBuild.registerLearnSkill('A03J') //perk
call AI.abilityBuild.registerLearnSkill('BCA1')
call AI.abilityBuild.registerLearnSkill('BCA3')
call AI.abilityBuild.registerLearnSkill('BCA2')
call AI.abilityBuild.registerLearnSkill('BCA4')
call AI.abilityBuild.registerLearnSkill('A03S') //perk
call AI.abilityBuild.registerLearnSkill('BCA3')
call AI.abilityBuild.registerLearnSkill('BCA2')
call AI.abilityBuild.registerLearnSkill('A0CH') //perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'amrc'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('fgdg') //dynamic boots 1
call AI.itemBuild.add('rlif') //viper dagger 1
call AI.itemBuild.add('azhr') //sanake best 1
call AI.itemBuild.add('fgdg') //dynamic boots 2
call AI.itemBuild.add('rlif') //viper dagger 2
call AI.itemBuild.add('engs') //defiled Helm 1
call AI.itemBuild.add('ckng') //battle insignia 1
call AI.itemBuild.add('azhr') //sanake best 2
call AI.itemBuild.add('fgdg') //dynamic boots 3
call AI.itemBuild.add('rlif') //viper dagger 3
call AI.itemBuild.add('ckng') //battle insignia 2
call AI.itemBuild.add('engs') //defiled Helm 2
call AI.itemBuild.add('wild') //ancient drum 1
call AI.itemBuild.add('azhr') //sanake best 3
call AI.itemBuild.add('wild') //ancient drum 1
call AI.itemBuild.add('wild') //ancient drum 2
call AI.itemBuild.add('engs') //defiled Helm 3
call AI.itemBuild.add('ckng') //battle insignia 3
set AI.itemBuild.enchantBuild.random1 = 'I00D'
set AI.itemBuild.enchantBuild.random2 = 'I03E'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I034','rlif')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MURDERER_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIBC.StartAI(HERO_AI,false)
call AIBC.createSkillBuild()
call AIBC.createUpgradeBuild()
call AIBC.createItemBuild()
call AIBC.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HBC1')
endfunction
endscope
scope AIElderSage initializer init
struct AIEN extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local Ability a5 = AI.playerHero.Abilities.integer[5]
local boolean b1 = AI.enemyUnitCount >= 2 or AI.enemyHeroCount >= 2
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_REPLENISH_ID) == 0
if AI.enemyHeroCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 700 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 700 and b1 and AI.weakEnemyHp <= 0.30 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if UnitHasBuff(AI.weakEnemy,NaturesTouchDebuff.buff) and AI.weakEnemyHp <= 0.35 then
if IssueImmediateOrderById(u,ORDER_tranquility) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a5.isOnCooldown() and a5.level != 0 then
if IssueImmediateOrderById(u,ORDER_thunderclap) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.alliedHeroCount > 0 then
if traitCD and AI.enemyHeroCount >= 1 and (AI.weakAlliedHp <= 0.20 or AI.percentLife <= 0.20) then
if IssueTargetOrderById(u,ORDER_antimagicshell,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if DistanceBetweenUnits(u,AI.weakAllied) <= 800 and AI.weakAlliedHp <= 0.70 and not UnitHasBuff(AI.weakAllied,NaturesTouch.buff) then
if IssueTargetOrderById(u,ORDER_rejuvination,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(u,AI.weakAllied) <= 800 and b1 and AI.weakAlliedHp <= 0.60 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if UnitHasBuff(AI.weakAllied,NaturesTouch.buff) and AI.weakAlliedHp <= 0.35 and AI.enemyHeroCount != 0 then
if IssueImmediateOrderById(u,ORDER_tranquility) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.enemyUnitCount >= 3 then
if GetRandomInt(1,100) <= 40 + 5 * AI.enemyUnitCount then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.percentLife <= 0.60 and not UnitHasBuff(u,NaturesTouch.buff) then
if IssueTargetOrderById(u,ORDER_rejuvination,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('ENA1')
call AI.abilityBuild.registerLearnSkill('ENA3')
call AI.abilityBuild.registerLearnSkill('ENA2')
call AI.abilityBuild.registerLearnSkill('ENA3')
call AI.abilityBuild.registerLearnSkill('ENA4')
call AI.abilityBuild.registerLearnSkill('A03B') //Perk
call AI.abilityBuild.registerLearnSkill('ENA1')
call AI.abilityBuild.registerLearnSkill('ENA3')
call AI.abilityBuild.registerLearnSkill('ENA2')
call AI.abilityBuild.registerLearnSkill('ENA4')
call AI.abilityBuild.registerLearnSkill('A0AW') //Perk
call AI.abilityBuild.registerLearnSkill('ENA3')
call AI.abilityBuild.registerLearnSkill('ENA1')
call AI.abilityBuild.registerLearnSkill('ENA2')
call AI.abilityBuild.registerLearnSkill('ENA4')
call AI.abilityBuild.registerLearnSkill('A03R') //Perk
call AI.abilityBuild.registerLearnSkill('ENA1')
call AI.abilityBuild.registerLearnSkill('ENA2')
call AI.abilityBuild.registerLearnSkill('A0AC') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('modt') //beer barrel 1
call AI.itemBuild.add('dust') //shappire bots 1
call AI.itemBuild.add('gmfr') //Emerald Shield 1
call AI.itemBuild.add('modt') //beer barrel 2
call AI.itemBuild.add('gmfr') //Emerald Shield 2
call AI.itemBuild.add('ofro') //renewal branch 1
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('modt') //beer barrel 3
call AI.itemBuild.add('dust') //shappire bots 2
call AI.itemBuild.add('gmfr') //Emerald Shield 3
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('ofro') //renewal branch 2
call AI.itemBuild.add('k3m1') //Angelic Robe 1
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('dust') //shappire bots 3
call AI.itemBuild.add('ofro') //renewal branch 3
call AI.itemBuild.add('k3m1') //Angelic Robe 2
call AI.itemBuild.add('k3m1') //Angelic Robe 3
set AI.itemBuild.enchantBuild.random1 = 'I04S'
set AI.itemBuild.enchantBuild.random2 = 'I00H'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I038','stel')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_REPLENISH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIEN.StartAI(HERO_AI,false)
call AIEN.createSkillBuild()
call AIEN.createUpgradeBuild()
call AIEN.createItemBuild()
call AIEN.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HEN1')
endfunction
endscope
scope AIDemonGuard initializer init
struct AIDG extends array
static boolean Ractive = false
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_HEAVEN_ID) == 0
local LinkedList l = GetUnitData(u,"DemonicHandIns")
local integer dh = l.size
local real x
local real y
local real a
local real d
if AI.enemyHeroCount > 0 then
set d = DistanceBetweenUnits(u,AI.weakEnemy)
if traitCD and ((AI.enemyHeroCount >= AI.alliedHeroCount + 1 and AI.percentLife <= 0.60) or AI.percentLife <= 0.20) then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if d <= 450 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if d <= 300 and (UnitHasBuff(AI.weakEnemy,DemonicHand.buff) or AI.weakEnemyHp <= 0.25 or AI.enemyHeroCount >= 2) then
if IssueImmediateOrderById(u,ORDER_immolation) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 and (dh >= 1 and UnitHasBuff(AI.weakEnemy,FlamingCuirassSlow.buff)) then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = GetUnitX(AI.weakEnemy) + 120 * Cos(a)
set y = GetUnitY(AI.weakEnemy) + 120 * Sin(a)
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if Ractive then
if dh == 0 then
if AI.closestEnemyDistance <= 300 then
if IssueImmediateOrderById(u,ORDER_thunderclap) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.enemyUnitCount >= 3 and DistanceBetweenUnits(u,AI.weakUnit) <= 450 then
if GetRandomInt(1,100) <= 40 + 5 * AI.enemyUnitCount then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.goldUnit != null then
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 200 then
if IssueImmediateOrderById(u,ORDER_immolation) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('DGA1')
call AI.abilityBuild.registerLearnSkill('DGA3')
call AI.abilityBuild.registerLearnSkill('DGA2')
call AI.abilityBuild.registerLearnSkill('DGA1')
call AI.abilityBuild.registerLearnSkill('DGA4')
call AI.abilityBuild.registerLearnSkill('A042')//PERK1
call AI.abilityBuild.registerLearnSkill('DGA3')
call AI.abilityBuild.registerLearnSkill('DGA2')
call AI.abilityBuild.registerLearnSkill('DGA1')
call AI.abilityBuild.registerLearnSkill('DGA4')
call AI.abilityBuild.registerLearnSkill('A03L')//PERK3
call AI.abilityBuild.registerLearnSkill('DGA3')
call AI.abilityBuild.registerLearnSkill('DGA2')
call AI.abilityBuild.registerLearnSkill('DGA1')
call AI.abilityBuild.registerLearnSkill('DGA4')
call AI.abilityBuild.registerLearnSkill('A03R')//PERK4
call AI.abilityBuild.registerLearnSkill('DGA3')
call AI.abilityBuild.registerLearnSkill('DGA2')
call AI.abilityBuild.registerLearnSkill('A0CJ')//PERK5
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'vddl'
set AI.itemBuild.startItemID2 = 'brag'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('gmfr') //emerald shield 1
call AI.itemBuild.add('kybl') //Arcanite Buckler 1
call AI.itemBuild.add('dust') //shappire bots 1
call AI.itemBuild.add('gmfr') //emerald shield 2
call AI.itemBuild.add('kybl') //Arcanite Buckler 2
call AI.itemBuild.add('pmna') //Pipe of Antonidas 1
call AI.itemBuild.add('prvt') //Symbol of Valour 1
call AI.itemBuild.add('ratc') //Skull Hammer 1
call AI.itemBuild.add('pmna') //Pipe of Antonidas 2
call AI.itemBuild.add('prvt') //Symbol of Valour 2
call AI.itemBuild.add('kybl') //Arcanite Buckler 3
call AI.itemBuild.add('gmfr') //emerald shield 3
call AI.itemBuild.add('ratc') //Skull Hammer 2
call AI.itemBuild.add('prvt') //Symbol of Valour 3
call AI.itemBuild.add('dust') //shappire bots 2
call AI.itemBuild.add('dust') //shappire bots 3
call AI.itemBuild.add('pmna') //Pipe of Antonidas 3
call AI.itemBuild.add('ratc') //Skull Hammer 3
set AI.itemBuild.enchantBuild.random1 = 'I04U'
set AI.itemBuild.enchantBuild.random2 = 'I032'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I038','stel')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I00Q','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_HEAVEN_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIDG.StartAI(HERO_AI,false)
call AIDG.createSkillBuild()
call AIDG.createUpgradeBuild()
call AIDG.createItemBuild()
call AIDG.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HDG1')
endfunction
endscope
scope AIDeathSting initializer init
struct AIDS extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean b = UnitHasBuff(u,Tunnels.buff)
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local real dw
local real x
local real y
local real a
if AI.enemyHeroCount > 0 then
set dw = DistanceBetweenUnits(u,AI.weakEnemy)
if b and not AI.returnToBase then
if dw <= 150 or DistanceBetweenUnits(u,AI.threatEnemy) <= 150 then
if IssueImmediateOrderById(u,ORDER_manashieldon) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if traitCD and not b then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 and not b then
if dw <= 200 or a4.isOnCooldown() then
if IssueImmediateOrderById(u,ORDER_berserk) then
//instant spell
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 and not b and not UnitHasBuff(AI.weakEnemy,CorrosiveVenom.buff) then
if dw <= 255 then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 and AI.percentLife >= 0.30 and not b then
if dw <= 650 + 100 * a3.level and dw >= 200 and not AI.danger then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = GetUnitX(AI.weakEnemy) + 150 * Cos(a)
set y = GetUnitY(AI.weakEnemy) + 150 * Sin(a)
if IssuePointOrderById(u,ORDER_blink,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if dw <= 800 and not AI.returnToBase and not b and (AI.weakEnemyHp <= 0.30 or AI.enemyHeroCount >= 2) then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null then
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 255 then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('DSA2')
call AI.abilityBuild.registerLearnSkill('DSA5')
call AI.abilityBuild.registerLearnSkill('DSA1')
call AI.abilityBuild.registerLearnSkill('DSA2')
call AI.abilityBuild.registerLearnSkill('DSA4')
call AI.abilityBuild.registerLearnSkill('A034')//PERK
call AI.abilityBuild.registerLearnSkill('DSA2')
call AI.abilityBuild.registerLearnSkill('DSA1')
call AI.abilityBuild.registerLearnSkill('DSA2')
call AI.abilityBuild.registerLearnSkill('DSA4')
call AI.abilityBuild.registerLearnSkill('A03M')//PERK
call AI.abilityBuild.registerLearnSkill('DSA1')
call AI.abilityBuild.registerLearnSkill('DSA5')
call AI.abilityBuild.registerLearnSkill('DSA1')
call AI.abilityBuild.registerLearnSkill('DSA4')
call AI.abilityBuild.registerLearnSkill('A03R')//PERK
call AI.abilityBuild.registerLearnSkill('DSA5')
call AI.abilityBuild.registerLearnSkill('DSA5')
call AI.abilityBuild.registerLearnSkill('A0AC')//PERK
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'amrc'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('stel') //Sun Daggers 1
call AI.itemBuild.add('azhr') //Snake Vest 1
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('stel') //Sun Daggers 2
call AI.itemBuild.add('prvt') //Symbol of Valour 1
call AI.itemBuild.add('sand') //Heretic's Ring 1
call AI.itemBuild.add('azhr') //Snake Vest 2
call AI.itemBuild.add('prvt') //Symbol of Valour 2
call AI.itemBuild.add('pnvu') //Spider silk broach 1
call AI.itemBuild.add('sand') //Heretic's Ring 2
call AI.itemBuild.add('stel') //Sun Daggers 3
call AI.itemBuild.add('pnvu') //Spider silk broach 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
call AI.itemBuild.add('azhr') //Snake Vest 3
call AI.itemBuild.add('prvt') //Symbol of Valour 3
call AI.itemBuild.add('pnvu') //Spider silk broach 3
call AI.itemBuild.add('sand') //Heretic's Ring 3
set AI.itemBuild.enchantBuild.random1 = 'I00F'
set AI.itemBuild.enchantBuild.random2 = 'I031'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I035','stel')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIDS.StartAI(HERO_AI,false)
call AIDS.createSkillBuild()
call AIDS.createUpgradeBuild()
call AIDS.createItemBuild()
call AIDS.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HDS1')
endfunction
endscope
scope AIDisruptionMagus initializer init
struct AIDM extends array
static integer Wcount = 0
static real Wx = 0
static real Wy = 0
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local Table tb = GetUnitData(u,"DNebula")
local real x
local real y
local real a
if AI.enemyHeroCount > 0 then
if traitCD then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.percentMana <= 0.50 or AI.enemyHeroCount >= 3 then
if IssueImmediateOrderById(u,ORDER_immolation) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 and AI.enemyHeroCount >= 2 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 1000 then
if IsUnitMoving(AI.weakEnemy) then
set a = GetUnitFacing(AI.weakEnemy) * bj_DEGTORAD
set x = GetUnitX(AI.weakEnemy) + 200 * Cos(a)
set y = GetUnitY(AI.weakEnemy) + 200 * Sin(a)
else
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
endif
if IssuePointOrderById(u,ORDER_rainoffire,x,y) then
set thistype.Wx = x
set thistype.Wy = y
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.60 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 800 then
if IssueTargetOrderById(u,ORDER_acidbomb,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if thistype.Wcount > 0 then
if IssuePointOrderById(u,ORDER_blizzard,thistype.Wx,thistype.Wy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.enemyHeroCount >= Team[2/AI.team].playerCount/2 and not AI.returnToBase then
if IssuePointOrderById(u,ORDER_blizzard,GetUnitX(AI.threatEnemy),GetUnitY(AI.threatEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if tb != 0 then
if thistype.Wcount == 0 then
if tb.real[4] == -10 then
if DistanceBetweenUnits(u,AI.threatEnemy) <= 800 then
if IssuePointOrderById(u,ORDER_areadetection,GetUnitX(AI.threatEnemy),GetUnitY(AI.threatEnemy)) then
set u = null
return
endif
elseif DistanceBetweenUnits(u,AI.weakEnemy) <= 800 then
if IssuePointOrderById(u,ORDER_areadetection,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set u = null
return
endif
endif
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 and AI.enemyUnitCount >= 3 then
if IssueTargetOrderById(u,ORDER_acidbomb,AI.weakUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.goldUnit != null then
if not a1.isOnCooldown() and a1.level != 0 then
if IssueTargetOrderById(u,ORDER_acidbomb,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('ADA1')
call AI.abilityBuild.registerLearnSkill('ADA2')
call AI.abilityBuild.registerLearnSkill('ADA3')
call AI.abilityBuild.registerLearnSkill('ADA1')
call AI.abilityBuild.registerLearnSkill('ADA4')
call AI.abilityBuild.registerLearnSkill('A032')//perk
call AI.abilityBuild.registerLearnSkill('ADA2')
call AI.abilityBuild.registerLearnSkill('ADA1')
call AI.abilityBuild.registerLearnSkill('ADA3')
call AI.abilityBuild.registerLearnSkill('ADA4')
call AI.abilityBuild.registerLearnSkill('A03N')//perk
call AI.abilityBuild.registerLearnSkill('ADA1')
call AI.abilityBuild.registerLearnSkill('ADA2')
call AI.abilityBuild.registerLearnSkill('ADA3')
call AI.abilityBuild.registerLearnSkill('ADA4')
call AI.abilityBuild.registerLearnSkill('A03R')//perk
call AI.abilityBuild.registerLearnSkill('ADA2')
call AI.abilityBuild.registerLearnSkill('ADA3')
call AI.abilityBuild.registerLearnSkill('A0AE')//perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'brag'
set AI.itemBuild.startItemR1 = 8
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('modt') //Beel barrel 1
call AI.itemBuild.add('gmfr') //Emerald brooch 1
call AI.itemBuild.add('dust') //Shappire bots 1
call AI.itemBuild.add('modt') //Beel barrel 2
call AI.itemBuild.add('gmfr') //Emerald brooch 2
call AI.itemBuild.add('rde3') //magic emblem 1
call AI.itemBuild.add('modt') //Beel barrel 3
call AI.itemBuild.add('cnhn') //valiant heart 1
call AI.itemBuild.add('rde3') //magic emblem 2
call AI.itemBuild.add('ward') //sky halberd 1
call AI.itemBuild.add('gmfr') //Emerald brooch 3
call AI.itemBuild.add('rde3') //magic emblem 3
call AI.itemBuild.add('ward') //sky halberd 2
call AI.itemBuild.add('cnhn') //valiant heart 2
call AI.itemBuild.add('cnhn') //valiant heart 3
call AI.itemBuild.add('ward') //sky halberd 3
call AI.itemBuild.add('dust') //Shappire bots 2
call AI.itemBuild.add('dust') //Shappire bots 3
set AI.itemBuild.enchantBuild.random1 = 'I04S'
set AI.itemBuild.enchantBuild.random2 = 'I00E'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I038','stel')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIDM.StartAI(HERO_AI,false)
call AIDM.createSkillBuild()
call AIDM.createUpgradeBuild()
call AIDM.createItemBuild()
call AIDM.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HAD1')
endfunction
endscope
scope AIScarletGuard initializer init
struct AISG extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local AscalonsSwordArt b = GetUnitBuff(u,AscalonsSwordArt.buff).buffAllocIndex
local boolean tb = UnitHasBuff(u,Berserk.buff)
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_BERSERK_ID) == 0
local real x
local real y
local real a
if AI.enemyHeroCount > 0 then
if b != 0 then
if b.table.integer[1] != 0 and DistanceBetweenUnits(u,AI.weakEnemy) <= 850 and AI.enemyHeroCount <= AI.alliedHeroCount + 1 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 and AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_curseoff) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 350 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
set x = AI.hx + 300 * Cos(a)
set y = AI.hy + 300 * Sin(a)
if IssuePointOrderById(u,ORDER_carrionswarm,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.weakEnemy) <= 420 and (AI.weakEnemyHp <= 0.40 or AI.enemyHeroCount == 1) then
if IssuePointOrderById(u,ORDER_carrionswarm,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if tb and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
set AI.riskAction = true
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 and AI.enemyUnitCount >= 3 then
if GetRandomInt(1,100) <= 40 + 3 * AI.enemyUnitCount then
if DistanceBetweenUnits(u,AI.weakUnit) <= 350 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 and AI.enemyUnitCount >= 5 then
if DistanceBetweenUnits(u,AI.weakUnit) <= 420 and AI.weakEnemyHp <= 0.40 then
if IssuePointOrderById(u,ORDER_carrionswarm,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD and not AI.returnToBase then
if AI.percentLife <= 0.50 and b != 0 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
else
if AI.enemyHeroCount > 0 and AI.weakEnemyHp <= 0.20 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null then
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 350 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('SGA2')
call AI.abilityBuild.registerLearnSkill('SGA1')
call AI.abilityBuild.registerLearnSkill('SGA3')
call AI.abilityBuild.registerLearnSkill('SGA1')
call AI.abilityBuild.registerLearnSkill('SGA4')
call AI.abilityBuild.registerLearnSkill('A033') //perk
call AI.abilityBuild.registerLearnSkill('SGA2')
call AI.abilityBuild.registerLearnSkill('SGA3')
call AI.abilityBuild.registerLearnSkill('SGA1')
call AI.abilityBuild.registerLearnSkill('SGA4')
call AI.abilityBuild.registerLearnSkill('A03K') //perk
call AI.abilityBuild.registerLearnSkill('SGA2')
call AI.abilityBuild.registerLearnSkill('SGA1')
call AI.abilityBuild.registerLearnSkill('SGA3')
call AI.abilityBuild.registerLearnSkill('SGA4')
call AI.abilityBuild.registerLearnSkill('A03U') //perk
call AI.abilityBuild.registerLearnSkill('SGA2')
call AI.abilityBuild.registerLearnSkill('SGA3')
call AI.abilityBuild.registerLearnSkill('A0CH') //perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'arsh'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 10
call AI.itemBuild.add('ledg') //Heros shield 1
call AI.itemBuild.add('kybl') //Arcanite Buckler 1
call AI.itemBuild.add('rwiz') //black mace 1
call AI.itemBuild.add('kybl') //Arcanite Buckler 2
call AI.itemBuild.add('rwiz') //black mace 2
call AI.itemBuild.add('ckng') //Battle Insignia 1
call AI.itemBuild.add('fgdg') //Dynamic boots 1
call AI.itemBuild.add('ckng') //Battle Insignia 2
call AI.itemBuild.add('fgdg') //Dynamic boots 2
call AI.itemBuild.add('bgst') //executioner 1
call AI.itemBuild.add('fgdg') //Dynamic boots 3
call AI.itemBuild.add('bgst') //executioner 2
call AI.itemBuild.add('rwiz') //black mace 3
call AI.itemBuild.add('ckng') //Battle Insignia 3
call AI.itemBuild.add('kybl') //Arcanite Buckler 3
call AI.itemBuild.add('ledg') //Heros shield 2
call AI.itemBuild.add('ledg') //Heros shield 3
call AI.itemBuild.add('bgst') //executioner 3
set AI.itemBuild.enchantBuild.random1 = 'I03D'
set AI.itemBuild.enchantBuild.random2 = 'I03E'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I034','rwiz')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_BERSERK_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AISG.StartAI(HERO_AI,false)
call AISG.createSkillBuild()
call AISG.createUpgradeBuild()
call AISG.createItemBuild()
call AISG.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HSG1')
endfunction
endscope
scope AIFelRider initializer init
struct AIFR extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local integer st = GetUnitData(u,"FelStacks")
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_AVATAR_ID) == 0
local boolean tb = Status.UnitHasStatus(STATUS_SPELL_IMMUNITY,u)
local real d
if AI.enemyHeroCount > 0 then
set d = DistanceBetweenUnits(u,AI.weakEnemy)
if not a4.isOnCooldown() and a4.level != 0 then
if st == 10 then
if IssueImmediateOrderById(u,ORDER_roar) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if d <= 300 and AI.weakEnemyHp <= 0.20 and st >= 5 then
if IssueImmediateOrderById(u,ORDER_roar) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.returnToBase and st >= 5 then
if IssueImmediateOrderById(u,ORDER_roar) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if d <= 230 then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.closestEnemyHero) <= 230 then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.closestEnemyHero) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
if not a1.isOnCooldown() and a1.level != 0 and (AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.30) then
if d <= 600 then
if IssueTargetOrderById(u,ORDER_chainlightning,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if traitCD then
if (AI.enemyHeroCount >= 3 and UnitHasBuff(u,FelOnslaught.buff)) or AI.percentLife <= 0.50 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if tb and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
set AI.riskAction = true
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 and AI.enemyUnitCount >= 3 or AI.goldUnit != null then
if GetRandomInt(1,100) <= 40 + 3 * AI.enemyUnitCount then
if DistanceBetweenUnits(u,AI.weakUnit) <= 600 then
if IssueTargetOrderById(u,ORDER_chainlightning,AI.weakUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('FRA1')
call AI.abilityBuild.registerLearnSkill('FRA3')
call AI.abilityBuild.registerLearnSkill('FRA2')
call AI.abilityBuild.registerLearnSkill('FRA1')
call AI.abilityBuild.registerLearnSkill('FRA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('FRA3')
call AI.abilityBuild.registerLearnSkill('FRA1')
call AI.abilityBuild.registerLearnSkill('FRA2')
call AI.abilityBuild.registerLearnSkill('FRA4')
call AI.abilityBuild.registerLearnSkill('A0AW') //Perk
call AI.abilityBuild.registerLearnSkill('FRA3')
call AI.abilityBuild.registerLearnSkill('FRA1')
call AI.abilityBuild.registerLearnSkill('FRA2')
call AI.abilityBuild.registerLearnSkill('FRA4')
call AI.abilityBuild.registerLearnSkill('A03R') //Perk
call AI.abilityBuild.registerLearnSkill('FRA3')
call AI.abilityBuild.registerLearnSkill('FRA2')
call AI.abilityBuild.registerLearnSkill('A0AE') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 8
call AI.itemBuild.add('fgdg') //Dynamic boots 1
call AI.itemBuild.add('stel') //Sun Daggers 1
call AI.itemBuild.add('gopr') //runic bracers 1
call AI.itemBuild.add('fgdg') //Dynamic boots 2
call AI.itemBuild.add('stel') //Sun Daggers 2
call AI.itemBuild.add('gopr') //runic bracers 2
call AI.itemBuild.add('prvt') //symbol of valour 1
call AI.itemBuild.add('belv') //Battle Insignia 1
call AI.itemBuild.add('prvt') //symbol of valour 2
call AI.itemBuild.add('belv') //Battle Insignia 2
call AI.itemBuild.add('pgma') //sky mirror 1
call AI.itemBuild.add('fgdg') //Dynamic boots 3
call AI.itemBuild.add('stel') //Sun Daggers 3
call AI.itemBuild.add('gopr') //runic bracers 3
call AI.itemBuild.add('prvt') //symbol of valour 3
call AI.itemBuild.add('belv') //Battle Insignia 3
call AI.itemBuild.add('pgma') //sky mirror 2
call AI.itemBuild.add('pgma') //sky mirror 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I04P'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I037','stel')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_AVATAR_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIFR.StartAI(HERO_AI,false)
call AIFR.createSkillBuild()
call AIFR.createUpgradeBuild()
call AIFR.createItemBuild()
call AIFR.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HFR1')
endfunction
endscope
scope AISoulHarvester initializer init
struct AISB extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local integer ss = GetUnitData(u,"SoulShards")
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_RECKLESS_ID) == 0
local real d
if AI.channelingOrder != 0 or AI.busyTimes > 0 then
if AI.channelingOrder == ORDER_firebolt then
if not a4.isOnCooldown() and a4.level != 0 then
if AI.percentLife <= 0.25 or (ss <= 5 and AI.enemyHeroCount >= 1) then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
set u = null
return
endif
if AI.enemyHeroCount > 0 then
set d = DistanceBetweenUnits(u,AI.weakEnemy)
if not a2.isOnCooldown() and a2.level != 0 then
if GetRandomInt(1,100) <= 50 then
if d <= 600 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if DistanceBetweenUnits(u,AI.threatEnemy) <= 600 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.threatEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if d <= 700 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.threatEnemy) <= 500 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.threatEnemy),GetUnitY(AI.threatEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 and ss >= 7 then
if d <= 700 and (AI.enemyHeroCount < AI.alliedHeroCount or AI.weakEnemyHp <= 0.50) and ss == 10 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakEnemy) then
set AI.channelingOrder = ORDER_firebolt
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.percentLife <= 0.15 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
if AI.alliedHeroCount > 0 then
if not a3.isOnCooldown() and a3.level != 0 and ss >= 7 then
if DistanceBetweenUnits(u,AI.weakAllied) <= 700 and AI.weakAlliedHp <= 0.50 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakAllied) then
set AI.channelingOrder = ORDER_firebolt
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakUnit) <= 700 and ss < 10 or AI.goldUnit != null then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(u,AI.weakUnit) <= 600 and AI.enemyUnitCount >= 5 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if AI.percentLife <= 0.10 or (AI.returnToBase and AI.percentLife <= 0.25) then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('SHA1')
call AI.abilityBuild.registerLearnSkill('SHA3')
call AI.abilityBuild.registerLearnSkill('SHA2')
call AI.abilityBuild.registerLearnSkill('SHA3')
call AI.abilityBuild.registerLearnSkill('SHA4')
call AI.abilityBuild.registerLearnSkill('A03B') //PERK
call AI.abilityBuild.registerLearnSkill('SHA2')
call AI.abilityBuild.registerLearnSkill('SHA3')
call AI.abilityBuild.registerLearnSkill('SHA1')
call AI.abilityBuild.registerLearnSkill('SHA4')
call AI.abilityBuild.registerLearnSkill('A03N') //PERK
call AI.abilityBuild.registerLearnSkill('SHA3')
call AI.abilityBuild.registerLearnSkill('SHA2')
call AI.abilityBuild.registerLearnSkill('SHA1')
call AI.abilityBuild.registerLearnSkill('SHA4')
call AI.abilityBuild.registerLearnSkill('A03T') //PERK
call AI.abilityBuild.registerLearnSkill('SHA2')
call AI.abilityBuild.registerLearnSkill('SHA1')
call AI.abilityBuild.registerLearnSkill('A0AE') //PERK
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'arsh'
set AI.itemBuild.startItemID2 = 'frhg'
set AI.itemBuild.startItemR1 = 11
set AI.itemBuild.startItemR2 = 8
call AI.itemBuild.add('rde2') //imbued relic 1
call AI.itemBuild.add('tmsc') //arcanist rod 1
call AI.itemBuild.add('ches') //blessed helmet 1
call AI.itemBuild.add('rde2') //imbued relic 2
call AI.itemBuild.add('tmsc') //arcanist rod 2
call AI.itemBuild.add('ches') //blessed helmet 2
call AI.itemBuild.add('ofro') //branch of renewal 1
call AI.itemBuild.add('pres') //voodoo cane 1
call AI.itemBuild.add('ofro') //branch of renewal 2
call AI.itemBuild.add('pres') //voodoo cane 2
call AI.itemBuild.add('bzbf') //dragonhide jacket 1
call AI.itemBuild.add('rde2') //imbued relic 3
call AI.itemBuild.add('tmsc') //arcanist rod 3
call AI.itemBuild.add('ches') //blessed helmet 3
call AI.itemBuild.add('ofro') //branch of renewal 3
call AI.itemBuild.add('bzbf') //dragonhide jacket 2
call AI.itemBuild.add('pres') //voodoo cane 3
call AI.itemBuild.add('bzbf') //dragonhide jacket 3
set AI.itemBuild.enchantBuild.random1 = 'I00F'
set AI.itemBuild.enchantBuild.random2 = 'I00G'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I038','stel')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_RECKLESS_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AISB.StartAI(HERO_AI,false)
call AISB.createSkillBuild()
call AISB.createUpgradeBuild()
call AISB.createItemBuild()
call AISB.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HSB1')
endfunction
endscope
scope AISacredChampion initializer init
struct AISC extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean b = UnitHasBuff(u,WingedBlessing.buff)
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_SAVIOR_ID) == 0
if AI.enemyHeroCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 then
if AI.enemyHeroCount >= 2 and AI.closestEnemyDistance <= 500 then
if IssueImmediateOrderById(u,ORDER_defend) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 225 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.threatEnemy) <= 225 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.threatEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 and AI.weakEnemyHp < AI.weakAlliedHp and AI.weakAlliedHp >= 0.70 then
if IssueTargetOrderById(u,ORDER_manaburn,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.percentLife <= 0.40 then
if IssueTargetOrderById(u,ORDER_manaburn,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.alliedHeroCount > 0 then
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(u,AI.weakAllied) <= 600 and AI.weakAlliedHp <= 0.80 then
if IssueTargetOrderById(u,ORDER_banish,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if DistanceBetweenUnits(u,AI.weakAllied) <= 600 and AI.weakAlliedHp <= 0.60 then
if IssueTargetOrderById(u,ORDER_manaburn,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.percentLife <= 0.80 then
if IssueTargetOrderById(u,ORDER_banish,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.percentLife <= 0.50 then
if IssueTargetOrderById(u,ORDER_manaburn,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a2.isOnCooldown() and a2.level != 0 and AI.enemyUnitCount >= 5 or AI.percentLife <= 0.50 then
if IssueTargetOrderById(u,ORDER_banish,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.goldUnit != null then
if DistanceBetweenUnits(u,AI.goldUnit) <= 160 then
if IssueTargetOrderById(u,ORDER_manaburn,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if traitCD then
if GetUnitMoveSpeed(u) <= 250 and AI.percentLife <= 0.50 then
if IssueTargetOrderById(u,ORDER_antimagicshell,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.alliedHeroCount > 0 and AI.enemyHeroCount >= 3 then
if AI.weakAlliedHp <= 0.30 then
if IssueTargetOrderById(u,ORDER_ancestralspirittarget,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('SCA1')
call AI.abilityBuild.registerLearnSkill('SCA3')
call AI.abilityBuild.registerLearnSkill('SCA2')
call AI.abilityBuild.registerLearnSkill('SCA3')
call AI.abilityBuild.registerLearnSkill('SCA4')
call AI.abilityBuild.registerLearnSkill('A042') //perk
call AI.abilityBuild.registerLearnSkill('SCA1')
call AI.abilityBuild.registerLearnSkill('SCA3')
call AI.abilityBuild.registerLearnSkill('SCA2')
call AI.abilityBuild.registerLearnSkill('SCA4')
call AI.abilityBuild.registerLearnSkill('A03L') //perk
call AI.abilityBuild.registerLearnSkill('SCA2')
call AI.abilityBuild.registerLearnSkill('SCA3')
call AI.abilityBuild.registerLearnSkill('SCA1')
call AI.abilityBuild.registerLearnSkill('SCA4')
call AI.abilityBuild.registerLearnSkill('A03X') //perk
call AI.abilityBuild.registerLearnSkill('SCA2')
call AI.abilityBuild.registerLearnSkill('SCA1')
call AI.abilityBuild.registerLearnSkill('A03O') //perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 11
call AI.itemBuild.add('tmsc') //arcanist rood 1
call AI.itemBuild.add('ches') //blessed helmet 1
call AI.itemBuild.add('dust') //Shappire Boots 1
call AI.itemBuild.add('tmsc') //arcanist rood 2
call AI.itemBuild.add('rde2') //imbued relic 1
call AI.itemBuild.add('ches') //blessed helmet 2
call AI.itemBuild.add('bzbe') //Blessed steel 1
call AI.itemBuild.add('rde2') //imbued relic 2
call AI.itemBuild.add('bzbe') //Blessed steel 2
call AI.itemBuild.add('tmsc') //arcanist rood 3
call AI.itemBuild.add('ofro') //dragonhide jacket 1
call AI.itemBuild.add('ches') //blessed helmet 3
call AI.itemBuild.add('rde2') //imbued relic 3
call AI.itemBuild.add('bzbe') //Blessed steel 3
call AI.itemBuild.add('ofro') //dragonhide jacket 2
call AI.itemBuild.add('ofro') //dragonhide jacket 3
call AI.itemBuild.add('dust') //Shappire Boots 2
call AI.itemBuild.add('dust') //Shappire Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I04S'
set AI.itemBuild.enchantBuild.random2 = 'I032'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I038','stel')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I00I','ches')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_SAVIOR_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AISC.StartAI(HERO_AI,false)
call AISC.createSkillBuild()
call AISC.createUpgradeBuild()
call AISC.createItemBuild()
call AISC.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HSC1')
endfunction
endscope
scope AIShadowSlayer initializer init
struct AISS extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local HatefulGlaive b
local real a
local real x
local real y
if AI.enemyHeroCount > 0 then
if traitCD and not UnitHasBuff(u,Dash.buff) then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 and not UnitHasBuff(u,SilentEdge.buff) then
if AI.closestEnemyDistance <= 250 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 700 and AI.weakEnemyHp <= 0.20 or AI.enemyHeroCount == 1 or AI.alliedHeroCount >= 1 then
if IssueTargetOrderById(u,ORDER_manaburn,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 500 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.threatEnemy) <= 500 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.threatEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set b = GetUnitBuff(AI.weakEnemy,HatefulGlaive.buff).buffAllocIndex
if b != 0 then
if not b.dashed and not AI.returnToBase then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 1000 and not AI.danger and BlzGetUnitAbilityCooldownRemaining(u,'A06J') == 0 then
if IssueTargetOrderById(u,ORDER_fingerofdeath,AI.weakEnemy) then
set AI.channelingOrder = ORDER_fingerofdeath
set u = null
return
endif
endif
endif
else
if GetHeroMasteryType(u) == 2 then
if not AI.returnToBase then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 1000 and not AI.danger and BlzGetUnitAbilityCooldownRemaining(u,'A06J') == 0 then
if IssueTargetOrderById(u,ORDER_fingerofdeath,AI.weakEnemy) then
set AI.channelingOrder = ORDER_fingerofdeath
set u = null
return
endif
endif
endif
endif
endif
endif
if AI.returnToBase or AI.retreating then
if not a1.isOnCooldown() and a1.level != 0 and not UnitHasBuff(u,SilentEdge.buff) then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
if AI.goldUnit != null then
if not a3.isOnCooldown() and a3.level != 0 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 300 then
if IssueTargetOrderById(u,ORDER_manaburn,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if GetRandomInt(1,100) <= 15 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('SAA1')
call AI.abilityBuild.registerLearnSkill('SAA3')
call AI.abilityBuild.registerLearnSkill('SAA2')
call AI.abilityBuild.registerLearnSkill('SAA1')
call AI.abilityBuild.registerLearnSkill('SAA4')
call AI.abilityBuild.registerLearnSkill('A034') //Perk
call AI.abilityBuild.registerLearnSkill('SAA2')
call AI.abilityBuild.registerLearnSkill('SAA1')
call AI.abilityBuild.registerLearnSkill('SAA3')
call AI.abilityBuild.registerLearnSkill('SAA4')
call AI.abilityBuild.registerLearnSkill('A03N') //Perk
call AI.abilityBuild.registerLearnSkill('SAA2')
call AI.abilityBuild.registerLearnSkill('SAA1')
call AI.abilityBuild.registerLearnSkill('SAA3')
call AI.abilityBuild.registerLearnSkill('SAA4')
call AI.abilityBuild.registerLearnSkill('A03U') //Perk
call AI.abilityBuild.registerLearnSkill('SAA2')
call AI.abilityBuild.registerLearnSkill('SAA3')
call AI.abilityBuild.registerLearnSkill('A0AC') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'will'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('stel') //sun daggers 1
call AI.itemBuild.add('fgdg') //dynamic boots 1
call AI.itemBuild.add('engs') //defiled helm 1
call AI.itemBuild.add('stel') //sun daggers 2
call AI.itemBuild.add('fgdg') //dynamic boots 2
call AI.itemBuild.add('rwiz') //Black Mace 1
call AI.itemBuild.add('pnvu') //spider slik broach 1
call AI.itemBuild.add('engs') //defiled helm 2
call AI.itemBuild.add('pnvu') //spider slik broach 2
call AI.itemBuild.add('stel') //sun daggers 3
call AI.itemBuild.add('rwiz') //Black Mace 2
call AI.itemBuild.add('pomn') //troll savage mask 1
call AI.itemBuild.add('fgdg') //dynamic boots 3
call AI.itemBuild.add('pomn') //troll savage mask 2
call AI.itemBuild.add('pnvu') //spider slik broach 3
call AI.itemBuild.add('engs') //defiled helm 3
call AI.itemBuild.add('pomn') //troll savage mask 3
call AI.itemBuild.add('rwiz') //Black Mace 3
set AI.itemBuild.enchantBuild.random1 = 'I00K'
set AI.itemBuild.enchantBuild.random2 = 'I031'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I035','stel')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AISS.StartAI(HERO_AI,false)
call AISS.createSkillBuild()
call AISS.createUpgradeBuild()
call AISS.createItemBuild()
call AISS.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HSA1')
endfunction
endscope
scope AITempestDruid initializer init
struct AITD extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local Ability a5 = AI.playerHero.Abilities.integer[5]
local boolean b = UnitHasBuff(u,WildFlight.buff)
local LinkedList wc = GetUnitData(u,"WC_Inst")
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MURDERER_ID) == 0
local real a
local real x
local real y
local real d
if AI.enemyHeroCount > 0 then
set d = DistanceBetweenUnits(u,AI.weakEnemy)
if not a4.isOnCooldown() and a4.level != 0 then
if wc.size == AI.enemyHeroCount/2 then
if d <= 1680 and GetUnitAbilityLevel(AI.weakEnemy,'B00P') == 0 then
if IssuePointOrderById(u,ORDER_rainoffire,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.threatEnemy) <= 1680 and GetUnitAbilityLevel(AI.threatEnemy,'B00P') == 0 then
if IssuePointOrderById(u,ORDER_rainoffire,GetUnitX(AI.threatEnemy),GetUnitY(AI.threatEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.closestEnemyDistance <= 1680 and GetUnitAbilityLevel(AI.closestEnemyHero,'B00P') == 0 then
if IssuePointOrderById(u,ORDER_rainoffire,GetUnitX(AI.closestEnemyHero),GetUnitY(AI.closestEnemyHero)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if d <= 1100 then
if IssuePointOrderById(u,ORDER_clusterrockets,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.15 then
if IssueImmediateOrderById(u,ORDER_metamorphosis) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if UnitHasBuff(u,WildFlight.buff) then
if AI.weakEnemyHp <= 0.30 or AI.alliedHeroCount > AI.enemyHeroCount and not AI.danger then
if d <= 500 + 100 * a3.level then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
if IsUnitMoving(AI.weakEnemy) then
set a = GetUnitFacing(AI.weakEnemy) * bj_DEGTORAD
set x = x + 100 * Cos(a)
set y = y + 100 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set AI.busyTimes = 2
set u = null
return
endif
endif
endif
endif
if (AI.percentLife <= 0.25 and AI.returnToBase) or (AI.percentLife <= 0.60 and AI.danger) then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
set x = AI.hx + 700 * Cos(a)
set y = AI.hy + 700 * Sin(a)
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set AI.busyTimes = 2
set u = null
return
endif
endif
endif
if traitCD then
if AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 and AI.enemyUnitCount >= 4 or AI.goldUnit != null then
if DistanceBetweenUnits(u,AI.weakUnit) <= 1100 then
if IssuePointOrderById(u,ORDER_clusterrockets,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('TDA1')
call AI.abilityBuild.registerLearnSkill('TDA3')
call AI.abilityBuild.registerLearnSkill('TDA2')
call AI.abilityBuild.registerLearnSkill('TDA1')
call AI.abilityBuild.registerLearnSkill('TDA4')
call AI.abilityBuild.registerLearnSkill('A042') //Perk
call AI.abilityBuild.registerLearnSkill('TDA3')
call AI.abilityBuild.registerLearnSkill('TDA2')
call AI.abilityBuild.registerLearnSkill('TDA1')
call AI.abilityBuild.registerLearnSkill('TDA4')
call AI.abilityBuild.registerLearnSkill('A03M') //Perk
call AI.abilityBuild.registerLearnSkill('TDA2')
call AI.abilityBuild.registerLearnSkill('TDA3')
call AI.abilityBuild.registerLearnSkill('TDA1')
call AI.abilityBuild.registerLearnSkill('TDA4')
call AI.abilityBuild.registerLearnSkill('A03R') //Perk
call AI.abilityBuild.registerLearnSkill('TDA2')
call AI.abilityBuild.registerLearnSkill('TDA3')
call AI.abilityBuild.registerLearnSkill('A0AD') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'brag'
set AI.itemBuild.startItemID2 = 'frhg'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('fgdg') //dynamic boots 1
call AI.itemBuild.add('gopr') //runic bracers 1
call AI.itemBuild.add('sbch') //enginner rifle 1
call AI.itemBuild.add('gopr') //runic bracers 2
call AI.itemBuild.add('fgdg') //dynamic boots 2
call AI.itemBuild.add('rlif') //Viper Dagger 1
call AI.itemBuild.add('pres') //voodo cane 1
call AI.itemBuild.add('rlif') //Viper Dagger 2
call AI.itemBuild.add('prvt') //symbol of valour 1
call AI.itemBuild.add('pres') //voodo cane 2
call AI.itemBuild.add('gopr') //runic bracers 3
call AI.itemBuild.add('fgdg') //dynamic boots 3
call AI.itemBuild.add('rlif') //Viper Dagger 3
call AI.itemBuild.add('sbch') //enginner rifle 2
call AI.itemBuild.add('sbch') //enginner rifle 3
call AI.itemBuild.add('pres') //voodo cane 3
call AI.itemBuild.add('prvt') //symbol of valour 2
call AI.itemBuild.add('prvt') //symbol of valour 3
set AI.itemBuild.enchantBuild.random1 = 'I03E'
set AI.itemBuild.enchantBuild.random2 = 'I04Q'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I038','stel')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MURDERER_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AITD.StartAI(HERO_AI,false)
call AITD.createSkillBuild()
call AITD.createUpgradeBuild()
call AITD.createItemBuild()
call AITD.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HTD1')
endfunction
endscope
scope AIBoneCrusher initializer init
struct AIBR extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_BERSERK_ID) == 0
local boolean as = UnitHasBuff(u,UncontrolledAngerAttack.buff)
local boolean tb = UnitHasBuff(u,Berserk.buff)
if AI.enemyHeroCount > 0 then
if not a3.isOnCooldown() and a3.level != 0 then
if as then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 270 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.threatEnemy) <= 270 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.closestEnemyDistance <= 600 then
if IssueImmediateOrderById(u,ORDER_cannibalize) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.returnToBase and not AI.inCombat then
if IssueImmediateOrderById(u,ORDER_cannibalize) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.percentLife <= 0.75 or AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_tranquility) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.alliedHeroCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 then
if AI.alliedHeroCount >= 2 and AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_tranquility) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 and AI.enemyUnitCount >= 3 or AI.goldUnit != null then
if DistanceBetweenUnits(u,AI.weakUnit) <= 270 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if UnitHasBuff(u,InnerWrath.buff) and AI.percentLife <= 0.40 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
if AI.percentLife <= 0.30 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
if as or tb then
if AI.closestEnemyHero != null and AI.closestEnemyDistance <= 120 then
set AI.riskAction = true
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('BRA1')
call AI.abilityBuild.registerLearnSkill('BRA2')
call AI.abilityBuild.registerLearnSkill('BRA3')
call AI.abilityBuild.registerLearnSkill('BRA1')
call AI.abilityBuild.registerLearnSkill('BRA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('BRA3')
call AI.abilityBuild.registerLearnSkill('BRA1')
call AI.abilityBuild.registerLearnSkill('BRA2')
call AI.abilityBuild.registerLearnSkill('BRA4')
call AI.abilityBuild.registerLearnSkill('A03K') //Perk
call AI.abilityBuild.registerLearnSkill('BRA1')
call AI.abilityBuild.registerLearnSkill('BRA3')
call AI.abilityBuild.registerLearnSkill('BRA2')
call AI.abilityBuild.registerLearnSkill('BRA4')
call AI.abilityBuild.registerLearnSkill('A03S') //Perk
call AI.abilityBuild.registerLearnSkill('BRA3')
call AI.abilityBuild.registerLearnSkill('BRA2')
call AI.abilityBuild.registerLearnSkill('A0AG') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'amrc'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('fgdg') //dynamic boots 1
call AI.itemBuild.add('rwiz') //black mace 1
call AI.itemBuild.add('kybl') //Arcanite Buckler 1
call AI.itemBuild.add('rwiz') //black mace 2
call AI.itemBuild.add('kybl') //Arcanite Buckler 2
call AI.itemBuild.add('bgst') //executioner 1
call AI.itemBuild.add('ckng') //battle insignia 1
call AI.itemBuild.add('bgst') //executioner 2
call AI.itemBuild.add('ckng') //battle insignia 2
call AI.itemBuild.add('prvt') //symbol of valour 1
call AI.itemBuild.add('fgdg') //dynamic boots 2
call AI.itemBuild.add('rwiz') //black mace 3
call AI.itemBuild.add('kybl') //Arcanite Buckler 3
call AI.itemBuild.add('bgst') //executioner 3
call AI.itemBuild.add('prvt') //symbol of valour 2
call AI.itemBuild.add('prvt') //symbol of valour 3
call AI.itemBuild.add('fgdg') //dynamic boots 3
call AI.itemBuild.add('ckng') //battle insignia 3
set AI.itemBuild.enchantBuild.random1 = 'I00H'
set AI.itemBuild.enchantBuild.random2 = 'I00D'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I039','rwiz')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_BERSERK_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIBR.StartAI(HERO_AI,false)
call AIBR.createSkillBuild()
call AIBR.createUpgradeBuild()
call AIBR.createItemBuild()
call AIBR.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HJK1')
endfunction
endscope
scope AIGnollWarden initializer init
struct AIGW extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local Buff b = 0
local boolean r = UnitHasBuff(u,ThunderAwaken.buff)
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_AVATAR_ID) == 0
local boolean tb = Status.UnitHasStatus(STATUS_SPELL_IMMUNITY,u)
local Buff b2
if r then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if tb or r then
set AI.riskAction = true
endif
else
if tb and r and AI.percentLife >= 0.50 then
set AI.riskAction = true
endif
endif
endif
if AI.enemyHeroCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 then
if AI.enemyHeroCount >= 3 then
if IssueImmediateOrderById(u,ORDER_tranquility) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if b != 0 then
set b2 = b.int
if GetUnitLifePercent(b2.target) <= 20 and b2.elapsedTime <= 2.0 then
if IssueImmediateOrderById(u,ORDER_tranquility) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if (AI.enemyHeroCount >= 2 or AI.percentLife <= 0.30) and AI.closestEnemyDistance <= 600 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 900 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if traitCD then
if (AI.enemyHeroCount >= 2 and UnitHasBuff(u,ThunderAwaken.buff)) or AI.percentLife <= 0.50 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null then
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 300 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('GWA1')
call AI.abilityBuild.registerLearnSkill('GWA3')
call AI.abilityBuild.registerLearnSkill('GWA2')
call AI.abilityBuild.registerLearnSkill('GWA3')
call AI.abilityBuild.registerLearnSkill('GWA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('GWA1')
call AI.abilityBuild.registerLearnSkill('GWA3')
call AI.abilityBuild.registerLearnSkill('GWA1')
call AI.abilityBuild.registerLearnSkill('GWA4')
call AI.abilityBuild.registerLearnSkill('A03N') //Perk
call AI.abilityBuild.registerLearnSkill('GWA3')
call AI.abilityBuild.registerLearnSkill('GWA1')
call AI.abilityBuild.registerLearnSkill('GWA2')
call AI.abilityBuild.registerLearnSkill('GWA4')
call AI.abilityBuild.registerLearnSkill('A03U') //Perk
call AI.abilityBuild.registerLearnSkill('GWA2')
call AI.abilityBuild.registerLearnSkill('GWA2')
call AI.abilityBuild.registerLearnSkill('A0CH') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('fgdg') //dynamic boots 1
call AI.itemBuild.add('gopr') //runic bracers 1
call AI.itemBuild.add('stel') //sun daggers 1
call AI.itemBuild.add('fgdg') //dynamic boots 2
call AI.itemBuild.add('gopr') //runic bracers 2
call AI.itemBuild.add('rde4') //crows feather 1
call AI.itemBuild.add('sbch') //enginner rifles 1
call AI.itemBuild.add('stel') //sun daggers 2
call AI.itemBuild.add('rde4') //crows feather 2
call AI.itemBuild.add('sbch') //enginner rifles 2
call AI.itemBuild.add('engs') //defiled helm 1
call AI.itemBuild.add('fgdg') //dynamic boots 3
call AI.itemBuild.add('gopr') //runic bracers 3
call AI.itemBuild.add('engs') //defiled helm 2
call AI.itemBuild.add('stel') //sun daggers 3
call AI.itemBuild.add('rde4') //crows feather 3
call AI.itemBuild.add('sbch') //enginner rifles 3
call AI.itemBuild.add('engs') //defiled helm 3
set AI.itemBuild.enchantBuild.random1 = 'I04P'
set AI.itemBuild.enchantBuild.random2 = 'I03D'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I038','stel')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_AVATAR_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIGW.StartAI(HERO_AI,false)
call AIGW.createSkillBuild()
call AIGW.createUpgradeBuild()
call AIGW.createItemBuild()
call AIGW.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HGW1')
endfunction
endscope
scope AIDamnQueen initializer init
struct AIDQ extends array
static Missile a2missile
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local Ability a6 = AI.playerHero.Abilities.integer[6]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_RECKLESS_ID) == 0
local LinkedList list
local Buff vh
local real d
if not a6.isOnCooldown() and a6.level != 0 then
set list = GetUnitData(u,"VH_List")
set vh = list.head.data
if list.size >= 2 and vh.elapsedTime >= 5.0 and AI.percentLife <= 0.30 and AI.enemyHeroCount != 0 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyHeroCount > 0 then
set d = DistanceBetweenUnits(u,AI.weakEnemy)
if not a1.isOnCooldown() and a1.level != 0 then
if AI.enemyHeroCount >= 2 and d <= 400 then
if IssuePointOrderById(u,ORDER_carrionswarm,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.percentLife <= 0.80 and d <= 600 then
if IssuePointOrderById(u,ORDER_carrionswarm,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if d <= 700 and AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.50 or a1.isOnCooldown() then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if UnitHasBuff(AI.weakEnemy,VampiricHorde.buff) then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if UnitHasBuff(AI.weakEnemy,VampiricHorde.buff) and not UnitHasBuff(AI.weakEnemy,ChainsOfFatality.buff) and d <= 600 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if UnitHasBuff(AI.threatEnemy,VampiricHorde.buff) and not UnitHasBuff(AI.threatEnemy,ChainsOfFatality.buff) and DistanceBetweenUnits(u,AI.threatEnemy) <= 600 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.threatEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.40 and d <= 600 and not UnitHasBuff(AI.weakEnemy,ChainsOfFatality.buff) then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if GetUnitAbilityLevel(u,'A0AT') != 0 then
if not AI.danger then
if Distance(a2missile.x,a2missile.y,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) <= 200 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if (AI.enemyHeroCount >= 2 or AI.percentLife <= 0.30) and (DistanceBetweenUnits(u,AI.threatEnemy) <= 300 or d <= 300) then
if IssueImmediateOrderById(u,ORDER_howlofterror) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyUnitCount >= 3 and DistanceBetweenUnits(u,AI.weakUnit) <= 700 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if AI.percentLife <= 0.10 or AI.returnToBase then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
if AI.goldUnit != null then
if not a3.isOnCooldown() and a3.level != 0 then
if not UnitHasBuff(AI.goldUnit,ChainsOfFatality.buff) and DistanceBetweenUnits(u,AI.goldUnit) <= 500 and a3.currentCharges > 2 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('DQA1')
call AI.abilityBuild.registerLearnSkill('DQA3')
call AI.abilityBuild.registerLearnSkill('DQA2')
call AI.abilityBuild.registerLearnSkill('DQA3')
call AI.abilityBuild.registerLearnSkill('DQA4')
call AI.abilityBuild.registerLearnSkill('A032') //Perk
call AI.abilityBuild.registerLearnSkill('DQA1')
call AI.abilityBuild.registerLearnSkill('DQA3')
call AI.abilityBuild.registerLearnSkill('DQA2')
call AI.abilityBuild.registerLearnSkill('DQA4')
call AI.abilityBuild.registerLearnSkill('A0AW') //Perk
call AI.abilityBuild.registerLearnSkill('DQA3')
call AI.abilityBuild.registerLearnSkill('DQA1')
call AI.abilityBuild.registerLearnSkill('DQA2')
call AI.abilityBuild.registerLearnSkill('DQA4')
call AI.abilityBuild.registerLearnSkill('A03X') //Perk
call AI.abilityBuild.registerLearnSkill('DQA1')
call AI.abilityBuild.registerLearnSkill('DQA2')
call AI.abilityBuild.registerLearnSkill('A0AG') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'brag'
set AI.itemBuild.startItemID2 = 'will'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('gmfr') //emerald brooch 1
call AI.itemBuild.add('rag1') //arcane wand 1
call AI.itemBuild.add('dust') //shappire boots 1
call AI.itemBuild.add('gmfr') //emerald brooch 2
call AI.itemBuild.add('rag1') //arcane wand 2
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('pres') //voodoo cane 1
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('pres') //voodoo cane 2
call AI.itemBuild.add('prvt') //symbol of valour 1
call AI.itemBuild.add('gmfr') //emerald brooch 3
call AI.itemBuild.add('rag1') //arcane wand 3
call AI.itemBuild.add('prvt') //symbol of valour 2
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('pres') //voodoo cane 3
call AI.itemBuild.add('prvt') //symbol of valour 3
call AI.itemBuild.add('dust') //shappire boots 2
call AI.itemBuild.add('dust') //shappire boots 3
set AI.itemBuild.enchantBuild.random1 = 'I00K'
set AI.itemBuild.enchantBuild.random2 = 'I04S'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I03A','rwiz')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_RECKLESS_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIDQ.StartAI(HERO_AI,false)
call AIDQ.createSkillBuild()
call AIDQ.createUpgradeBuild()
call AIDQ.createItemBuild()
call AIDQ.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HDQ1')
endfunction
endscope
scope AILizardArcher initializer init
struct AILA extends array
static unit pet = null
static integer petBusy = 0
static integer petOrder = 0
private static method petLoop takes boolean b3, boolean b4 returns nothing
local unit u = GetUnitByIndex(GetUnitData(pet,"Alcira"))
local Ability a1 = Ability.GetUnitAbilityByID('LYA1',pet)
local Ability a2 = Ability.GetUnitAbilityByID('LYA2',pet)
local Ability a4 = Ability.GetUnitAbilityByID('LYA3',pet)
local Ability a5 = Ability.GetUnitAbilityByID('A06O',pet)
if not a5.isOnCooldown() and a5.level != 0 then
if DistanceBetweenUnits(pet,u) >= 1000 and petBusy == 0 then
if IssueImmediateOrderById(pet,ORDER_mount) then
set petBusy = 1
set u = null
return
endif
endif
endif
if petBusy == 0 and petOrder == 0 then
if AI.enemyHeroCount > 0 then
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(pet,AI.weakEnemy) <= 700 and not AI.retreating and not AI.danger then
if IssuePointOrderById(pet,ORDER_rainoffire,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set petOrder = ORDER_rainoffire
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(pet,AI.weakEnemy) <= 250 then
if IssueTargetOrderById(pet,ORDER_devour,AI.weakEnemy) then
set petBusy = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(pet,AI.threatEnemy) <= 250 then
if IssueTargetOrderById(pet,ORDER_devour,AI.threatEnemy) then
set petBusy = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 and b4 then
if DistanceBetweenUnits(pet,AI.threatEnemy) <= 450 then
if IssueImmediateOrderById(pet,ORDER_roar) then
set petBusy = 1
set u = null
return
endif
endif
endif
endif
else
if petBusy != 0 then
set petBusy = petBusy - 1
endif
if petOrder != 0 then
if GetUnitCurrentOrder(pet) != petOrder then
set petOrder = 0
endif
endif
endif
set u = null
endmethod
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean b = UnitHasBuff(u,CrocodileFangs.buff)
local boolean tb = UnitHasBuff(u,TitanWall.buff)
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_TITAN_ID) == 0
if UnitAlive(pet) then
call petLoop(a3.level != 0, b)
endif
if tb and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
set AI.riskAction = true
endif
if not a2.isOnCooldown() and a2.level != 0 then
if GetUnitState(pet,UNIT_STATE_LIFE) <= 200 then
if IssueImmediateOrderById(u,ORDER_summongrizzly) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.enemyHeroCount > 0 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
if AI.enemyHeroCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 then
if AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_tranquility) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 800 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if traitCD then
if AI.enemyHeroCount >= 3 or AI.percentLife <= 0.30 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null then
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 400 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('LMA2')
call AI.abilityBuild.registerLearnSkill('LMA1')
call AI.abilityBuild.registerLearnSkill('LMA3')
call AI.abilityBuild.registerLearnSkill('LMA1')
call AI.abilityBuild.registerLearnSkill('LMA4')
call AI.abilityBuild.registerLearnSkill('A042') //Perk
call AI.abilityBuild.registerLearnSkill('LMA2')
call AI.abilityBuild.registerLearnSkill('LMA1')
call AI.abilityBuild.registerLearnSkill('LMA2')
call AI.abilityBuild.registerLearnSkill('LMA4')
call AI.abilityBuild.registerLearnSkill('A03N') //Perk
call AI.abilityBuild.registerLearnSkill('LMA3')
call AI.abilityBuild.registerLearnSkill('LMA1')
call AI.abilityBuild.registerLearnSkill('LMA2')
call AI.abilityBuild.registerLearnSkill('LMA4')
call AI.abilityBuild.registerLearnSkill('A03X') //Perk
call AI.abilityBuild.registerLearnSkill('LMA3')
call AI.abilityBuild.registerLearnSkill('LMA3')
call AI.abilityBuild.registerLearnSkill('A0AE') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'stwa'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 8
call AI.itemBuild.add('dust') //shappire boots 1
call AI.itemBuild.add('gmfr') //emerald brooch 1
call AI.itemBuild.add('gopr') //runic bracers 1
call AI.itemBuild.add('dust') //shappire boots 2
call AI.itemBuild.add('gmfr') //emerald brooch 2
call AI.itemBuild.add('gopr') //runic bracers 2
call AI.itemBuild.add('rde3') //magic emblem 1
call AI.itemBuild.add('belv') //sinester pike 1
call AI.itemBuild.add('rde3') //magic emblem 2
call AI.itemBuild.add('belv') //sinester pike 2
call AI.itemBuild.add('ward') //sky halberd 1
call AI.itemBuild.add('gmfr') //emerald brooch 3
call AI.itemBuild.add('gopr') //runic bracers 3
call AI.itemBuild.add('ward') //sky halberd 2
call AI.itemBuild.add('ward') //sky halberd 3
call AI.itemBuild.add('rde3') //magic emblem 3
call AI.itemBuild.add('belv') //sinester pike 3
call AI.itemBuild.add('dust') //shappire boots 3
set AI.itemBuild.enchantBuild.random1 = 'I032'
set AI.itemBuild.enchantBuild.random2 = 'I00H'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I03A','rwiz')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_TITAN_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AILA.StartAI(HERO_AI,false)
call AILA.createSkillBuild()
call AILA.createUpgradeBuild()
call AILA.createItemBuild()
call AILA.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HLM1')
endfunction
endscope
scope AIFrozenshell initializer init
struct AIFS extends array
static integer count = 0
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_TITAN_ID) == 0
local boolean tb = UnitHasBuff(u,TitanWall.buff)
local real d
local real x
local real y
local real a
if FROST_ENEMIES != 0 then
set count = count + 1
if count >= 5 then
set FROST_ENEMIES = 0
set count = 0
endif
endif
if tb and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
set AI.riskAction = true
endif
if AI.enemyHeroCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.closestEnemyDistance <= 250 then
if IssueImmediateOrderById(u,ORDER_thunderclap) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyHeroCount >= 2 or AI.percentLife <= 0.50 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 800 then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
if IsUnitMoving(AI.weakEnemy) then
set a = Angle(AI.hx,AI.hy,x,y)
set x = x + 100 * Cos(a)
set y = y + 100 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 then
if (FROST_ENEMIES >= 2 or AI.weakEnemyHp <= 0.40) and AI.enemyHeroCount >= 2 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a2.isOnCooldown() and a2.level != 0 then
if (AI.enemyUnitCount >= 3 or AI.goldUnit != null) and DistanceBetweenUnits(u,AI.weakUnit) <= 200 then
if IssueImmediateOrderById(u,ORDER_thunderclap) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if AI.enemyHeroCount >= 3 or AI.percentLife <= 0.30 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('FSA1')
call AI.abilityBuild.registerLearnSkill('FSA2')
call AI.abilityBuild.registerLearnSkill('FSA3')
call AI.abilityBuild.registerLearnSkill('FSA1')
call AI.abilityBuild.registerLearnSkill('FSA4')
call AI.abilityBuild.registerLearnSkill('A03B') //Perk
call AI.abilityBuild.registerLearnSkill('FSA2')
call AI.abilityBuild.registerLearnSkill('FSA1')
call AI.abilityBuild.registerLearnSkill('FSA2')
call AI.abilityBuild.registerLearnSkill('FSA4')
call AI.abilityBuild.registerLearnSkill('A0AW') //Perk
call AI.abilityBuild.registerLearnSkill('FSA1')
call AI.abilityBuild.registerLearnSkill('FSA2')
call AI.abilityBuild.registerLearnSkill('FSA3')
call AI.abilityBuild.registerLearnSkill('FSA4')
call AI.abilityBuild.registerLearnSkill('A03R') //Perk
call AI.abilityBuild.registerLearnSkill('FSA3')
call AI.abilityBuild.registerLearnSkill('FSA3')
call AI.abilityBuild.registerLearnSkill('A0AD') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('kybl') //arcanite buckler 1
call AI.itemBuild.add('gmfr') //emerlad brooch 1
call AI.itemBuild.add('dust') //shappire boots 1
call AI.itemBuild.add('kybl') //arcanite buckler 2
call AI.itemBuild.add('gmfr') //emerlad brooch 2
call AI.itemBuild.add('prvt') //symbol of valour 1
call AI.itemBuild.add('wild') //ancient drums 1
call AI.itemBuild.add('prvt') //symbol of valour 2
call AI.itemBuild.add('kybl') //arcanite buckler 3
call AI.itemBuild.add('wild') //ancient drums 2
call AI.itemBuild.add('dust') //shappire boots 2
call AI.itemBuild.add('gmfr') //emerlad brooch 3
call AI.itemBuild.add('ckng') //battle insignia 1
call AI.itemBuild.add('prvt') //symbol of valour 3
call AI.itemBuild.add('ckng') //battle insignia 2
call AI.itemBuild.add('wild') //ancient drums 3
call AI.itemBuild.add('ckng') //battle insignia 3
call AI.itemBuild.add('dust') //shappire boots 3
set AI.itemBuild.enchantBuild.random1 = 'I03F'
set AI.itemBuild.enchantBuild.random2 = 'I00H'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I03A','rwiz')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02T','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_TITAN_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIFS.StartAI(HERO_AI,false)
call AIFS.createSkillBuild()
call AIFS.createUpgradeBuild()
call AIFS.createItemBuild()
call AIFS.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HFS1')
endfunction
endscope
scope AIGoblinGrenadier initializer init
struct AIGG extends array
static boolean reachesTarget = false
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local CobraK300 b = GetUnitBuff(u,CobraK300.buff).buffAllocIndex
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MURDERER_ID) == 0
if b != 0 then
if AI.returnToBase then
if AI.enemyHeroCount > 0 then
if BlzGetUnitAbilityCooldownRemaining(b.ve,'A08L') == 0 then
if IssueTargetOrderById(b.ve,ORDER_thunderbolt,AI.weakEnemy) then
set u = null
return
endif
endif
endif
if AI.inBase then
call IssueImmediateOrderById(b.ve,ORDER_taunt)
set u = null
return
else
call IssuePointOrderById(b.ve,ORDER_move,AI.lastTargetX,AI.lastTargetY)
set u = null
return
endif
else
if AI.enemyHeroCount > 0 then
if BlzGetUnitAbilityCooldownRemaining(b.ve,'A08L') == 0 then
if IssueTargetOrderById(b.ve,ORDER_thunderbolt,AI.weakEnemy) then
set u = null
return
endif
endif
endif
if (AI.enemyHeroCount != 0 or AI.weakTower != null or (AI.enemyUnitCount != 0 and AI.state != 7) or reachesTarget) then
call IssueImmediateOrderById(b.ve,ORDER_taunt)
set u = null
set reachesTarget = false
return
else
call IssuePointOrderById(b.ve,ORDER_move,AI.lastTargetX,AI.lastTargetY)
set u = null
return
endif
endif
else
if not a4.isOnCooldown() and a4.level != 0 then
if (AI.enemyHeroCount == 0 and AI.enemyUnitCount == 0) or AI.state == 7 or AI.percentLife <= 0.25 then
if IssueImmediateOrderById(u,ORDER_summongrizzly) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyHeroCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 700 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 175 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.weakEnemyHp <= 0.25 or AI.enemyHeroCount >= AI.alliedHeroCount or AI.percentLife <= 0.50 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 900 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.enemyUnitCount >= 4 or AI.goldUnit != null then
if not a3.isOnCooldown() and a3.level != 0 then
if DistanceBetweenUnits(u,AI.weakUnit) <= 900 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('GGA1')
call AI.abilityBuild.registerLearnSkill('GGA2')
call AI.abilityBuild.registerLearnSkill('GGA3')
call AI.abilityBuild.registerLearnSkill('GGA1')
call AI.abilityBuild.registerLearnSkill('GGA4')
call AI.abilityBuild.registerLearnSkill('A034') //Perk
call AI.abilityBuild.registerLearnSkill('GGA2')
call AI.abilityBuild.registerLearnSkill('GGA1')
call AI.abilityBuild.registerLearnSkill('GGA2')
call AI.abilityBuild.registerLearnSkill('GGA4')
call AI.abilityBuild.registerLearnSkill('A03N') //Perk
call AI.abilityBuild.registerLearnSkill('GGA1')
call AI.abilityBuild.registerLearnSkill('GGA2')
call AI.abilityBuild.registerLearnSkill('GGA3')
call AI.abilityBuild.registerLearnSkill('GGA4')
call AI.abilityBuild.registerLearnSkill('A03S') //Perk
call AI.abilityBuild.registerLearnSkill('GGA3')
call AI.abilityBuild.registerLearnSkill('GGA3')
call AI.abilityBuild.registerLearnSkill('A0CH') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'amrc'
set AI.itemBuild.startItemID2 = 'blba'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('azhr') //Snake Vest 1
call AI.itemBuild.add('ckng') //Battle Insignia 1
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('ckng') //Battle Insignia 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('rwiz') //Black Mace 1
call AI.itemBuild.add('stel') //Sun Daggers 1
call AI.itemBuild.add('rwiz') //Black Mace 2
call AI.itemBuild.add('stel') //Sun Daggers 2
call AI.itemBuild.add('pnvu') //spider broach 1
call AI.itemBuild.add('pnvu') //spider broach 2
call AI.itemBuild.add('rwiz') //Black Mace 3
call AI.itemBuild.add('azhr') //Snake Vest 2
call AI.itemBuild.add('azhr') //Snake Vest 3
call AI.itemBuild.add('stel') //Sun Daggers 3
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
call AI.itemBuild.add('ckng') //Battle Insignia 3
call AI.itemBuild.add('pnvu') //spider broach 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I031'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I03A','rwiz')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MURDERER_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIGG.StartAI(HERO_AI,false)
call AIGG.createSkillBuild()
call AIGG.createUpgradeBuild()
call AIGG.createItemBuild()
call AIGG.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HGG1')
endfunction
endscope
scope AIVoodooPriest initializer init
struct AIVP extends array
static unit totem = null
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local Buff b = GetUnitData(u,"VMaskBuff")
local Table tb = GetUnitData(u,"DS_Ability")
local LinkedList list = tb.integer[1]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MIND_ID) == 0
local real d
local real d2
if AI.enemyHeroCount > 0 then
set d = DistanceBetweenUnits(u,AI.weakEnemy)
set d2 = DistanceBetweenUnits(u,AI.threatEnemy)
if not a3.isOnCooldown() and a3.level != 0 then
if AI.enemyHeroCount >= 2 then
if b == 0 then
if d2 <= 750 then
if IssueTargetOrderById(u,ORDER_rejuvination,AI.threatEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if b.target == AI.weakEnemy and AI.threatEnemy != AI.weakEnemy then
if d2 <= 750 then
if IssueTargetOrderById(u,ORDER_rejuvination,AI.threatEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
else
if b == 0 then
if d <= 750 then
if IssueTargetOrderById(u,ORDER_rejuvination,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if list.size != 0 then
if totem != null then
set tb = GetUnitUserData(totem)
if DistanceBetweenUnits(AI.weakEnemy,totem) <= 250 and DistanceBetweenUnits(totem,u) <= 800 and tb.real[2] >= 3.00 then
if IssueTargetOrderById(u,ORDER_firebolt,totem) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if GetRandomInt(1,100) <= 20 * list.size and list.size > 1 then
if IssueTargetOrderById(u,ORDER_firebolt,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyHeroCount == 1 and AI.weakEnemyHp <= 0.25 then
if d <= 600 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
elseif AI.enemyHeroCount >= AI.alliedHeroCount then
if b != 0 then
if d <= 600 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if b.target == AI.weakEnemy and AI.enemyHeroCount == 1 then
if AI.alliedHeroCount == 0 then
if IssueTargetOrderById(u,ORDER_spiritlink,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
else
if DistanceBetweenUnits(u,AI.weakAllied) <= 700 then
if IssueTargetOrderById(u,ORDER_spiritlink,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
else
if d <= 700 and AI.weakEnemyHp <= 0.50 then
if IssueTargetOrderById(u,ORDER_spiritlink,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.alliedHeroCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakAllied) <= 700 and AI.weakAlliedHp <= 0.80 then
if IssueTargetOrderById(u,ORDER_spiritlink,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null then
if not a3.isOnCooldown() and b == 0 then
if IssueTargetOrderById(u,ORDER_rejuvination,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if AI.percentLife <= 0.75 then
if AI.enemyUnitCount == 0 then
if IssueTargetOrderById(u,ORDER_spiritlink,u) then
set AI.busyTimes = 1
set u = null
return
endif
else
if IssueTargetOrderById(u,ORDER_spiritlink,AI.weakUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('VPA1')
call AI.abilityBuild.registerLearnSkill('VPA2')
call AI.abilityBuild.registerLearnSkill('VPA3')
call AI.abilityBuild.registerLearnSkill('VPA1')
call AI.abilityBuild.registerLearnSkill('VPA4')
call AI.abilityBuild.registerLearnSkill('A03B') //Perk
call AI.abilityBuild.registerLearnSkill('VPA2')
call AI.abilityBuild.registerLearnSkill('VPA1')
call AI.abilityBuild.registerLearnSkill('VPA3')
call AI.abilityBuild.registerLearnSkill('VPA4')
call AI.abilityBuild.registerLearnSkill('A03M') //Perk
call AI.abilityBuild.registerLearnSkill('VPA1')
call AI.abilityBuild.registerLearnSkill('VPA2')
call AI.abilityBuild.registerLearnSkill('VPA3')
call AI.abilityBuild.registerLearnSkill('VPA4')
call AI.abilityBuild.registerLearnSkill('A03T') //Perk
call AI.abilityBuild.registerLearnSkill('VPA2')
call AI.abilityBuild.registerLearnSkill('VPA3')
call AI.abilityBuild.registerLearnSkill('A0AE') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'arsh'
set AI.itemBuild.startItemID2 = 'frhg'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('rde2') //Imbued Relic 1
call AI.itemBuild.add('mgtk') //Druid Clothes 1
call AI.itemBuild.add('modt') //Beer Barrel 1
call AI.itemBuild.add('rde2') //Imbued Relic 2
call AI.itemBuild.add('mgtk') //Druid Clothes 2
call AI.itemBuild.add('dust') //Shappire Boots 1
call AI.itemBuild.add('pres') //Voodoo Cane 1
call AI.itemBuild.add('modt') //Beer Barrel 2
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('rde2') //Imbued Relic 3
call AI.itemBuild.add('mgtk') //Druid Clothes 3
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('modt') //Beer Barrel 3
call AI.itemBuild.add('pres') //Voodoo Cane 2
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('dust') //Shappire Boots 2
call AI.itemBuild.add('pres') //Voodoo Cane 3
call AI.itemBuild.add('dust') //Shappire Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I04V'
set AI.itemBuild.enchantBuild.random2 = 'I033'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MIND_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIVP.StartAI(HERO_AI,false)
call AIVP.createSkillBuild()
call AIVP.createUpgradeBuild()
call AIVP.createItemBuild()
call AIVP.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HVP1')
endfunction
endscope
scope AIEarthbinder initializer init
struct AIEB extends array
static Missile earthenAxe = 0
static unit golem1 = null
static unit golem2 = null
static boolean lastShield = false
static boolean lastTremor = false
static boolean array cast[3]
static real petDist1 = 0
static real petDist2 = 0
static boolean activated = false
private static method GolemActions takes unit u , integer index, real d returns nothing
local real x
local real y
local real a
local real hp = GetUnitLifePercent(u)
set cast[index] = false
if d <= 700 and AI.percentLife <= 0.60 and not UnitHasBuff(AI.playerHero.hero,PrimalShield.buff) and not lastShield then
if IssueTargetOrderById(u,ORDER_massteleport,AI.playerHero.hero) then
set lastShield = true
set cast[index] = true
return
endif
endif
if AI.alliedHeroCount > 0 then
if DistanceBetweenUnits(u,AI.weakAllied) <= 700 and AI.weakAlliedHp <= 0.40 and not lastShield and not UnitHasBuff(AI.weakAllied,PrimalShield.buff) then
if IssueTargetOrderById(u,ORDER_massteleport,AI.weakAllied) then
set cast[index] = true
set lastShield = true
return
endif
endif
endif
if AI.enemyHeroCount > 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 and ((AI.weakEnemyHp <= 0.40 and hp <= 50) or hp <= 15) and not lastTremor then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
set a = Angle(GetUnitX(u),GetUnitY(u),x,y)
set x = x + 120 * Cos(a)
set y = y + 120 * Sin(a)
if IssuePointOrderById(u,ORDER_massteleport,x,y) then
set cast[index] = true
set lastTremor = true
return
endif
endif
endif
if AI.enemyUnitCount >= 2 then
set x = GetUnitX(AI.weakUnit)
set y = GetUnitY(AI.weakUnit)
if hp <= 10 and Distance(x,y,GetUnitX(u),GetUnitY(u)) <= 800 and not lastTremor then
set a = Angle(GetUnitX(u),GetUnitY(u),x,y)
if IssuePointOrderById(u,ORDER_massteleport,x,y) then
set cast[index] = true
set lastTremor = true
return
endif
endif
endif
endmethod
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MURDERER_ID) == 0
local real x
local real y
local real a
if golem1 != null then
set petDist1 = DistanceBetweenUnits(u,golem1)
call GolemActions(golem1,1,petDist1)
endif
if golem2 != null then
set petDist2 = DistanceBetweenUnits(u,golem2)
call GolemActions(golem2,2,petDist2)
endif
if traitCD then
if AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.enemyHeroCount >= 1 or AI.weakTower != null or AI.goldUnit != null and not AI.returnToBase and (golem1 == null and golem2 == null) then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyHeroCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 then
if (golem1 != null or golem2 != null) and AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_cannibalize) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 800 then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
set a = Angle(GetUnitX(u),GetUnitY(u),x,y)
set x = x + 75.00 * Cos(a)
set y = y + 75.00 * Sin(a)
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyHeroCount >= 1 and not UnitHasBuff(u,Tremors.buff) and not EarthenSteelMissile[earthenAxe].returning then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyUnitCount >= 4 or AI.goldUnit != null then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('EBA1')
call AI.abilityBuild.registerLearnSkill('EBA2')
call AI.abilityBuild.registerLearnSkill('EBA3')
call AI.abilityBuild.registerLearnSkill('EBA1')
call AI.abilityBuild.registerLearnSkill('EBA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('EBA2')
call AI.abilityBuild.registerLearnSkill('EBA3')
call AI.abilityBuild.registerLearnSkill('EBA2')
call AI.abilityBuild.registerLearnSkill('EBA4')
call AI.abilityBuild.registerLearnSkill('A03L') //Perk
call AI.abilityBuild.registerLearnSkill('EBA3')
call AI.abilityBuild.registerLearnSkill('EBA1')
call AI.abilityBuild.registerLearnSkill('EBA3')
call AI.abilityBuild.registerLearnSkill('EBA4')
call AI.abilityBuild.registerLearnSkill('A03X') //Perk
call AI.abilityBuild.registerLearnSkill('EBA2')
call AI.abilityBuild.registerLearnSkill('EBA1')
call AI.abilityBuild.registerLearnSkill('A0CJ') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'arsh'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 8
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('ciri') //Titan Staff 1
call AI.itemBuild.add('wild') //Ancient Drums 1
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('ciri') //Titan Staff 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('wild') //Ancient Drums 2
call AI.itemBuild.add('tkno') //Earth Idol 1
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('fgrg') //Gravewalker Heart 1
call AI.itemBuild.add('ciri') //Titan Staff 3
call AI.itemBuild.add('fgrg') //Gravewalker Heart 2
call AI.itemBuild.add('tkno') //Earth Idol 2
call AI.itemBuild.add('wild') //Ancient Drums 3
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('tkno') //Earth Idol 3
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
call AI.itemBuild.add('fgrg') //Gravewalker Heart 3
set AI.itemBuild.enchantBuild.random1 = 'I00H'
set AI.itemBuild.enchantBuild.random2 = 'I00H'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02Y','gopr')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MURDERER_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIEB.StartAI(HERO_AI,false)
call AIEB.createSkillBuild()
call AIEB.createUpgradeBuild()
call AIEB.createItemBuild()
call AIEB.selectTrait()
set AIEB.activated = true
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HEB1')
endfunction
endscope
scope AIWarlock initializer init
struct AIWL extends array
static integer netherCurseCount = 0
public static method OnChanneling takes InnerDemon b returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
if b != 0 then
if AI.percentLife >= 0.90 then
if not b.charge and BlzGetUnitAbilityCooldownRemaining(u,'A018') == 0 then
if IssueImmediateOrderById(u,ORDER_manashieldon) then
set u = null
return
endif
endif
endif
if b.charge then
if b.count >= 5 or AI.percentLife <= 0.25 then
if b.target != null then
if IssueImmediateOrderById(u,ORDER_manashieldoff) then
set u = null
return
endif
endif
endif
endif
endif
if AI.threat > AI.threatThreshold * 2 or AI.returnToBase or not a1.isOnCooldown() then
if IssueImmediateOrderById(u,ORDER_stop) then
set u = null
return
endif
endif
set u = null
endmethod
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_REPLENISH_ID) == 0
local InnerDemon b = GetUnitBuff(u,InnerDemon.buff).buffAllocIndex
local real x
local real y
local real a
local real d
if AI.channelingOrder != 0 or AI.busyTimes > 0 then
if AI.channelingOrder == ORDER_drain then
call OnChanneling(b)
endif
set u = null
return
endif
if b != 0 then
if AI.percentLife >= 0.90 then
if not b.charge then
if IssueImmediateOrderById(u,ORDER_manashieldon) then
set u = null
return
endif
endif
endif
if b.charge then
if b.count == 10 or AI.percentLife <= 0.50 then
if b.target != null then
if IssueImmediateOrderById(u,ORDER_manashieldoff) then
set u = null
return
endif
else
if AI.weakEnemy != null then
if IsUnitInSightOfUnit(u,AI.weakEnemy,30.00) then
if IssueImmediateOrderById(u,ORDER_manashieldoff) then
set u = null
return
endif
endif
endif
endif
endif
endif
endif
if AI.enemyHeroCount > 0 then
set d = DistanceBetweenUnits(u,AI.weakEnemy)
if not a1.isOnCooldown() and a1.level != 0 then
if d <= 600 then
set netherCurseCount = 0
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.enemyHeroCount >= 2 and AI.percentLife >= 0.50 then
if IssueImmediateOrderById(u,ORDER_tranquility) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if UnitHasBuff(AI.weakEnemy,NetherCurse.buff) then
if d <= 600 then
if not IsUnitMoving(AI.weakEnemy) then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
else
set a = GetUnitFacing(AI.weakEnemy) * bj_DEGTORAD
set x = GetUnitX(AI.weakEnemy) + 200 * Cos(a)
set y = GetUnitY(AI.weakEnemy) + 200 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_earthquake,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 and netherCurseCount != 0 then
if not AI.returnToBase and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if d <= 600 then
if IssueTargetOrderById(u,ORDER_drain,AI.weakEnemy) then
set AI.channelingOrder = ORDER_drain
set u = null
return
endif
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.enemyUnitCount >= 3 and DistanceBetweenUnits(u,AI.weakUnit) <= 600 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null then
if not a3.isOnCooldown() and a3.level != 0 then
if AI.percentLife <= 0.80 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 200 then
if IssueTargetOrderById(u,ORDER_drain,AI.goldUnit) then
set AI.channelingOrder = ORDER_drain
set u = null
return
endif
endif
endif
endif
endif
if AI.alliedHeroCount > 0 then
if traitCD and AI.enemyHeroCount >= 1 and (AI.weakAlliedHp <= 0.20 or AI.percentLife <= 0.20) then
if IssueTargetOrderById(u,ORDER_antimagicshell,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('WLA1')
call AI.abilityBuild.registerLearnSkill('WLA3')
call AI.abilityBuild.registerLearnSkill('WLA2')
call AI.abilityBuild.registerLearnSkill('WLA1')
call AI.abilityBuild.registerLearnSkill('WLA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('WLA3')
call AI.abilityBuild.registerLearnSkill('WLA2')
call AI.abilityBuild.registerLearnSkill('WLA1')
call AI.abilityBuild.registerLearnSkill('WLA4')
call AI.abilityBuild.registerLearnSkill('A03M') //Perk
call AI.abilityBuild.registerLearnSkill('WLA3')
call AI.abilityBuild.registerLearnSkill('WLA1')
call AI.abilityBuild.registerLearnSkill('WLA2')
call AI.abilityBuild.registerLearnSkill('WLA4')
call AI.abilityBuild.registerLearnSkill('A03T') //Perk
call AI.abilityBuild.registerLearnSkill('WLA3')
call AI.abilityBuild.registerLearnSkill('WLA2')
call AI.abilityBuild.registerLearnSkill('A0CK') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'brag'
set AI.itemBuild.startItemR1 = 8
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('ciri') //Titan Staff 1
call AI.itemBuild.add('sand') //Heretics Ring 1
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('ciri') //Titan Staff 2
call AI.itemBuild.add('dust') //Shappire Boots 1
call AI.itemBuild.add('sand') //Heretics Ring 2
call AI.itemBuild.add('mnst') //Imbued Orb 1
call AI.itemBuild.add('bzbf') //Dragonhide Jacket 1
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('sand') //Heretics Ring 3
call AI.itemBuild.add('bzbf') //Dragonhide Jacket 2
call AI.itemBuild.add('mnst') //Imbued Orb 2
call AI.itemBuild.add('ciri') //Titan Staff 3
call AI.itemBuild.add('mnst') //Imbued Orb 3
call AI.itemBuild.add('bzbf') //Dragonhide Jacket 3
call AI.itemBuild.add('dust') //Shappire Boots 2
call AI.itemBuild.add('dust') //Shappire Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I00F'
set AI.itemBuild.enchantBuild.random2 = 'I033'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02X','gopr')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_REPLENISH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIWL.StartAI(HERO_AI,false)
call AIWL.createSkillBuild()
call AIWL.createUpgradeBuild()
call AIWL.createItemBuild()
call AIWL.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HWL1')
endfunction
endscope
scope AIZealot initializer init
struct AIZE extends array
static BerserkClone bc = 0
static integer sb = 0
static real petDist = 0
public static method BerserkShadowActions takes nothing returns nothing
local real cd1
local real cd2
if sb == 0 then
set cd1 = BlzGetUnitAbilityCooldownRemaining(bc.clone,'A09U')
set cd2 = BlzGetUnitAbilityCooldownRemaining(bc.clone,'A09V')
if AI.enemyHeroCount > 0 then
if cd1 == 0 then
if DistanceBetweenUnits(bc.clone,AI.weakEnemy) <= 700 then
if IssuePointOrderById(bc.clone,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set sb = 1
return
endif
endif
endif
if cd2 == 0 and (AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.50) and not AI.returnToBase then
if DistanceBetweenUnits(bc.clone,AI.weakEnemy) <= 700 then
if IssuePointOrderById(bc.clone,ORDER_flamestrike,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set sb = 2
return
endif
endif
endif
endif
else
if sb > 0 then
set sb = sb - 1
endif
endif
endmethod
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean b3 = UnitHasBuff(u,KillerInstinct.buff)
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MURDERER_ID) == 0
local real x
local real y
local real a
set bc = GetUnitData(u,"BerserkC")
if bc != 0 then
set petDist = DistanceBetweenUnits(u,bc.clone)
call BerserkShadowActions()
endif
if not a3.isOnCooldown() and a3.level != 0 then
if bc != 0 then
if AI.percentLife > 0.25 and AI.threat < AI.threatThreshold and AI.enemyHeroCount > 0 then
if not b3 then
if IssueImmediateOrderById(u,ORDER_immolation) then
set u = null
return
endif
endif
else
if b3 then
if IssueImmediateOrderById(u,ORDER_unimmolation) then
set u = null
return
endif
endif
endif
else
if b3 then
if IssueImmediateOrderById(u,ORDER_unimmolation) then
set u = null
return
endif
endif
endif
endif
if AI.enemyHeroCount > 0 or AI.weakTower != null or AI.goldUnit != null then
if not a2.isOnCooldown() and a2.level != 0 then
if IssueImmediateOrderById(u,ORDER_summongrizzly) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyHeroCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 700 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.alliedHeroCount >= AI.enemyHeroCount and AI.weakEnemyHp <= 0.25 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 then
if not IsUnitMoving(AI.weakEnemy) then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
else
set a = GetUnitFacing(AI.weakEnemy) * bj_DEGTORAD
set x = GetUnitX(AI.weakEnemy) + 200 * Cos(a)
set y = GetUnitY(AI.weakEnemy) + 200 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 2
set u = null
return
endif
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.enemyUnitCount >= 4 and DistanceBetweenUnits(u,AI.weakUnit) <= 600 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD and not AI.retreating and AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('ZEA1')
call AI.abilityBuild.registerLearnSkill('ZEA2')
call AI.abilityBuild.registerLearnSkill('ZEA3')
call AI.abilityBuild.registerLearnSkill('ZEA1')
call AI.abilityBuild.registerLearnSkill('ZEA4')
call AI.abilityBuild.registerLearnSkill('A034') //Perk
call AI.abilityBuild.registerLearnSkill('ZEA3')
call AI.abilityBuild.registerLearnSkill('ZEA1')
call AI.abilityBuild.registerLearnSkill('ZEA2')
call AI.abilityBuild.registerLearnSkill('ZEA4')
call AI.abilityBuild.registerLearnSkill('A03J') //Perk
call AI.abilityBuild.registerLearnSkill('ZEA1')
call AI.abilityBuild.registerLearnSkill('ZEA3')
call AI.abilityBuild.registerLearnSkill('ZEA2')
call AI.abilityBuild.registerLearnSkill('ZEA4')
call AI.abilityBuild.registerLearnSkill('A03S') //Perk
call AI.abilityBuild.registerLearnSkill('ZEA3')
call AI.abilityBuild.registerLearnSkill('ZEA2')
call AI.abilityBuild.registerLearnSkill('A0CH') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('azhr') //Snake Vest 1
call AI.itemBuild.add('evtl') //Katana 1
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('evtl') //Katana 2
call AI.itemBuild.add('azhr') //Snake Vest 2
call AI.itemBuild.add('engs') //Defiled Helm 1
call AI.itemBuild.add('ckng') //Battle Insignia 1
call AI.itemBuild.add('engs') //Defiled Helm 2
call AI.itemBuild.add('ckng') //Battle Insignia 2
call AI.itemBuild.add('ajen') //Tempest Hammer 1
call AI.itemBuild.add('evtl') //Katana 3
call AI.itemBuild.add('azhr') //Snake Vest 3
call AI.itemBuild.add('ajen') //Tempest Hammer 2
call AI.itemBuild.add('ckng') //Battle Insignia 3
call AI.itemBuild.add('engs') //Defiled Helm 3
call AI.itemBuild.add('ajen') //Tempest Hammer 3
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I031'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I034','evtl')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MURDERER_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIZE.StartAI(HERO_AI,false)
call AIZE.createSkillBuild()
call AIZE.createUpgradeBuild()
call AIZE.createItemBuild()
call AIZE.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HZE1')
endfunction
endscope
scope AIMoonMistress initializer init
struct AIMM extends array
static real SFx
static real SFy
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local real r
local real x
local real y
local real a
if AI.enemyHeroCount > 0 then
if traitCD then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.enemyHeroCount >= 2 and AI.alliedHeroCount >= 1 and not AI.returnToBase then
if IssueImmediateOrderById(u,ORDER_howlofterror) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.75 then
if IssuePointOrderById(u,ORDER_rainoffire,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if SFx != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 800 then
if IssuePointOrderById(u,ORDER_earthquake,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
set SFx = 0
set SFy = 0
return
endif
endif
else
if AI.enemyHeroCount >= 2 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 800 then
if IssuePointOrderById(u,ORDER_earthquake,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.enemyHeroCount >= 3 then
set r = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
if not AI.returnToBase and MoonFire.DATAS.size >= 3 and (r >= 18 or r < 6) then
if IssueImmediateOrderById(u,ORDER_immolation) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.enemyUnitCount > 0 then
if not a2.isOnCooldown() and a2.level != 0 then
if (AI.enemyUnitCount >= 3 or AI.goldUnit != null) and DistanceBetweenUnits(u,AI.weakUnit) <= 600 then
if IssuePointOrderById(u,ORDER_rainoffire,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('MMA2')
call AI.abilityBuild.registerLearnSkill('MMA1')
call AI.abilityBuild.registerLearnSkill('MMA3')
call AI.abilityBuild.registerLearnSkill('MMA2')
call AI.abilityBuild.registerLearnSkill('MMA4')
call AI.abilityBuild.registerLearnSkill('A032') //Perk
call AI.abilityBuild.registerLearnSkill('MMA1')
call AI.abilityBuild.registerLearnSkill('MMA3')
call AI.abilityBuild.registerLearnSkill('MMA2')
call AI.abilityBuild.registerLearnSkill('MMA4')
call AI.abilityBuild.registerLearnSkill('A03M') //Perk
call AI.abilityBuild.registerLearnSkill('MMA1')
call AI.abilityBuild.registerLearnSkill('MMA3')
call AI.abilityBuild.registerLearnSkill('MMA2')
call AI.abilityBuild.registerLearnSkill('MMA4')
call AI.abilityBuild.registerLearnSkill('A03T') //Perk
call AI.abilityBuild.registerLearnSkill('MMA1')
call AI.abilityBuild.registerLearnSkill('MMA3')
call AI.abilityBuild.registerLearnSkill('A0CH') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'brag'
set AI.itemBuild.startItemID2 = 'frhg'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('modt') //Beer Barrel 1
call AI.itemBuild.add('ciri') //Titan Staff 1
call AI.itemBuild.add('sror') //Kelen's Boots 1
call AI.itemBuild.add('modt') //Beer Barrel 2
call AI.itemBuild.add('ciri') //Titan Staff 2
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('rde3') //Magic Emblem 1
call AI.itemBuild.add('ciri') //Titan Staff 3
call AI.itemBuild.add('modt') //Beer Barrel 3
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('rde3') //Magic Emblem 2
call AI.itemBuild.add('pres') //Voodoo Cane 1
call AI.itemBuild.add('pres') //Voodoo Cane 2
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('rde3') //Magic Emblem 3
call AI.itemBuild.add('pres') //Voodoo Cane 3
call AI.itemBuild.add('sror') //Kelen's Boots 2
call AI.itemBuild.add('sror') //Kelen's Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I04S'
set AI.itemBuild.enchantBuild.random2 = 'I031'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','ciri')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIMM.StartAI(HERO_AI,false)
call AIMM.createSkillBuild()
call AIMM.createUpgradeBuild()
call AIMM.createItemBuild()
call AIMM.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HMM1')
endfunction
endscope
scope AIHeadhunter initializer init
struct AIHH extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MURDERER_ID) == 0
local Buff b = GetUnitBuff(u,StackHeads.buff)
local real r
local real x
local real y
local real a
if AI.enemyHeroCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if GetRandomInt(1,100) <= 50 * AI.enemyHeroCount then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
else
if traitCD and not AI.retreating then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount and not AI.returnToBase and not AI.danger and a1.isOnCooldown() then
if IssueImmediateOrderById(u,ORDER_cannibalize) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null then
if not a1.isOnCooldown() and a1.level != 0 then
if GetRandomInt(1,100) <= 25 then
if DistanceBetweenUnits(u,AI.goldUnit) <= 600 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('HHA1')
call AI.abilityBuild.registerLearnSkill('HHA2')
call AI.abilityBuild.registerLearnSkill('HHA3')
call AI.abilityBuild.registerLearnSkill('HHA2')
call AI.abilityBuild.registerLearnSkill('HHA4')
call AI.abilityBuild.registerLearnSkill('A042') //Perk
call AI.abilityBuild.registerLearnSkill('HHA1')
call AI.abilityBuild.registerLearnSkill('HHA3')
call AI.abilityBuild.registerLearnSkill('HHA2')
call AI.abilityBuild.registerLearnSkill('HHA4')
call AI.abilityBuild.registerLearnSkill('A03L') //Perk
call AI.abilityBuild.registerLearnSkill('HHA1')
call AI.abilityBuild.registerLearnSkill('HHA3')
call AI.abilityBuild.registerLearnSkill('HHA2')
call AI.abilityBuild.registerLearnSkill('HHA4')
call AI.abilityBuild.registerLearnSkill('A03U') //Perk
call AI.abilityBuild.registerLearnSkill('HHA1')
call AI.abilityBuild.registerLearnSkill('HHA3')
call AI.abilityBuild.registerLearnSkill('A0CH') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'amrc'
set AI.itemBuild.startItemID2 = 'blba'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('rwiz') //Black Mace 1
call AI.itemBuild.add('ajen') //Tempest Hammer 1
call AI.itemBuild.add('fgdg') //Dynamic Bots 1
call AI.itemBuild.add('rwiz') //Black Mace 2
call AI.itemBuild.add('ajen') //Tempest Hammer 2
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('pomn') //Troll Mask 1
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('pomn') //Troll Mask 2
call AI.itemBuild.add('ajen') //Tempest Hammer 3
call AI.itemBuild.add('pnvu') //Spider Broach 1
call AI.itemBuild.add('pomn') //Troll Mask 3
call AI.itemBuild.add('rwiz') //Black Mace 3
call AI.itemBuild.add('pnvu') //Spider Broach 2
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('pnvu') //Spider Broach 3
call AI.itemBuild.add('fgdg') //Dynamic Bots 2
call AI.itemBuild.add('fgdg') //Dynamic Bots 3
set AI.itemBuild.enchantBuild.random1 = 'I00F'
set AI.itemBuild.enchantBuild.random2 = 'I04U'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','ajen')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MURDERER_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIHH.StartAI(HERO_AI,false)
call AIHH.createSkillBuild()
call AIHH.createUpgradeBuild()
call AIHH.createItemBuild()
call AIHH.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HHH1')
endfunction
endscope
scope AIPlagueBringer initializer init
struct AIPB extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_RECKLESS_ID) == 0
local boolean tb = UnitHasBuff(u,Reckless.buff)
local real x
local real y
local real a
if tb then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
set AI.riskAction = true
endif
endif
if AI.enemyHeroCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 then
if (AI.percentLife > 0.20 or AI.riskAction) and not AI.danger then
if AI.closestEnemyDistance <= 210 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyHeroCount > AI.alliedHeroCount then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if not AI.returnToBase and AI.closestEnemyDistance <= 300 then
if IssueTargetOrderById(u,ORDER_shadowstrike,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if AI.weakEnemyHp <= 0.35 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 550 then
if not IsUnitMoving(AI.weakEnemy) then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
else
set a = GetUnitFacing(AI.weakEnemy) * bj_DEGTORAD
set x = GetUnitX(AI.weakEnemy) + 50 * Cos(a)
set y = GetUnitY(AI.weakEnemy) + 50 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if UnitHasBuff(u,ShakeEntrails.buff) then
if DistanceBetweenUnits(u,AI.threatEnemy) <= 550 then
if not IsUnitMoving(AI.threatEnemy) then
set x = GetUnitX(AI.threatEnemy)
set y = GetUnitY(AI.threatEnemy)
else
set a = GetUnitFacing(AI.threatEnemy) * bj_DEGTORAD
set x = GetUnitX(AI.threatEnemy) + 50 * Cos(a)
set y = GetUnitY(AI.threatEnemy) + 50 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
endif
if AI.enemyUnitCount >= 3 or AI.goldUnit != null then
if not a2.isOnCooldown() and a2.level != 0 and AI.inCombat then
if IssueTargetOrderById(u,ORDER_shadowstrike,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if traitCD then
if AI.percentLife <= 0.10 or AI.returnToBase then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('PBA1')
call AI.abilityBuild.registerLearnSkill('PBA2')
call AI.abilityBuild.registerLearnSkill('PBA3')
call AI.abilityBuild.registerLearnSkill('PBA2')
call AI.abilityBuild.registerLearnSkill('PBA4')
call AI.abilityBuild.registerLearnSkill('A042') //Perk
call AI.abilityBuild.registerLearnSkill('PBA3')
call AI.abilityBuild.registerLearnSkill('PBA2')
call AI.abilityBuild.registerLearnSkill('PBA3')
call AI.abilityBuild.registerLearnSkill('PBA4')
call AI.abilityBuild.registerLearnSkill('A03M') //Perk
call AI.abilityBuild.registerLearnSkill('PBA2')
call AI.abilityBuild.registerLearnSkill('PBA3')
call AI.abilityBuild.registerLearnSkill('PBA1')
call AI.abilityBuild.registerLearnSkill('PBA4')
call AI.abilityBuild.registerLearnSkill('A007') //Perk
call AI.abilityBuild.registerLearnSkill('PBA1')
call AI.abilityBuild.registerLearnSkill('PBA1')
call AI.abilityBuild.registerLearnSkill('A0CJ') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'vddl'
set AI.itemBuild.startItemID2 = 'brag'
set AI.itemBuild.startItemR1 = 8
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('kybl') //Arcanite Buckler 1
call AI.itemBuild.add('ckng') //Battle Insignia 1
call AI.itemBuild.add('dust') //Shappire Bots 1
call AI.itemBuild.add('kybl') //Arcanite Buckler 2
call AI.itemBuild.add('ckng') //Battle Insignia 2
call AI.itemBuild.add('phlt') //Kraken Shell 1
call AI.itemBuild.add('kybl') //Arcanite Buckler 3
call AI.itemBuild.add('fgrg') //Gravewalker Heart 1
call AI.itemBuild.add('ckng') //Battle Insignia 3
call AI.itemBuild.add('ratc') //Skull Hammer 1
call AI.itemBuild.add('phlt') //Kraken Shell 2
call AI.itemBuild.add('fgrg') //Gravewalker Heart 2
call AI.itemBuild.add('ratc') //Skull Hammer 2
call AI.itemBuild.add('phlt') //Kraken Shell 3
call AI.itemBuild.add('fgrg') //Gravewalker Heart 3
call AI.itemBuild.add('ratc') //Skull Hammer 3
call AI.itemBuild.add('dust') //Shappire Bots 2
call AI.itemBuild.add('dust') //Shappire Bots 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I00F'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02Z','kybl')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_RECKLESS_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIPB.StartAI(HERO_AI,false)
call AIPB.createSkillBuild()
call AIPB.createUpgradeBuild()
call AIPB.createItemBuild()
call AIPB.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HPB1')
endfunction
endscope
scope AIGryphonRider initializer init
struct AIGR extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_RECKLESS_ID) == 0
local SkyDive b = GetUnitBuff(u,SkyDive.buff).buffAllocIndex
local boolean tb = UnitHasBuff(u,TitanWall.buff)
local real x
local real y
if tb and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
set AI.riskAction = true
endif
if AI.enemyHeroCount > 0 and b == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.70 or AI.returnToBase then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
if Distance(AI.hx,AI.hy,x,y) <= 600 then
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.enemyHeroCount >= 2 then
if IssuePointOrderById(u,ORDER_rainoffire,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.alliedHeroCount > 0 and (AI.weakAlliedHp < 0.35 and AI.weakAlliedHp < AI.percentLife) then
if DistanceBetweenUnits(u,AI.weakAllied) <= 500 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakAllied) then
set AI.busyTimes = 1
set u = null
return
endif
endif
elseif AI.enemyHeroCount >= 2 or AI.percentLife <= 0.20 then
if IssueTargetOrderById(u,ORDER_firebolt,u) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if b != 0 then
if AI.enemyHeroCount > 0 then
if not a3.isOnCooldown() and a3.level != 0 then
if IssueImmediateOrderById(u,ORDER_howlofterror) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if (AI.enemyUnitCount >= 4 or AI.goldUnit != null) and b == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.goldUnit != null then
set x = GetUnitX(AI.goldUnit)
set y = GetUnitY(AI.goldUnit)
else
set x = GetUnitX(AI.weakUnit)
set y = GetUnitY(AI.weakUnit)
endif
if Distance(AI.hx,AI.hy,x,y) <= 500 then
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if AI.enemyHeroCount >= 3 or AI.percentLife <= 0.30 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('GRA1')
call AI.abilityBuild.registerLearnSkill('GRA3')
call AI.abilityBuild.registerLearnSkill('GRA2')
call AI.abilityBuild.registerLearnSkill('GRA3')
call AI.abilityBuild.registerLearnSkill('GRA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('GRA2')
call AI.abilityBuild.registerLearnSkill('GRA3')
call AI.abilityBuild.registerLearnSkill('GRA1')
call AI.abilityBuild.registerLearnSkill('GRA4')
call AI.abilityBuild.registerLearnSkill('A03K') //Perk
call AI.abilityBuild.registerLearnSkill('GRA1')
call AI.abilityBuild.registerLearnSkill('GRA2')
call AI.abilityBuild.registerLearnSkill('GRA3')
call AI.abilityBuild.registerLearnSkill('GRA4')
call AI.abilityBuild.registerLearnSkill('A03S') //Perk
call AI.abilityBuild.registerLearnSkill('GRA2')
call AI.abilityBuild.registerLearnSkill('GRA1')
call AI.abilityBuild.registerLearnSkill('A0AD') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'stwa'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('ajen') //Tempest Hammer 1
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('ajen') //Tempest Hammer 2
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('stel') //Sun Daggers 1
call AI.itemBuild.add('pgma') //Mirror Ring 1
call AI.itemBuild.add('ajen') //Tempest Hammer 3
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('pnvu') //Spider Broach 1
call AI.itemBuild.add('stel') //Sun Daggers 2
call AI.itemBuild.add('pgma') //Mirror Ring 2
call AI.itemBuild.add('pnvu') //Spider Broach 2
call AI.itemBuild.add('stel') //Sun Daggers 3
call AI.itemBuild.add('pgma') //Mirror Ring 3
call AI.itemBuild.add('pnvu') //Spider Broach 3
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I04Q'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_TITAN_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIGR.StartAI(HERO_AI,false)
call AIGR.createSkillBuild()
call AIGR.createUpgradeBuild()
call AIGR.createItemBuild()
call AIGR.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HGR1')
endfunction
endscope
scope AIFleshBehemoth initializer init
struct AIFB extends array
static integer WActive = 0
static boolean rcd
static real lastWX = 0
static real lastWY = 0
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[2]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_AVATAR_ID) == 0
local boolean hasW = GetUnitAbilityLevel(AI.weakEnemy,'B03Y') > 0
local boolean tb = Status.UnitHasStatus(STATUS_SPELL_IMMUNITY,u)
local real x
local real y
local real a
local real d
if not a3.isOnCooldown() and a3.level != 0 then
if AI.enemyUnitCount != 0 and AI.percentLife <= 0.30 then
if IssueImmediateOrderById(u,ORDER_howlofterror) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyHeroCount > 0 then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
set d = Distance(AI.hx,AI.hy,x,y)
if not a2.isOnCooldown() and a2.level != 0 and AI.percentLife > 0.10 then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if AIFB.WActive < AI.enemyHeroCount and not hasW and d <= 900 then
if not IsUnitMoving(AI.weakEnemy) then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
else
set a = GetUnitFacing(AI.weakEnemy) * bj_DEGTORAD
set x = GetUnitX(AI.weakEnemy) + 200 * Cos(a)
set y = GetUnitY(AI.weakEnemy) + 200 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if (AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.30 or hasW) and not AI.returnToBase then
if d <= 400 then
if IssueTargetOrderById(u,ORDER_magicleash,AI.weakEnemy) then
if GetHeroMasteryType(u) == 1 then
set AI.busyTimes = 1
else
set AI.channelingOrder = ORDER_magicleash
endif
set u = null
return
endif
endif
endif
if AI.enemyHeroCount < AI.alliedHeroCount then
if AI.closestEnemyDistance <= 400 then
if IssueTargetOrderById(u,ORDER_magicleash,AI.closestEnemyHero) then
set AI.channelingOrder = ORDER_magicleash
set u = null
return
endif
endif
endif
endif
if tb and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
set AI.riskAction = true
endif
endif
if (AI.enemyUnitCount >= 4 or AI.goldUnit != null) and AI.enemyHeroCount == 0 then
if not a2.isOnCooldown() and a2.level != 0 then
if AI.goldUnit != null then
set x = GetUnitX(AI.goldUnit)
set y = GetUnitY(AI.goldUnit)
else
set x = GetUnitX(AI.weakUnit)
set y = GetUnitY(AI.weakUnit)
endif
if WActive == 0 and lastWX != x and lastWY != y then
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if AI.enemyHeroCount >= 2 and not rcd then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('FBA2')
call AI.abilityBuild.registerLearnSkill('FBA3')
call AI.abilityBuild.registerLearnSkill('FBA1')
call AI.abilityBuild.registerLearnSkill('FBA2')
call AI.abilityBuild.registerLearnSkill('FBA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('FBA3')
call AI.abilityBuild.registerLearnSkill('FBA2')
call AI.abilityBuild.registerLearnSkill('FBA3')
call AI.abilityBuild.registerLearnSkill('FBA4')
call AI.abilityBuild.registerLearnSkill('A03N') //Perk
call AI.abilityBuild.registerLearnSkill('FBA2')
call AI.abilityBuild.registerLearnSkill('FBA3')
call AI.abilityBuild.registerLearnSkill('FBA1')
call AI.abilityBuild.registerLearnSkill('FBA4')
call AI.abilityBuild.registerLearnSkill('A03R') //Perk
call AI.abilityBuild.registerLearnSkill('FBA1')
call AI.abilityBuild.registerLearnSkill('FBA1')
call AI.abilityBuild.registerLearnSkill('A03O') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'vddl'
set AI.itemBuild.startItemID2 = 'brag'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 5
call AI.itemBuild.add('dust') //Shapire Boots 1
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('ckng') //Battle Insignia 1
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('ssil') //Crusader Sword 1
call AI.itemBuild.add('ckng') //Battle Insignia 2
call AI.itemBuild.add('afac') //Silver Axe 1
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('afac') //Silver Axe 2
call AI.itemBuild.add('ssil') //Crusader Sword 2
call AI.itemBuild.add('afac') //Silver Axe 3
call AI.itemBuild.add('fgrg') //Gravewalker Heart 1
call AI.itemBuild.add('ckng') //Battle Insignia 3
call AI.itemBuild.add('fgrg') //Gravewalker Heart 2
call AI.itemBuild.add('fgrg') //Gravewalker Heart 3
call AI.itemBuild.add('ssil') //Crusader Sword 3
call AI.itemBuild.add('dust') //Shapire Boots 2
call AI.itemBuild.add('dust') //Shapire Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I00F'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','gopr')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_AVATAR_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIFB.StartAI(HERO_AI,false)
call AIFB.createSkillBuild()
call AIFB.createUpgradeBuild()
call AIFB.createItemBuild()
call AIFB.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HFB1')
endfunction
endscope
scope AIDreamEater initializer init
struct AIDE extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean r = UnitHasBuff(u,EmeraldTrance.buff)
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local real x
local real y
local real a
local real d
if r then
if AI.enemyHeroCount == 0 or AI.alliedHeroCount == 0 or AI.percentLife < 0.30 then
if IssueImmediateOrderById(u,ORDER_unimmolation) then
set u = null
return
endif
endif
endif
if AI.enemyHeroCount > 0 then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
set d = Distance(AI.hx,AI.hy,x,y)
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyHeroCount > AI.alliedHeroCount + 1 then
if Distance(GetUnitX(AI.threatEnemy),GetUnitY(AI.threatEnemy),AI.hx,AI.hy) <= 600 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.threatEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if d <= 600 then
if IssueTargetOrderById(u,ORDER_firebolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if d <= 900 then
if not IsUnitMoving(AI.weakEnemy) then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
else
set a = GetUnitFacing(AI.weakEnemy) * bj_DEGTORAD
set x = GetUnitX(AI.weakEnemy) + 100 * Cos(a)
set y = GetUnitY(AI.weakEnemy) + 100 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.percentLife < 0.25 or (AI.danger and r) then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
set x = AI.hx + 500 * Cos(a)
set y = AI.hy + 500 * Sin(a)
else
if d <= 500 and AI.alliedHeroCount + 1 >= AI.enemyHeroCount and not AI.danger then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
else
set x = bj_PI
endif
endif
if x != bj_PI then
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount and AI.enemyHeroCount >= 2 then
if not AI.returnToBase then
if IssueImmediateOrderById(u,ORDER_immolation) then
set u = null
return
endif
endif
endif
endif
endif
if (AI.enemyUnitCount >= 4 or AI.goldUnit != null) and AI.enemyHeroCount == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.goldUnit != null then
set x = GetUnitX(AI.goldUnit)
set y = GetUnitY(AI.goldUnit)
else
set x = GetUnitX(AI.weakUnit)
set y = GetUnitY(AI.weakUnit)
endif
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.goldUnit != null and AI.alliedHeroCount > 0 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if traitCD then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('DEA1')
call AI.abilityBuild.registerLearnSkill('DEA3')
call AI.abilityBuild.registerLearnSkill('DEA2')
call AI.abilityBuild.registerLearnSkill('DEA1')
call AI.abilityBuild.registerLearnSkill('DEA4')
call AI.abilityBuild.registerLearnSkill('A041') //Perk
call AI.abilityBuild.registerLearnSkill('DEA2')
call AI.abilityBuild.registerLearnSkill('DEA1')
call AI.abilityBuild.registerLearnSkill('DEA3')
call AI.abilityBuild.registerLearnSkill('DEA4')
call AI.abilityBuild.registerLearnSkill('A03L') //Perk
call AI.abilityBuild.registerLearnSkill('DEA2')
call AI.abilityBuild.registerLearnSkill('DEA1')
call AI.abilityBuild.registerLearnSkill('DEA2')
call AI.abilityBuild.registerLearnSkill('DEA4')
call AI.abilityBuild.registerLearnSkill('A03T') //Perk
call AI.abilityBuild.registerLearnSkill('DEA3')
call AI.abilityBuild.registerLearnSkill('DEA3')
call AI.abilityBuild.registerLearnSkill('A0CJ') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'brag'
set AI.itemBuild.startItemID2 = 'ratf'
set AI.itemBuild.startItemR1 = 9
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('dust') //Shapire Boots 1
call AI.itemBuild.add('tmsc') //Arcanist't Rod 1
call AI.itemBuild.add('sclp') //Giant Stone Shield 1
call AI.itemBuild.add('tmsc') //Arcanist't Rod 2
call AI.itemBuild.add('sclp') //Giant Stone Shield 2
call AI.itemBuild.add('mort') //Bright Plate 1
call AI.itemBuild.add('tmsc') //Arcanist't Rod 3
call AI.itemBuild.add('sclp') //Giant Stone Shield 3
call AI.itemBuild.add('lhst') //Scythe of Souls 1
call AI.itemBuild.add('mort') //Bright Plate 2
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('mort') //Bright Plate 3
call AI.itemBuild.add('lhst') //Scythe of Souls 2
call AI.itemBuild.add('lhst') //Scythe of Souls 3
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('dust') //Shapire Boots 2
call AI.itemBuild.add('dust') //Shapire Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I03F'
set AI.itemBuild.enchantBuild.random2 = 'I04T'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I00P','sclp')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIDE.StartAI(HERO_AI,false)
call AIDE.createSkillBuild()
call AIDE.createUpgradeBuild()
call AIDE.createItemBuild()
call AIDE.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HDE1')
endfunction
endscope
scope AIDwarfRunner initializer init
globals
private integer array ABI_ID[3]
endglobals
struct AIDR extends array
static integer CUP = 0
static real time = 0
private static method SelectUpgrade takes unit u, boolean apc returns nothing
local integer ulvl = GetUpgradeSkillLevel(u,'DRI3')
call UnitRemoveAbility(u,ABI_ID[CUP])
if apc then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount and AI.enemyHeroCount != 0 and AI.percentLife > 0.75 then
set CUP = 2
call UnitAddAbility(u,ABI_ID[CUP])
call SetUnitAbilityLevel(u,ABI_ID[CUP],ulvl + 1)
call UnitMakeAbilityPermanent(u,true,ABI_ID[CUP])
if GetHeroMasteryType(u) == 2 then
call SetUnitData(u,"RF_AttackRate",60)
call BlzSetUnitAttackCooldown(u,1.8 - (0.10 + 0.10 * GetUnitAbilityLevel(u,'DRA3')) * 2,0)
else
call SetUnitData(u,"RF_AttackRate",30)
call BlzSetUnitAttackCooldown(u,1.8 - (0.10 + 0.10 * GetUnitAbilityLevel(u,'DRA3')),0)
endif
return
endif
endif
if AI.enemyHeroCount > AI.alliedHeroCount + 1 or AI.percentLife < 0.50 then
set CUP = 1
call UnitAddAbility(u,ABI_ID[CUP])
call SetUnitAbilityLevel(u,ABI_ID[CUP],ulvl + 1)
call UnitMakeAbilityPermanent(u,true,ABI_ID[CUP])
return
endif
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
set CUP = 0
call UnitAddAbility(u,ABI_ID[CUP])
call SetUnitAbilityLevel(u,ABI_ID[CUP],ulvl + 1)
call UnitMakeAbilityPermanent(u,true,ABI_ID[CUP])
call BlzSetUnitAttackCooldown(u,1.8,0)
return
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
set CUP = 1
call UnitAddAbility(u,ABI_ID[CUP])
call SetUnitAbilityLevel(u,ABI_ID[CUP],ulvl + 1)
call UnitMakeAbilityPermanent(u,true,ABI_ID[CUP])
return
endif
endmethod
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MURDERER_ID) == 0
local boolean apc = UnitHasBuff(u,APCanon.buff)
local Overheat b2 = GetUnitBuff(u,Overheat.buff).buffAllocIndex
local real a
local unit t
if traitCD and not AI.retreating and apc then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.enemyHeroCount != 0 then
if b2 == 0 then
call BlzUnitDisableAbility(u,'DRA2',false,false)
call IssueImmediateOrderById(u,ORDER_berserk)
call BlzUnitDisableAbility(u,'DRA2',true,false)
else
if b2.run then
if CUP != 1 then
if b2.count == 9 then
call BlzUnitDisableAbility(u,'DRA2',false,false)
call IssueImmediateOrderById(u,ORDER_berserk)
call BlzUnitDisableAbility(u,'DRA2',true,false)
endif
endif
else
if CUP == 1 then
call BlzUnitDisableAbility(u,'DRA2',false,false)
call IssueImmediateOrderById(u,ORDER_berserk)
call BlzUnitDisableAbility(u,'DRA2',true,false)
endif
endif
endif
else
if b2 != 0 then
if b2.run then
call BlzUnitDisableAbility(u,'DRA2',false,false)
call IssueImmediateOrderById(u,ORDER_berserk)
call BlzUnitDisableAbility(u,'DRA2',true,false)
endif
endif
endif
endif
if AI.enemyHeroCount > 0 then
if not a3.isOnCooldown() and a3.level != 0 then
call SelectUpgrade(u,apc)
call CooldownProcess(u,'DRA3')
endif
if not a4.isOnCooldown() and a4.level != 0 then
if GetRandomInt(1,100) <= 20 * AI.enemyHeroCount and AI.alliedHeroCount >= AI.enemyHeroCount then
if IssueImmediateOrderById(u,ORDER_curseoff) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 500 then
if IsUnitInSightOfUnit(u,AI.weakEnemy,22) then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if (AI.enemyUnitCount >= 4 or AI.goldUnit != null) and AI.enemyHeroCount == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.goldUnit != null then
set t = AI.goldUnit
else
set t = AI.weakUnit
endif
if DistanceBetweenUnits(u,t) <= 500 then
if IsUnitInSightOfUnit(u,t,22) then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set t = null
set u = null
return
endif
endif
endif
endif
endif
set t = null
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('DRA1')
call AI.abilityBuild.registerLearnSkill('DRA2')
call AI.abilityBuild.registerLearnSkill('DRA3')
call AI.abilityBuild.registerLearnSkill('DRA2')
call AI.abilityBuild.registerLearnSkill('DRA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('DRA3')
call AI.abilityBuild.registerLearnSkill('DRA2')
call AI.abilityBuild.registerLearnSkill('DRA3')
call AI.abilityBuild.registerLearnSkill('DRA4')
call AI.abilityBuild.registerLearnSkill('A0AW') //Perk
call AI.abilityBuild.registerLearnSkill('DRA2')
call AI.abilityBuild.registerLearnSkill('DRA3')
call AI.abilityBuild.registerLearnSkill('DRA1')
call AI.abilityBuild.registerLearnSkill('DRA4')
call AI.abilityBuild.registerLearnSkill('A03U') //Perk
call AI.abilityBuild.registerLearnSkill('DRA1')
call AI.abilityBuild.registerLearnSkill('DRA1')
call AI.abilityBuild.registerLearnSkill('A0AD') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'blba'
set AI.itemBuild.startItemR1 = 5
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('ciri') //Titan Staff 1
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('spsh') //Tidefury 1
call AI.itemBuild.add('spsh') //Tidefury 2
call AI.itemBuild.add('ckng') //Battle Insignia 1
call AI.itemBuild.add('ckng') //Battle Insignia 2
call AI.itemBuild.add('spsh') //Tidefury 3
call AI.itemBuild.add('sbch') //Engineer's Rifle 1
call AI.itemBuild.add('ciri') //Titan Staff 2
call AI.itemBuild.add('ckng') //Battle Insignia 3
call AI.itemBuild.add('sbch') //Engineer's Rifle 2
call AI.itemBuild.add('ciri') //Titan Staff 3
call AI.itemBuild.add('sbch') //Engineer's Rifle 3
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I00F'
set AI.itemBuild.enchantBuild.random2 = 'I031'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I036','spsh')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MURDERER_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIDR.StartAI(HERO_AI,false)
call AIDR.createSkillBuild()
call AIDR.createUpgradeBuild()
call AIDR.createItemBuild()
call AIDR.selectTrait()
set ABI_ID[0] = 'A0B9'
set ABI_ID[1] = 'A0BA'
set ABI_ID[2] = 'A0BB'
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HDR1')
endfunction
endscope
scope AITheHermit initializer init
struct AITH extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_HEAVEN_ID) == 0
local Buff b = GetUnitBuff(u,Burrow.buff)
local real x
local real y
local real a
if traitCD and ((AI.enemyHeroCount >= AI.alliedHeroCount + 1 and AI.percentLife <= 0.40) or AI.percentLife <= 0.20) then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if b != 0 then
if AI.enemyHeroCount >= 1 and AI.closestEnemyDistance <= 280 and b.elapsedTime >= 6.5 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.alliedHeroCount >= AI.enemyHeroCount and AI.enemyHeroCount != 0 or AI.goldUnit != null then
if IssueImmediateOrderById(u,ORDER_burrow) then
set AI.busyTimes = 1
set u = null
return
endif
else
if AI.enemyHeroCount == 1 and AI.percentLife <= 0.40 and AI.closestEnemyDistance <= 200 then
if IssueImmediateOrderById(u,ORDER_burrow) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.enemyHeroCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 then
if b != 0 then
if AI.closestEnemyDistance <= 550 then
if IssueImmediateOrderById(u,ORDER_curseoff) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if AI.closestEnemyDistance <= 250 then
if IssueImmediateOrderById(u,ORDER_curseoff) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if IsUnitMoving(AI.weakEnemy) then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
set a = GetUnitFacing(AI.weakEnemy) * bj_DEGTORAD
set x = x + 100.00 * Cos(a)
set y = y + 100.00 * Sin(a)
else
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
endif
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.percentLife <= 0.75 then
if IssueImmediateOrderById(u,ORDER_thunderclap) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if (AI.enemyUnitCount >= 4 or AI.goldUnit != null) and AI.enemyHeroCount == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.goldUnit != null then
set x = GetUnitX(AI.goldUnit)
set y = GetUnitY(AI.goldUnit)
else
set x = GetUnitX(AI.weakUnit)
set y = GetUnitY(AI.weakUnit)
endif
if IssuePointOrderById(u,ORDER_flamestrike,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('THA1')
call AI.abilityBuild.registerLearnSkill('THA2')
call AI.abilityBuild.registerLearnSkill('THA3')
call AI.abilityBuild.registerLearnSkill('THA1')
call AI.abilityBuild.registerLearnSkill('THA4')
call AI.abilityBuild.registerLearnSkill('A042') //Perk
call AI.abilityBuild.registerLearnSkill('THA3')
call AI.abilityBuild.registerLearnSkill('THA1')
call AI.abilityBuild.registerLearnSkill('THA3')
call AI.abilityBuild.registerLearnSkill('THA4')
call AI.abilityBuild.registerLearnSkill('A03L') //Perk
call AI.abilityBuild.registerLearnSkill('THA2')
call AI.abilityBuild.registerLearnSkill('THA1')
call AI.abilityBuild.registerLearnSkill('THA3')
call AI.abilityBuild.registerLearnSkill('THA4')
call AI.abilityBuild.registerLearnSkill('A03T') //Perk
call AI.abilityBuild.registerLearnSkill('THA2')
call AI.abilityBuild.registerLearnSkill('THA2')
call AI.abilityBuild.registerLearnSkill('A03O') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'brag'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 5
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('wswd') //Traveler Boots 1
call AI.itemBuild.add('shar') //Chaos Ring 1
call AI.itemBuild.add('wswd') //Traveler Boots 2
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('sand') //Heretic's Ring 1
call AI.itemBuild.add('shar') //Chaos Ring 2
call AI.itemBuild.add('ciri') //Titan Staff 1
call AI.itemBuild.add('shar') //Chaos Ring 3
call AI.itemBuild.add('ciri') //Titan Staff 2
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('sand') //Heretic's Ring 1
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('rde3') //Magic Emblem 1
call AI.itemBuild.add('ciri') //Titan Staff 3
call AI.itemBuild.add('sand') //Heretic's Ring 1
call AI.itemBuild.add('rde3') //Magic Emblem 2
call AI.itemBuild.add('rde3') //Magic Emblem 3
call AI.itemBuild.add('wswd') //Traveler Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I033'
set AI.itemBuild.enchantBuild.random2 = 'I04V'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02U','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_HEAVEN_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AITH.StartAI(HERO_AI,false)
call AITH.createSkillBuild()
call AITH.createUpgradeBuild()
call AITH.createItemBuild()
call AITH.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HTH1')
endfunction
endscope
scope AIOgreSorcerer initializer init
struct AIOS extends array
static real sbcd = 0
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a2a = AI.playerHero.Abilities.integer[5]
local Ability a2b = AI.playerHero.Abilities.integer[6]
local Ability a2c = AI.playerHero.Abilities.integer[7]
local Ability a1 = AI.playerHero.Abilities.integer[2]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local real x
local real y
local real a
local integer i
if sbcd != 0 then
set sbcd = sbcd - 0.50
if sbcd < 0 then
set sbcd = 0
endif
endif
if AI.enemyHeroCount > 0 or AI.goldUnit != null or AI.enemyUnitCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 then
if not UnitHasBuff(u,Bloodlust.buff) then
if IssueTargetOrderById(u,ORDER_thunderbolt,u) then
set AI.busyTimes = 1
set u = null
return
endif
elseif AI.threatAlly != null then
if DistanceBetweenUnits(u,AI.threatAlly) <= 600 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.threatAlly) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.enemyHeroCount > 0 then
if traitCD then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.threatEnemy) <= 300 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.threatEnemy),GetUnitY(AI.threatEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.weakEnemy) <= 900 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
set i = GetRandomInt(1,3)
if i == 1 then
if not a2a.isOnCooldown() and a2a.level != 0 and sbcd == 0 then
if IssuePointOrderById(u,ORDER_rainoffire,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set sbcd = a2a.finalCooldown
set AI.busyTimes = 1
set u = null
return
endif
endif
elseif i == 2 then
if not a2b.isOnCooldown() and a2b.level != 0 and sbcd == 0 then
if AI.closestEnemyDistance <= 200 and AI.closestEnemyHero != null then
if IssueImmediateOrderById(u,ORDER_stomp) then
set sbcd = a2b.finalCooldown
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
elseif i == 3 then
if not a2c.isOnCooldown() and a2c.level != 0 and sbcd == 0 then
if AI.enemyHeroCount >= 2 then
if IssuePointOrderById(u,ORDER_earthquake,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set sbcd = a2c.finalCooldown
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
set x = DistanceBetweenUnits(AI.goldUnit,u)
if not a1.isOnCooldown() and a1.level != 0 and x <= 300 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if not a2c.isOnCooldown() and a2c.level != 0 and sbcd == 0 and x <= 300 then
if IssuePointOrderById(u,ORDER_earthquake,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set sbcd = a2c.finalCooldown
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyUnitCount >= 4 and AI.enemyHeroCount == 0 then
if not a2a.isOnCooldown() and a2a.level != 0 and sbcd == 0 then
if IssuePointOrderById(u,ORDER_rainoffire,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set sbcd = a2a.finalCooldown
set AI.busyTimes = 1
set u = null
return
endif
endif
if not a2b.isOnCooldown() and a2b.level != 0 and sbcd == 0 then
if DistanceBetweenUnits(u,AI.weakUnit) <= 250 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set sbcd = a2b.finalCooldown
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('OSA1')
call AI.abilityBuild.registerLearnSkill('OSA2')
call AI.abilityBuild.registerLearnSkill('OSA3')
call AI.abilityBuild.registerLearnSkill('OSA2')
call AI.abilityBuild.registerLearnSkill('OSA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('OSA3')
call AI.abilityBuild.registerLearnSkill('OSA2')
call AI.abilityBuild.registerLearnSkill('OSA2')
call AI.abilityBuild.registerLearnSkill('OSA4')
call AI.abilityBuild.registerLearnSkill('A0AW') //Perk
call AI.abilityBuild.registerLearnSkill('OSA3')
call AI.abilityBuild.registerLearnSkill('OSA1')
call AI.abilityBuild.registerLearnSkill('OSA3')
call AI.abilityBuild.registerLearnSkill('OSA4')
call AI.abilityBuild.registerLearnSkill('A03R') //Perk
call AI.abilityBuild.registerLearnSkill('OSA1')
call AI.abilityBuild.registerLearnSkill('OSA1')
call AI.abilityBuild.registerLearnSkill('A0AE') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'vddl'
set AI.itemBuild.startItemR1 = 8
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('wswd') //Traveler Boots 1
call AI.itemBuild.add('tmsc') //Arcanist Rood 1
call AI.itemBuild.add('wswd') //Traveler Boots 2
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('tmsc') //Arcanist Rood 2
call AI.itemBuild.add('rde3') //Magic Emblem 1
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('mnst') //Orb of Imbued Magic 1
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('pres') //Voodoo Cane 1
call AI.itemBuild.add('rde3') //Magic Emblem 2
call AI.itemBuild.add('tmsc') //Arcanist Rood 3
call AI.itemBuild.add('mnst') //Orb of Imbued Magic 2
call AI.itemBuild.add('rde3') //Magic Emblem 3
call AI.itemBuild.add('pres') //Voodoo Cane 2
call AI.itemBuild.add('mnst') //Orb of Imbued Magic 3
call AI.itemBuild.add('pres') //Voodoo Cane 3
call AI.itemBuild.add('wswd') //Traveler Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I00F'
set AI.itemBuild.enchantBuild.random2 = 'I00G'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02Y','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIOS.StartAI(HERO_AI,false)
call AIOS.createSkillBuild()
call AIOS.createUpgradeBuild()
call AIOS.createItemBuild()
call AIOS.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HOS1')
endfunction
endscope
scope AIShadowCrawler initializer init
struct AISW extends array
static integer Rdelay = 0
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local real x
local real y
local real a
local real d
if Rdelay != 0 then
set Rdelay = Rdelay - 1
endif
if AI.enemyHeroCount > 0 then
if traitCD then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if GetHeroMasteryType(u) == 1 then
if not AI.danger then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 500 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if AI.closestEnemyDistance <= 200 and AI.percentLife <= 0.30 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.closestEnemyHero),GetUnitY(AI.closestEnemyHero)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.returnToBase then
set a = GetUnitFacing(u)
set x = AI.hx + 300 * Cos(a)
set y = AI.hy + 300 * Sin(a)
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
else
if not AI.danger then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 500 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if AI.closestEnemyDistance <= 200 and AI.percentLife <= 0.30 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.closestEnemyHero) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
if not a4.isOnCooldown() and a4.level != 0 and Rdelay == 0 then
set x = GetUnitX(AI.weakEnemy)
set y = GetUnitY(AI.weakEnemy)
set a = Angle(AI.hx,AI.hy,x,y)
set d = Distance(AI.hx,AI.hy,x,y)
if AI.weakEnemyHp <= 0.20 and d <= 250 + 100 * a4.level and d > 100 then
if IsUnitMoving(AI.weakEnemy) then
set x = x + 150 * Cos(a)
set y = y + 150 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set Rdelay = 2
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if GetRandomInt(1,100) <= 15 and a4.currentCharges > 1 and d > 150 then
if d <= 200 + 100 * a4.level then
if IsUnitMoving(AI.weakEnemy) then
set x = x + 200 * Cos(a)
set y = y + 200 * Sin(a)
endif
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set Rdelay = 2
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.percentLife <= 0.50 and AI.enemyHeroCount > AI.alliedHeroCount + 1 then
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
set x = GetUnitX(u) + 400 * Cos(a)
set y = GetUnitY(u) + 400 * Sin(a)
if IssuePointOrderById(u,ORDER_shockwave,x,y) then
set Rdelay = 2
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
set x = DistanceBetweenUnits(AI.goldUnit,u)
if not a1.isOnCooldown() and a1.level != 0 and x <= 300 and AI.percentLife <= 0.50 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
/*if AI.enemyUnitCount >= 4 and AI.enemyHeroCount == 0 then
if not a2a.isOnCooldown() and a2a.level != 0 and sbcd == 0 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set sbcd = a2a.finalCooldown
set AI.channelingOrder = ORDER_flamestrike
set u = null
return
endif
endif
endif*/
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('SWA3')
call AI.abilityBuild.registerLearnSkill('SWA1')
call AI.abilityBuild.registerLearnSkill('SWA2')
call AI.abilityBuild.registerLearnSkill('SWA1')
call AI.abilityBuild.registerLearnSkill('SWA4')
call AI.abilityBuild.registerLearnSkill('A034') //Perk
call AI.abilityBuild.registerLearnSkill('SWA3')
call AI.abilityBuild.registerLearnSkill('SWA2')
call AI.abilityBuild.registerLearnSkill('SWA3')
call AI.abilityBuild.registerLearnSkill('SWA4')
call AI.abilityBuild.registerLearnSkill('A03J') //Perk
call AI.abilityBuild.registerLearnSkill('SWA1')
call AI.abilityBuild.registerLearnSkill('SWA2')
call AI.abilityBuild.registerLearnSkill('SWA2')
call AI.abilityBuild.registerLearnSkill('SWA4')
call AI.abilityBuild.registerLearnSkill('A03U') //Perk
call AI.abilityBuild.registerLearnSkill('SWA3')
call AI.abilityBuild.registerLearnSkill('SWA1')
call AI.abilityBuild.registerLearnSkill('A0CH') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'will'
set AI.itemBuild.startItemR1 = 6
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('rwiz') //BlackMace 1
call AI.itemBuild.add('stel') //Sun Daggers 1
call AI.itemBuild.add('rwiz') //BlackMace 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('wlsd') //Scourge Bone Chimes 1
call AI.itemBuild.add('engs') //Defiled Gem 1
call AI.itemBuild.add('stel') //Sun Daggers 2
call AI.itemBuild.add('wlsd') //Scourge Bone Chimes 2
call AI.itemBuild.add('bzbf') //Dragonhide Jacket 1
call AI.itemBuild.add('rwiz') //BlackMace 3
call AI.itemBuild.add('engs') //Defiled Gem 2
call AI.itemBuild.add('stel') //Sun Daggers 3
call AI.itemBuild.add('engs') //Defiled Gem 3
call AI.itemBuild.add('bzbf') //Dragonhide Jacket 2
call AI.itemBuild.add('wlsd') //Scourge Bone Chimes 3
call AI.itemBuild.add('bzbf') //Dragonhide Jacket 3
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I03D'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I03A','rwiz')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02Y','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AISW.StartAI(HERO_AI,false)
call AISW.createSkillBuild()
call AISW.createUpgradeBuild()
call AISW.createItemBuild()
call AISW.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HSW1')
endfunction
endscope
scope AIAxeMaster initializer init
struct AIAM extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MURDERER_ID) == 0
local real x
local real y
local real a
local real d
if AI.enemyHeroCount > 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if AI.enemyHeroCount >= 2 and AI.enemyHeroCount > AI.alliedHeroCount + 1 then
if DistanceBetweenUnits(u,AI.threatEnemy) <= 600 + 100 * a1.level then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.threatEnemy),GetUnitY(AI.threatEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 + 100 * a1.level and not IsUnitMoving(AI.weakEnemy) then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.closestEnemyDistance <= 200 and not AI.danger then
call BlzUnitDisableAbility(u,'AMA2',false,false)
if IssueImmediateOrderById(u,ORDER_manashieldon) then
call BlzUnitDisableAbility(u,'AMA2',true,false)
set u = null
return
else
call BlzUnitDisableAbility(u,'AMA2',true,false)
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount and AI.enemyHeroCount >= AI.team.playerCount/2 then
call BlzUnitDisableAbility(u,'AMA4',false,false)
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'AMA4',true,false)
set u = null
return
else
call BlzUnitDisableAbility(u,'AMA4',true,false)
endif
endif
if AI.percentLife <= 0.20 then
call BlzUnitDisableAbility(u,'AMA4',false,false)
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'AMA4',true,false)
set u = null
return
else
call BlzUnitDisableAbility(u,'AMA4',true,false)
endif
endif
if AI.weakEnemyHp <= 0.20 and AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
call BlzUnitDisableAbility(u,'AMA4',false,false)
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'AMA4',true,false)
set u = null
return
else
call BlzUnitDisableAbility(u,'AMA4',true,false)
endif
endif
endif
if traitCD and not AI.returnToBase and AI.weakEnemyHp <= 0.50 and not AI.danger then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
set x = DistanceBetweenUnits(AI.goldUnit,u)
if not a1.isOnCooldown() and a1.level != 0 and x <= 200 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyUnitCount > 0 and AI.enemyHeroCount == 0 then
if not a2.isOnCooldown() and a2.level != 0 then
if not AI.retreating and AI.enemyUnitCount >= 4 and DistanceBetweenUnits(u,AI.weakUnit) <= 200 then
call BlzUnitDisableAbility(u,'AMA2',false,false)
if IssueImmediateOrderById(u,ORDER_manashieldon) then
call BlzUnitDisableAbility(u,'AMA2',true,false)
set u = null
return
else
call BlzUnitDisableAbility(u,'AMA2',true,false)
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('AMA1')
call AI.abilityBuild.registerLearnSkill('AMA2')
call AI.abilityBuild.registerLearnSkill('AMA3')
call AI.abilityBuild.registerLearnSkill('AMA3')
call AI.abilityBuild.registerLearnSkill('AMA4')
call AI.abilityBuild.registerLearnSkill('A033') //Perk
call AI.abilityBuild.registerLearnSkill('AMA2')
call AI.abilityBuild.registerLearnSkill('AMA3')
call AI.abilityBuild.registerLearnSkill('AMA2')
call AI.abilityBuild.registerLearnSkill('AMA4')
call AI.abilityBuild.registerLearnSkill('A03N') //Perk
call AI.abilityBuild.registerLearnSkill('AMA1')
call AI.abilityBuild.registerLearnSkill('AMA2')
call AI.abilityBuild.registerLearnSkill('AMA3')
call AI.abilityBuild.registerLearnSkill('AMA4')
call AI.abilityBuild.registerLearnSkill('A03U') //Perk
call AI.abilityBuild.registerLearnSkill('AMA1')
call AI.abilityBuild.registerLearnSkill('AMA1')
call AI.abilityBuild.registerLearnSkill('A0AC') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'amrc'
set AI.itemBuild.startItemID2 = 'blba'
set AI.itemBuild.startItemR1 = 5
set AI.itemBuild.startItemR2 = 8
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('rwiz') //BlackMace 1
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('ckng') //Battle Insignia 1
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
call AI.itemBuild.add('bgst') //Executioner 1
call AI.itemBuild.add('rwiz') //BlackMace 2
call AI.itemBuild.add('pnvu') //Spider Broach 1
call AI.itemBuild.add('rwiz') //BlackMace 3
call AI.itemBuild.add('ckng') //Battle Insignia 2
call AI.itemBuild.add('bgst') //Executioner 2
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('ckng') //Battle Insignia 3
call AI.itemBuild.add('bgst') //Executioner 3
call AI.itemBuild.add('pnvu') //Spider Broach 2
call AI.itemBuild.add('pnvu') //Spider Broach 3
set AI.itemBuild.enchantBuild.random1 = 'I00K'
set AI.itemBuild.enchantBuild.random2 = 'I031'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I035','rwiz')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02Y','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MURDERER_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIAM.StartAI(HERO_AI,false)
call AIAM.createSkillBuild()
call AIAM.createUpgradeBuild()
call AIAM.createItemBuild()
call AIAM.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HAM1')
endfunction
endscope
scope AIFireReaver initializer init
struct AIFI extends array
static boolean Wactivated = false
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local real x
local real y
local real a
if AI.enemyHeroCount > 0 then
if traitCD then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if not AI.danger then
if AI.enemyHeroCount >= 2 or AI.weakEnemyHp <= 0.35 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 500 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
else
if AI.closestEnemyDistance <= 500 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if a2.level != 0 then
if not Wactivated then
set Wactivated = true
call BlzUnitDisableAbility(u,'FIA2',false,false)
call IssueImmediateOrderById(u,ORDER_poisonarrows)
call UnitAddBuff(u,u,999999,BurningAttacksBonuses.buff,0,0)
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if IssueTargetOrderById(u,ORDER_manaburn,u) then
set AI.busyTimes = 1
set u = null
return
endif
else
if AI.alliedHeroCount > 0 then
if DistanceBetweenUnits(u,AI.threatAlly) <= 600 then
if IssueTargetOrderById(u,ORDER_manaburn,AI.threatAlly) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if UnitHasBuff(u,MoltenShield.buff) then
if AI.weakEnemyHp <= 0.40 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if AI.weakEnemyHp <= 0.25 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
else
if Wactivated then
set Wactivated = false
call BlzUnitDisableAbility(u,'FIA2',true,false)
call IssueImmediateOrderById(u,ORDER_unpoisonarrows)
call UnitRemoveBuff(u,BurningAttacksBonuses.buff)
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
set x = DistanceBetweenUnits(AI.goldUnit,u)
if not a1.isOnCooldown() and a1.level != 0 and x <= 200 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyUnitCount > 0 and AI.enemyHeroCount == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if not AI.retreating and AI.enemyUnitCount >= 4 then
set x = DistanceBetweenUnits(AI.weakUnit,u)
if x <= 300 then
if IssueImmediateOrderById(u,ORDER_stomp) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('FIA1')
call AI.abilityBuild.registerLearnSkill('FIA2')
call AI.abilityBuild.registerLearnSkill('FIA3')
call AI.abilityBuild.registerLearnSkill('FIA1')
call AI.abilityBuild.registerLearnSkill('FIA4')
call AI.abilityBuild.registerLearnSkill('A032') //Perk
call AI.abilityBuild.registerLearnSkill('FIA3')
call AI.abilityBuild.registerLearnSkill('FIA1')
call AI.abilityBuild.registerLearnSkill('FIA3')
call AI.abilityBuild.registerLearnSkill('FIA4')
call AI.abilityBuild.registerLearnSkill('A03M') //Perk
call AI.abilityBuild.registerLearnSkill('FIA2')
call AI.abilityBuild.registerLearnSkill('FIA2')
call AI.abilityBuild.registerLearnSkill('FIA1')
call AI.abilityBuild.registerLearnSkill('FIA4')
call AI.abilityBuild.registerLearnSkill('A03R') //Perk
call AI.abilityBuild.registerLearnSkill('FIA2')
call AI.abilityBuild.registerLearnSkill('FIA3')
call AI.abilityBuild.registerLearnSkill('A0CH') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'arsh'
set AI.itemBuild.startItemR1 = 7
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('modt') //Beer Barrel 1
call AI.itemBuild.add('gopr') //Runic Bracers 1
call AI.itemBuild.add('tmsc') //Arcanist Rod 1
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('tmsc') //Arcanist Rod 2
call AI.itemBuild.add('infs') //Fel Staff 1
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('gopr') //Runic Bracers 2
call AI.itemBuild.add('pres') //Voodoo Cane 1
call AI.itemBuild.add('tmsc') //Arcanist Rod 3
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('modt') //Beer Barrel 2
call AI.itemBuild.add('gopr') //Runic Bracers 3
call AI.itemBuild.add('pres') //Voodoo Cane 3
call AI.itemBuild.add('modt') //Beer Barrel 3
call AI.itemBuild.add('infs') //Fel Staff 2
call AI.itemBuild.add('infs') //Fel Staff 3
set AI.itemBuild.enchantBuild.random1 = 'I04Q'
set AI.itemBuild.enchantBuild.random2 = 'I04S'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I00O','tmsc')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02Y','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIFI.StartAI(HERO_AI,false)
call AIFI.createSkillBuild()
call AIFI.createUpgradeBuild()
call AIFI.createItemBuild()
call AIFI.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HFI1')
endfunction
endscope
scope AIWarden initializer init
struct AIWD extends array
static unit RTarget = null
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_FLASH_ID) == 0
local Sharpstorm b = GetUnitBuff(u,Sharpstorm.buff).buffAllocIndex
local real x
local real y
local real a
if AI.enemyHeroCount > 0 then
if traitCD then
if AI.percentLife <= 0.50 and AI.enemyHeroCount >= AI.alliedHeroCount then
if AI.returnToBase then
set a = Angle(AI.hx,AI.hy,AI.team.startX,AI.team.startY)
else
set a = Angle(AI.hx,AI.hy,AI.retreatX,AI.retreatY)
endif
set x = AI.hx + 390 * Cos(a)
set y = AI.hy + 390 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if AI.weakEnemyHp <= 0.25 and AI.enemyHeroCount <= AI.alliedHeroCount and AI.percentLife <= 0.40 then
set a = AngleBetweenUnits(u,AI.weakEnemy)
set x = AI.hx + 380 * Cos(a)
set y = AI.hy + 380 * Sin(a)
if IssuePointOrderById(u,ORDER_monsoon,x,y) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if b != 0 then
if AI.closestEnemyDistance <= 300 and AI.alliedHeroCount + 1 >= AI.enemyHeroCount and b.mode == 1 then
if IssueImmediateOrderById(u,ORDER_manashieldon) then
set u = null
return
endif
endif
if AI.enemyHeroCount == 1 and AI.closestEnemyDistance <= 150 and b.mode == 2 then
if IssueImmediateOrderById(u,ORDER_manashieldon) then
set u = null
return
endif
endif
if AI.enemyHeroCount > AI.alliedHeroCount and AI.returnToBase and b.mode == 1 then
if IssueImmediateOrderById(u,ORDER_manashieldon) then
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if not AI.danger then
if AI.closestEnemyDistance <= 250 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.enemyHeroCount >= 2 and AI.closestEnemyDistance <= 400 then
if IssueImmediateOrderById(u,ORDER_fanofknives) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if DistanceBetweenUnits(u,AI.weakEnemy) <= 500.00 and AI.weakEnemyHp <= 0.25 then
if IssueImmediateOrderById(u,ORDER_fanofknives) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if AI.percentLife >= 0.25 and DistanceBetweenUnits(u,AI.weakEnemy) <= 300.00 then
if IssueTargetOrderById(u,ORDER_thunderbolt,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if GetUnitData(u,"FW_Buff") != 0 then
set AI.riskAction = true
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
set x = DistanceBetweenUnits(AI.goldUnit,u)
if not a1.isOnCooldown() and a1.level != 0 and x <= 150 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
if AI.enemyUnitCount > 0 and AI.enemyHeroCount == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if not AI.retreating and AI.enemyUnitCount >= 4 then
set x = DistanceBetweenUnits(AI.weakUnit,u)
if x <= 150 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 then
if GetRandomInt(1,100) <= 5 * AI.enemyUnitCount then
set x = DistanceBetweenUnits(AI.weakUnit,u)
if x <= 300 then
if IssueImmediateOrderById(u,ORDER_fanofknives) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('WDA1')
call AI.abilityBuild.registerLearnSkill('WDA2')
call AI.abilityBuild.registerLearnSkill('WDA3')
call AI.abilityBuild.registerLearnSkill('WDA2')
call AI.abilityBuild.registerLearnSkill('WDA4')
call AI.abilityBuild.registerLearnSkill('A034') //Perk
call AI.abilityBuild.registerLearnSkill('WDA3')
call AI.abilityBuild.registerLearnSkill('WDA2')
call AI.abilityBuild.registerLearnSkill('WDA2')
call AI.abilityBuild.registerLearnSkill('WDA4')
call AI.abilityBuild.registerLearnSkill('A03J') //Perk
call AI.abilityBuild.registerLearnSkill('WDA3')
call AI.abilityBuild.registerLearnSkill('WDA1')
call AI.abilityBuild.registerLearnSkill('WDA1')
call AI.abilityBuild.registerLearnSkill('WDA4')
call AI.abilityBuild.registerLearnSkill('A03U') //Perk
call AI.abilityBuild.registerLearnSkill('WDA3')
call AI.abilityBuild.registerLearnSkill('WDA1')
call AI.abilityBuild.registerLearnSkill('A0AC') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'blba'
set AI.itemBuild.startItemID2 = 'will'
set AI.itemBuild.startItemR1 = 5
set AI.itemBuild.startItemR2 = 7
call AI.itemBuild.add('fgdg') //Dynamic Boots 1
call AI.itemBuild.add('ajen') //Tempest Hammer 1
call AI.itemBuild.add('fgdg') //Dynamic Boots 2
call AI.itemBuild.add('ajen') //Tempest Hammer 2
call AI.itemBuild.add('rat9') //Lightning Razor 1
call AI.itemBuild.add('ajen') //Tempest Hammer 3
call AI.itemBuild.add('desc') //Gargoyle Fangs 1
call AI.itemBuild.add('stel') //Sun Daggers 1
call AI.itemBuild.add('stel') //Sun Daggers 2
call AI.itemBuild.add('rat9') //Lightning Razor 2
call AI.itemBuild.add('engs') //Defiled Helm 1
call AI.itemBuild.add('stel') //Sun Daggers 3
call AI.itemBuild.add('desc') //Gargoyle Fangs 2
call AI.itemBuild.add('fgdg') //Dynamic Boots 3
call AI.itemBuild.add('rat9') //Lightning Razor 3
call AI.itemBuild.add('engs') //Defiled Helm 2
call AI.itemBuild.add('desc') //Gargoyle Fangs 3
call AI.itemBuild.add('engs') //Defiled Helm 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I00D'
call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('I035','ajen')
//call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02Y','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_FLASH_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIWD.StartAI(HERO_AI,false)
call AIWD.createSkillBuild()
call AIWD.createUpgradeBuild()
call AIWD.createItemBuild()
call AIWD.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HWD1')
endfunction
endscope
scope AIIronAssembly initializer init
struct AIIA extends array
static boolean RActivated = false
public static method RavagerWheelSecondCast takes unit u returns nothing
if BlzGetUnitAbilityCooldownRemaining(u,'A02B') == 0 then
if AI.enemyHeroCount != 0 then
if IssuePointOrderById(u,ORDER_areadetection,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
return
endif
endif
if AI.enemyHeroCount == 0 and AI.goldUnit != null then
if IssuePointOrderById(u,ORDER_areadetection,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
return
endif
endif
if AI.enemyUnitCount != 0 then
if IssuePointOrderById(u,ORDER_areadetection,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
return
endif
endif
endif
endmethod
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local integer op = GetUnitData(u,"DS_option")
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_TITAN_ID) == 0
local Buff b2 = GetUnitBuff(u,PlatinumAlloy.buff)
local real x
local real y
local real a
if RActivated then
if traitCD and b2 == 0 and a3.isOnCooldown() then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
else
if traitCD and b2 == 0 and a3.isOnCooldown() and AI.percentLife <= 0.25 and AI.enemyHeroCount != 0 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if b2 != 0 then
set AI.riskAction = true
endif
if AI.enemyHeroCount > 0 then
if not a3.isOnCooldown() and a3.level != 0 then
if RActivated and AI.percentLife <= 0.50 then
if IssueImmediateOrderById(u,ORDER_howlofterror) then
set AI.busyTimes = 1
set u = null
return
endif
else
if AI.percentLife <= 0.25 then
if IssueImmediateOrderById(u,ORDER_howlofterror) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 800 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if AI.percentLife < 0.50 and op == 1 then
call SetUnitData(u,"DS_option",2)
elseif op == 2 and (AI.riskAction or b2 != 0) then
call SetUnitData(u,"DS_option",1)
endif
if AI.closestEnemyDistance <= 250 then
if IssueImmediateOrderById(u,ORDER_thunderclap) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if not a3.isOnCooldown() then
if AI.closestEnemyDistance <= 300 then
call BlzUnitDisableAbility(u,'IAA4',false,false)
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'IAA4',true,false)
set RActivated = true
set u = null
return
else
call BlzUnitDisableAbility(u,'IAA4',true,false)
endif
endif
else
if AI.percentLife >= 0.75 and AI.alliedHeroCount + 1 >= AI.enemyHeroCount and AI.closestEnemyDistance <= 300 then
call BlzUnitDisableAbility(u,'IAA4',false,false)
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'IAA4',true,false)
set RActivated = true
set u = null
return
else
call BlzUnitDisableAbility(u,'IAA4',true,false)
endif
endif
endif
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
set x = DistanceBetweenUnits(AI.goldUnit,u)
if not a1.isOnCooldown() and a1.level != 0 and x <= 600 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyUnitCount > 0 and AI.enemyHeroCount == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if not AI.retreating and AI.enemyUnitCount >= 4 then
set x = DistanceBetweenUnits(AI.weakUnit,u)
if x <= 500 then
if IssuePointOrderById(u,ORDER_shockwave,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('IAA1')
call AI.abilityBuild.registerLearnSkill('IAA2')
call AI.abilityBuild.registerLearnSkill('IAA3')
call AI.abilityBuild.registerLearnSkill('IAA1')
call AI.abilityBuild.registerLearnSkill('IAA4')
call AI.abilityBuild.registerLearnSkill('A042') //Perk
call AI.abilityBuild.registerLearnSkill('IAA3')
call AI.abilityBuild.registerLearnSkill('IAA1')
call AI.abilityBuild.registerLearnSkill('IAA2')
call AI.abilityBuild.registerLearnSkill('IAA4')
call AI.abilityBuild.registerLearnSkill('A0AW') //Perk
call AI.abilityBuild.registerLearnSkill('IAA3')
call AI.abilityBuild.registerLearnSkill('IAA1')
call AI.abilityBuild.registerLearnSkill('IAA2')
call AI.abilityBuild.registerLearnSkill('IAA4')
call AI.abilityBuild.registerLearnSkill('A007') //Perk
call AI.abilityBuild.registerLearnSkill('IAA3')
call AI.abilityBuild.registerLearnSkill('IAA2')
call AI.abilityBuild.registerLearnSkill('A0CJ') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'vddl'
set AI.itemBuild.startItemID2 = 'ratf'
set AI.itemBuild.startItemR1 = 5
set AI.itemBuild.startItemR2 = 6
call AI.itemBuild.add('dust') //Shapphire Boots 1
call AI.itemBuild.add('phlt') //Kraken Shell 1
call AI.itemBuild.add('tkno') //Earth Idol 1
call AI.itemBuild.add('phlt') //Kraken Shell 2
call AI.itemBuild.add('kymn') //Titanic Shoulders 1
call AI.itemBuild.add('bzbe') //Blessed Steel 1
call AI.itemBuild.add('tkno') //Earth Idol 2
call AI.itemBuild.add('fgrg') //Gravewalker Heart 1
call AI.itemBuild.add('phlt') //Kraken Shell 3
call AI.itemBuild.add('dust') //Shapphire Boots 2
call AI.itemBuild.add('tkno') //Earth Idol 3
call AI.itemBuild.add('bzbe') //Blessed Steel 2
call AI.itemBuild.add('dust') //Shapphire Boots 3
call AI.itemBuild.add('bzbe') //Blessed Steel 3
call AI.itemBuild.add('kymn') //Titanic Shoulders 2
call AI.itemBuild.add('fgrg') //Gravewalker Heart 2
call AI.itemBuild.add('kymn') //Titanic Shoulders 3
call AI.itemBuild.add('fgrg') //Gravewalker Heart 3
set AI.itemBuild.enchantBuild.random1 = 'I04U'
set AI.itemBuild.enchantBuild.random2 = 'I04U'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('','')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I02Z','phlt')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_TITAN_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIIA.StartAI(HERO_AI,false)
call AIIA.createSkillBuild()
call AIIA.createUpgradeBuild()
call AIIA.createItemBuild()
call AIIA.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HIA1')
endfunction
endscope
scope AIMindbender initializer init
struct AIMB extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MIND_ID) == 0
local Levitate b = GetUnitBuff(u,Levitate.buff).buffAllocIndex
local integer wc = a2.currentCharges
local integer o = GetUnitCurrentOrder(u)
local boolean c = o == ORDER_move or o == ORDER_attack
local real x
local real y
local real a
if AI.enemyHeroCount > 0 then
if not a4.isOnCooldown() and a4.level != 0 and c then
if AI.alliedHeroCount + 1 >= AI.enemyHeroCount then
if IssueImmediateOrderById(u,ORDER_thunderclap) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a3.isOnCooldown() and a3.level != 0 and c then
if AI.enemyHeroCount >= 1 then
call BlzUnitDisableAbility(u,'MBA3',false,false)
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'MBA3',true,false)
set u = null
return
else
call BlzUnitDisableAbility(u,'MBA3',true,false)
endif
endif
endif
if traitCD then
if AI.enemyHeroCount >= 2 then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 and c then
if DistanceBetweenUnits(u,AI.weakEnemy) <= 600 then
if IssuePointOrderById(u,ORDER_carrionswarm,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 and wc > 0 and c then
if UnitHasBuff(u,ArcaneOverload.buff) then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
elseif not AI.returnToBase then
if GetRandomInt(1,100) <= 10 then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if GetRandomInt(1,100) <= 10 then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.threatEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 and c then
set x = DistanceBetweenUnits(AI.goldUnit,u)
if not a1.isOnCooldown() and a1.level != 0 and x <= 200 then
if IssuePointOrderById(u,ORDER_carrionswarm,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if GetRandomInt(1,100) <= 10 then
if IssueTargetOrderById(u,ORDER_shadowstrike,AI.goldUnit) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.enemyUnitCount > 0 and AI.enemyHeroCount == 0 and c then
if not a1.isOnCooldown() and a1.level != 0 then
if not AI.retreating and AI.enemyUnitCount >= 4 then
set x = DistanceBetweenUnits(AI.weakUnit,u)
if x <= 300 then
if IssuePointOrderById(u,ORDER_carrionswarm,GetUnitX(AI.weakUnit),GetUnitY(AI.weakUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('MBA1')
call AI.abilityBuild.registerLearnSkill('MBA2')
call AI.abilityBuild.registerLearnSkill('MBA3')
call AI.abilityBuild.registerLearnSkill('MBA2')
call AI.abilityBuild.registerLearnSkill('MBA4')
call AI.abilityBuild.registerLearnSkill('A032') //Perk
call AI.abilityBuild.registerLearnSkill('MBA1')
call AI.abilityBuild.registerLearnSkill('MBA2')
call AI.abilityBuild.registerLearnSkill('MBA1')
call AI.abilityBuild.registerLearnSkill('MBA4')
call AI.abilityBuild.registerLearnSkill('A03M') //Perk
call AI.abilityBuild.registerLearnSkill('MBA1')
call AI.abilityBuild.registerLearnSkill('MBA2')
call AI.abilityBuild.registerLearnSkill('MBA3')
call AI.abilityBuild.registerLearnSkill('MBA4')
call AI.abilityBuild.registerLearnSkill('A03R') //Perk
call AI.abilityBuild.registerLearnSkill('MBA3')
call AI.abilityBuild.registerLearnSkill('MBA3')
call AI.abilityBuild.registerLearnSkill('A0CJ') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'brag'
set AI.itemBuild.startItemR1 = 8
set AI.itemBuild.startItemR2 = 5
call AI.itemBuild.add('tmsc') //Arcanist Rood 1
call AI.itemBuild.add('I00C') //Swift Treads 1
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('tmsc') //Arcanist Rood 2
call AI.itemBuild.add('I00A') //Witch's Relic 1
call AI.itemBuild.add('I00A') //Witch's Relic 2
call AI.itemBuild.add('tmsc') //Arcanist Rood 3
call AI.itemBuild.add('rde3') //Magic Emblem 1
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('pres') //Voodoo Cane 1
call AI.itemBuild.add('rde3') //Magic Emblem 2
call AI.itemBuild.add('I00A') //Witch's Relic 3
call AI.itemBuild.add('pres') //Voooo Cane 2
call AI.itemBuild.add('pres') //Voodoo Cane 3
call AI.itemBuild.add('rde3') //Magic Emblem 3
call AI.itemBuild.add('I00C') //Swift Treads 2
call AI.itemBuild.add('I00C') //Swift Treads 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I00F'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('','')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I030','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MIND_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AIMB.StartAI(HERO_AI,false)
call AIMB.createSkillBuild()
call AIMB.createUpgradeBuild()
call AIMB.createItemBuild()
call AIMB.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HMB1')
endfunction
endscope
scope AITheReaper initializer init
struct AITR extends array
private static method onLoop takes nothing returns nothing
local unit u = AI.playerHero.hero
local Ability a1 = AI.playerHero.Abilities.integer[1]
local Ability a2 = AI.playerHero.Abilities.integer[2]
local Ability a3 = AI.playerHero.Abilities.integer[3]
local Ability a4 = AI.playerHero.Abilities.integer[4]
local boolean traitCD = BlzGetUnitAbilityCooldownRemaining(u,HeroicTraits_MIND_ID) == 0
local Buff b = GetUnitBuff(u,GrimCloak.buff)
local boolean rActive = GetUnitAbilityLevel(u,'A0D6') != 0
local Team te = 2/GetUnitTeam(u)
if b != 0 then
set AI.riskAction = true
endif
if rActive then
if BlzGetUnitAbilityCooldownRemaining(u,'A0D6') == 0 then
if AI.enemyHeroCount != 0 and not AI.danger then
if IssueTargetOrderById(u,ORDER_fingerofdeath,AI.weakEnemy) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if not a4.isOnCooldown() and a4.level != 0 then
if AI.enemyHeroCount >= (te.playerCount/2) + 1 then
if IssueImmediateOrderById(u,ORDER_defend) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a1.isOnCooldown() and a1.level != 0 then
call BlzUnitDisableAbility(u,'TRA1',false,false)
if rActive then
if traitCD then
if IssueImmediateOrderById(u,ORDER_windwalk) then
set u = null
return
endif
endif
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'TRA1',true,false)
set u = null
return
endif
else
if DistanceBetweenUnits(u,AI.weakEnemy) <= 300 and AI.enemyHeroCount != 0 then
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'TRA1',true,false)
set u = null
return
endif
endif
if AI.closestEnemyDistance <= 300 and AI.closestEnemyHero != null then
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'TRA1',true,false)
set u = null
return
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
if IssueImmediateOrderById(u,ORDER_berserk) then
call BlzUnitDisableAbility(u,'TRA1',true,false)
set u = null
return
endif
endif
endif
call BlzUnitDisableAbility(u,'TRA1',true,false)
endif
if not a3.isOnCooldown() and a3.level != 0 then
if AI.percentLife <= 0.20 then
if IssueImmediateOrderById(u,ORDER_divineshield) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if not a2.isOnCooldown() and a2.level != 0 then
if rActive and AI.enemyHeroCount != 0 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.weakEnemy),GetUnitY(AI.weakEnemy)) then
set AI.busyTimes = 1
set u = null
return
endif
else
if GetRandomInt(1,100) <= 20 then
if AI.closestEnemyDistance <= 300 and AI.closestEnemyHero != null then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.closestEnemyHero),GetUnitY(AI.closestEnemyHero)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
endif
if AI.goldUnit != null and AI.enemyHeroCount == 0 then
if IssuePointOrderById(u,ORDER_flamestrike,GetUnitX(AI.goldUnit),GetUnitY(AI.goldUnit)) then
set AI.busyTimes = 1
set u = null
return
endif
endif
endif
if AI.enemyUnitCount > 0 and AI.enemyHeroCount == 0 then
if not a1.isOnCooldown() and a1.level != 0 then
if not AI.retreating and AI.enemyUnitCount >= 3 then
if DistanceBetweenUnits(AI.weakUnit,u) <= 200 then
if IssueImmediateOrderById(u,ORDER_berserk) then
set u = null
return
endif
endif
endif
endif
endif
set u = null
endmethod
public static method createSkillBuild takes nothing returns nothing
call AI.abilityBuild.registerLearnSkill('TRA1')
call AI.abilityBuild.registerLearnSkill('TRA2')
call AI.abilityBuild.registerLearnSkill('TRA3')
call AI.abilityBuild.registerLearnSkill('TRA1')
call AI.abilityBuild.registerLearnSkill('TRA4')
call AI.abilityBuild.registerLearnSkill('A034') //Perk
call AI.abilityBuild.registerLearnSkill('TRA3')
call AI.abilityBuild.registerLearnSkill('TRA1')
call AI.abilityBuild.registerLearnSkill('TRA3')
call AI.abilityBuild.registerLearnSkill('TRA4')
call AI.abilityBuild.registerLearnSkill('A03K') //Perk
call AI.abilityBuild.registerLearnSkill('TRA1')
call AI.abilityBuild.registerLearnSkill('TRA3')
call AI.abilityBuild.registerLearnSkill('TRA2')
call AI.abilityBuild.registerLearnSkill('TRA4')
call AI.abilityBuild.registerLearnSkill('A03S') //Perk
call AI.abilityBuild.registerLearnSkill('TRA2')
call AI.abilityBuild.registerLearnSkill('TRA2')
call AI.abilityBuild.registerLearnSkill('A03I') //Perk
endmethod
public static method createUpgradeBuild takes nothing returns nothing
call UpgradeBuild.Build(AI.upgradeBuild)
endmethod
public static method createItemBuild takes nothing returns nothing
set AI.itemBuild.startItemID1 = 'frhg'
set AI.itemBuild.startItemID2 = 'brag'
set AI.itemBuild.startItemR1 = 8
set AI.itemBuild.startItemR2 = 5
call AI.itemBuild.add('tmsc') //Arcanist Rood 1
call AI.itemBuild.add('I00C') //Swift Treads 1
call AI.itemBuild.add('cnhn') //Valiant Heart 1
call AI.itemBuild.add('tmsc') //Arcanist Rood 2
call AI.itemBuild.add('I00A') //Witch's Relic 1
call AI.itemBuild.add('I00A') //Witch's Relic 2
call AI.itemBuild.add('tmsc') //Arcanist Rood 3
call AI.itemBuild.add('rde3') //Magic Emblem 1
call AI.itemBuild.add('cnhn') //Valiant Heart 2
call AI.itemBuild.add('cnhn') //Valiant Heart 3
call AI.itemBuild.add('pres') //Voodoo Cane 1
call AI.itemBuild.add('rde3') //Magic Emblem 2
call AI.itemBuild.add('I00A') //Witch's Relic 3
call AI.itemBuild.add('pres') //Voooo Cane 2
call AI.itemBuild.add('pres') //Voodoo Cane 3
call AI.itemBuild.add('rde3') //Magic Emblem 3
call AI.itemBuild.add('I00C') //Swift Treads 2
call AI.itemBuild.add('I00C') //Swift Treads 3
set AI.itemBuild.enchantBuild.random1 = 'I031'
set AI.itemBuild.enchantBuild.random2 = 'I00F'
//call AI.itemBuild.enchantBuild.SetWeaponEnchantEffect('','')
call AI.itemBuild.enchantBuild.SetArmorEnchantEffect('I030','cnhn')
endmethod
public static method selectTrait takes nothing returns nothing
local player p = GetOwningPlayer(AI.playerHero.hero)
call UnitRemoveAbility(AI.playerHero.hero,HeroicTraits_TRAIT_SELECT_ID)
call RemoveUnit(Players[GetPlayerId(p)].traitUnit)
set Players[GetPlayerId(p)].traitUnit = null
call GivesTraitAbility(HeroicTraits_S_MIND_ID,AI.playerHero)
set p = null
endmethod
implement AIHandler
endstruct
private function InitAI takes nothing returns nothing
if INIT_AI then
set INIT_AI = false
call AITR.StartAI(HERO_AI,false)
call AITR.createSkillBuild()
call AITR.createUpgradeBuild()
call AITR.createItemBuild()
call AITR.selectTrait()
endif
endfunction
private function init takes nothing returns nothing
call LoadFunction.RegisterFunction(function InitAI,'HTR1')
endfunction
endscope
library AiCore initializer init uses LinkedList, HeroAIThreat, InCombat, GuardPath
globals
private constant integer STATE_TO_FOUNTAIN = 1
private constant integer STATE_TO_BASE = 2
private constant integer STATE_TO_MINE = 3
private constant integer STATE_TO_FINAL = 6
private constant integer STATE_TO_OBELISK = 7
private constant integer STATE_CUSTOM_TARGET = 8
private constant real PERIODIC = 0.50
private constant real AREA_EVALUATION = 1000
private constant real HP_TO_HEAL = 0.20
private constant real HP_TO_RETURN = 0.70
private constant real MP_TO_RETURN = 0.90
private constant real MP_TO_RETURN_LEVEL = 0.10
private integer AIEventType
private timer Timer = null
private trigger EventTrigger = null
private integer TEMP
private trigger OnAttack
endglobals
struct AICore extends array
implement HeroAIThreat
Hero playerHero
Team team
group enumGroup
integer state
integer enemyHeroCount
integer enemyUnitCount
integer alliedHeroCount
integer alliedUnitCount
//integer alliedTowerCount
unit weakAllied
unit weakEnemy
unit weakUnit
unit weakTower
unit closestEnemyHero
unit goldUnit
unit runeSpot
real weakAlliedDist
real weakEnemyDist
real weakUnitDist
real weakTowerDist
real goldUnitDist
real weakAlliedHp
real weakEnemyHp
real weakUnitHp
real weakTowerHp
real closestEnemyDistance
real retreatX
real retreatY
real guardX
real guardY
real guardArea
real courageBase
real courageAdd
real life
real maxLife
real percentLife
real mana
real maxMana
real percentMana
real hx
real hy
real healX
real healY
real lastTargetX
real lastTargetY
unit lastTarget
integer lastOrder
integer iniPlace
integer moveCounter
integer randomBackCounter
real customTargetX
real customTargetY
real customTargetDuration
integer busyTimes
integer channelingOrder
boolean riskAction
boolean returnToBase
boolean inCombat
boolean retreating
boolean inBase
boolean ranged
boolean danger
Base targetBase
Base nearestBase
GoldMine targetMine
GoldMine nearestMine
boolean reachesTarget
Rune targetRune
AbilityBuild abilityBuild
UpgradeBuild upgradeBuild
ItemBuild itemBuild
boolean activated
boolean basic
trigger eventTrig
public static method HeroOrderTP takes Hero h, unit t, real x, real y returns boolean
if h.heroAI.channelingOrder != ORDER_channel then
if t == null then
if IssuePointOrderById(h.hero,ORDER_massteleport,x,y) then
set h.heroAI.channelingOrder = ORDER_massteleport
return true
endif
else
if IssueTargetOrderById(h.hero,ORDER_massteleport,t) then
set h.heroAI.channelingOrder = ORDER_massteleport
return true
endif
endif
endif
return false
endmethod
public method updateState takes nothing returns nothing
local integer sw = 0
local integer currentPriority
local boolean forceChange = false
local integer cb = GetUnitData(playerHero.hero,"BaseControl")
local boolean tpcd = BlzGetUnitAbilityCooldownRemaining(playerHero.hero,'A00A') > 0
local boolean ignoreHeal = false
local integer count
local integer nearestMinePriority
local integer nearestBasePriority
local Ability a
local Base tempBase
local GoldMine tempMine
if playerHero.TypeID == 'HFB1' then
set AIFB.rcd = BlzGetUnitAbilityCooldownRemaining(playerHero.hero,'FBA4') == 0
set a = playerHero.Abilities.integer[4]
if AIFB.rcd and a.level != 0 and (alliedHeroCount + 1 >= enemyHeroCount and enemyHeroCount != 0) and GetUnitState(playerHero.hero,UNIT_STATE_MANA) >= 150 then
set ignoreHeal = true
set riskAction = true
set returnToBase = false
endif
endif
if (percentLife <= HP_TO_HEAL or percentMana <= 0.10 or returnToBase) and cb == 0 and not ignoreHeal then
if returnToBase then
if percentLife >= HP_TO_RETURN and percentMana >= MP_TO_RETURN - MP_TO_RETURN_LEVEL * (GetHeroLevel(playerHero.hero)/5) then
set returnToBase = false
set reachesTarget = true
endif
if not inCombat and enemyHeroCount == 0 and team.heroesDeath < Team[2/team].heroesDeath and not tpcd then
if Distance(hx,hy,playerHero.heroAI.team.startX,playerHero.heroAI.team.startY) > 3500 then
call HeroOrderTP(playerHero,null,playerHero.heroAI.team.startX,playerHero.heroAI.team.startY)
endif
endif
else
if percentMana <= 0.10 and (not inCombat or enemyHeroCount > alliedHeroCount) then
set returnToBase = true
else
if percentLife <= HP_TO_HEAL then
set returnToBase = true
endif
endif
endif
else
if not reachesTarget then
if state == STATE_CUSTOM_TARGET then
if customTargetDuration <= 0 then
set customTargetDuration = 0
set reachesTarget = true
endif
endif
if team.AI_TeamBasePriority1 >= 170 and team.bases == 1 and team.AI_TeamBaseTarget1.owner == team and state != STATE_TO_OBELISK and targetBase != team.AI_TeamBaseTarget1 then
set forceChange = true
set reachesTarget = true
endif
if state == STATE_TO_OBELISK then
if Distance(hx,hy,AncientObelisk.x,AncientObelisk.y) <= 150 or AncientObelisk.owner != 0 then
set reachesTarget = true
set forceChange = true
if playerHero.TypeID == 'HGG1' then
if UnitHasBuff(playerHero.hero,CobraK300.buff) then
set AIGG.reachesTarget = true
endif
endif
endif
endif
if targetBase != 0 and state != STATE_CUSTOM_TARGET then
set currentPriority = getBasePriority(targetBase,team)
if Distance(hx,hy,targetBase.x,targetBase.y) <= 150 then
set reachesTarget = true
if playerHero.TypeID == 'HGG1' then
if UnitHasBuff(playerHero.hero,CobraK300.buff) then
set AIGG.reachesTarget = true
endif
endif
endif
if team.AI_TeamMineTarget1 == nearestMine and team.AI_TeamMineTarget1.owner == team then
set count = team.AI_TeamMineTarget1.getCurrentHeroes(team)
if not team.AI_TeamMineTarget1.defenders.passive and count <= team.AI_TeamMineTarget1.getCurrentHeroes(2/team) then
set reachesTarget = true
endif
endif
if currentPriority < team.AI_TeamBasePriority1 or currentPriority <= 30 then
set reachesTarget = true
endif
if AncientObelisk.enabled and AncientObelisk.owner == 0 then
set reachesTarget = true
set forceChange = true
endif
endif
if targetMine != 0 and state != STATE_CUSTOM_TARGET then
set currentPriority = getGoldPriority(targetMine,team)
if Distance(hx,hy,targetMine.x,targetMine.y) <= 150 then
set reachesTarget = true
if playerHero.TypeID == 'HGG1' then
if UnitHasBuff(playerHero.hero,CobraK300.buff) then
set AIGG.reachesTarget = true
endif
endif
endif
if team.AI_TeamBaseTarget1 == nearestBase and team.AI_TeamBaseTarget1.owner == team then
set count = team.AI_TeamBaseTarget1.getCurrentHeroes(team)
if IsUnitInCombat(team.AI_TeamBaseTarget1.tower) and count <= team.AI_TeamBaseTarget1.getCurrentHeroes(2/team) then
set reachesTarget = true
endif
endif
if currentPriority < team.AI_TeamMinePriority1 or currentPriority <= 30 then
set reachesTarget = true
endif
if team.AI_TeamBaseTarget1.owner == 0 and team.AI_TeamBaseTarget1.getHeroesTarget(team) == 0 then
set reachesTarget = true
endif
if AncientObelisk.enabled and AncientObelisk.owner == 0 then
set reachesTarget = true
set forceChange = true
endif
endif
if state == STATE_TO_FINAL then
if team.AI_TeamBasePriority1 > 30 or team.AI_TeamMinePriority1 > 30 then
set reachesTarget = true
endif
if AncientObelisk.enabled and AncientObelisk.owner == 0 then
set reachesTarget = true
set forceChange = true
endif
endif
endif
if reachesTarget and (not inCombat or forceChange) then
set reachesTarget = false
if state == STATE_CUSTOM_TARGET then
set courageAdd = 0.0
endif
if targetBase != 0 then
call targetBase.addHeroesTarget(team,-1)
set targetBase = 0
endif
if targetMine != 0 then
call targetMine.addHeroesTarget(team,-1)
set targetMine = 0
endif
if AncientObelisk.enabled and AncientObelisk.owner == 0 then
set sw = 1
set state = STATE_TO_OBELISK
endif
if team.AI_TeamBasePriority1 > 30 and sw == 0 then
set count = team.AI_TeamBaseTarget1.getHeroesTarget(team)
if team.AI_TeamBaseTarget1.owner == 0 and GetRandomInt(1,100) <= 100 - (45 * count) then
set sw = 1
set tempBase = team.AI_TeamBaseTarget1
endif
if nearestBase.owner == 0 and nearestBase != team.AI_TeamBaseTarget1 and nearestBase != 0 and sw == 0 then
set sw = 1
set tempBase = nearestBase
endif
if team.AI_TeamBaseTarget1.owner == 2/team and sw == 0 then
if team.AI_TeamBasePriority1 > team.AI_TeamMinePriority1 and (GetHeroLevel(playerHero.hero) >= 8 or weakTowerHp <= 0.20)then
set sw = 1
set tempBase = team.AI_TeamBaseTarget1
endif
endif
if team.AI_TeamBaseTarget1.owner == team and sw == 0 and (team.heroesDeath <= Team[2/team].heroesDeath or GetUnitAbilityLevel(team.AI_TeamBaseTarget1.tower,'A00H') != 0)then
if team.bases == 1 and team.AI_TeamBasePriority1 >= 170 then
if nearestBase != team.AI_TeamBaseTarget1 and not tpcd then
call HeroOrderTP(playerHero,team.AI_TeamBaseTarget1.tower,0,0)
endif
set sw = 1
set tempBase = team.AI_TeamBaseTarget1
endif
if cb == 0 and enemyHeroCount == 0 and nearestBase != team.AI_TeamBaseTarget1 and not tpcd and sw == 0 then
if team.AI_TeamBaseTarget1.getCurrentHeroes(2/team) > count and sw == 0 then
call HeroOrderTP(playerHero,team.AI_TeamBaseTarget1.tower,0,0)
set sw = 1
set tempBase = team.AI_TeamBaseTarget1
endif
endif
if nearestBase == team.AI_TeamBaseTarget1 and sw == 0 then
set sw = 1
set tempBase = team.AI_TeamBaseTarget1
endif
endif
if sw == 1 then
set targetBase = tempBase
call targetBase.addHeroesTarget(team,1)
set state = STATE_TO_BASE
set targetMine = 0
endif
endif
if team.AI_TeamMinePriority1 > 30 and sw == 0 then
set count = team.AI_TeamMineTarget1.getHeroesTarget(team)
if team.AI_TeamMineTarget1.owner == 0 and GetRandomInt(1,100) <= 100 - (45 * count) then
set sw = 1
set tempMine = team.AI_TeamMineTarget1
endif
if nearestMine.owner == 0 and nearestMine != team.AI_TeamMineTarget1 and nearestMine != 0 and sw == 0 then
set sw = 1
set tempMine = nearestMine
endif
if nearestMine.owner == 2/team and nearestMine != team.AI_TeamMineTarget1 and nearestMine != 0 and sw == 0 then
set sw = 1
set tempMine = nearestMine
endif
if team.AI_TeamMineTarget1.owner == 2/team and sw == 0 then
set sw = 1
set tempMine = team.AI_TeamMineTarget1
endif
if team.AI_TeamMineTarget1.owner == team and sw == 0 then
if team.AI_TeamMineTarget1 == nearestMine then
set sw = 1
set tempMine = team.AI_TeamMineTarget1
else
if cb == 0 and enemyHeroCount == 0 and not tpcd then
if team.AI_TeamMineTarget1.getCurrentHeroes(2/team) > team.AI_TeamMineTarget1.getHeroesTarget(team) then
call HeroOrderTP(playerHero,team.AI_TeamMineTarget1.gold,0,0)
set sw = 1
set tempMine = team.AI_TeamMineTarget1
endif
endif
endif
endif
if sw == 1 then
set targetMine = tempMine
call targetMine.addHeroesTarget(team,1)
set state = STATE_TO_MINE
set targetBase = 0
else
set sw = 1
set targetBase = team.AI_TeamBaseTarget1
call targetBase.addHeroesTarget(team,1)
set state = STATE_TO_BASE
set targetMine = 0
endif
endif
if sw == 0 then
set state = STATE_TO_FINAL
endif
endif
endif
endmethod
private static method GetTeamPriorityBonus takes Team t, integer r returns integer
if t == 1 then
if r == 1 then
return 30
endif
if r == 2 then
return 25
endif
if r == 3 then
return 5
endif
if r == 4 then
return 20
endif
elseif t == 2 then
if r == 1 then
return 5
endif
if r == 2 then
return 20
endif
if r == 3 then
return 30
endif
if r == 4 then
return 25
endif
endif
return 0
endmethod
public static method getGoldPriority takes GoldMine g, Team t returns integer
local integer gpriority = 0
if g.owner == 0 then
set gpriority = gpriority + 60
if g.defenders.passive then
set gpriority = gpriority + 60
endif
elseif g.owner != t then
set gpriority = gpriority + 60
if not g.defenders.passive then
set gpriority = gpriority + 30
endif
if Base[g].owner != t then
set gpriority = gpriority + 30
endif
else
if not g.defenders.passive then
set gpriority = gpriority + 60
set gpriority = gpriority + 12 * g.getCurrentHeroes(2/t)
endif
endif
return gpriority + GetTeamPriorityBonus(t,g)
endmethod
public static method updateGoldPriority takes Team t returns nothing
local integer gpriority = 0
local integer i = 1
set t.AI_TeamMinePriority1 = 0
loop
set gpriority = getGoldPriority(GoldMine[i],t)
//call BJDebugMsg("Mine: "+I2S(i)+"-"+I2S(gpriority))
if gpriority > t.AI_TeamMinePriority1 then
set t.AI_TeamMinePriority1 = gpriority
set t.AI_TeamMineTarget1 = GoldMine[i]
endif
set i = i + 1
exitwhen i > 4
endloop
//call BJDebugMsg("Max Gold Proority: "+I2S(gp)+"-"+I2S(tg))
endmethod
public static method getBasePriority takes Base b, Team t returns integer
local integer bpriority = 0
local integer pb = GetTeamPriorityBonus(t,b)
if b.owner == 0 then
set bpriority = bpriority + 60
if b.controlTeam == 0 then
set bpriority = bpriority + 60
elseif pb == 30 and b.controlTeam != t then
set bpriority = bpriority + 20
endif
elseif b.owner != t then
set bpriority = bpriority + 30
if IsUnitInCombat(b.tower) then
set bpriority = bpriority + 40
if GetUnitLifePercent(b.tower) <= 50 then
set bpriority = bpriority + 50
endif
else
if GetUnitLifePercent(b.tower) <= 15 then
set bpriority = bpriority + 90
endif
endif
else
if IsUnitInCombat(b.tower) then
set bpriority = bpriority + 60
if GetUnitLifePercent(b.tower) <= 50 then
set bpriority = bpriority + 60
endif
set bpriority = bpriority + 10 * b.getCurrentHeroes(2/t)
endif
endif
return bpriority + pb
endmethod
public static method updateBasePriority takes Team t returns nothing
local integer bpriority = 0
local integer i = 1
set t.AI_TeamBasePriority1 = 0
loop
set bpriority = getBasePriority(Base[i],t)
//call BJDebugMsg("Base: "+I2S(i)+"-"+I2S(bpriority))
if bpriority > t.AI_TeamBasePriority1 then
set t.AI_TeamBasePriority1 = bpriority
set t.AI_TeamBaseTarget1 = Base[i]
endif
set i = i + 1
exitwhen i > 4
endloop
//call BJDebugMsg("Max Base Proority: "+I2S(bp)+"-"+I2S(tb))
endmethod
private method updateRetreatTarget takes nothing returns nothing
local integer i = 0
local real dist
local real dist2 = 10000000
local real temp = 0
local boolean b = percentLife <= 0.75 or returnToBase
set retreatX = team.commander.xOrigin
set retreatY = team.commander.yOrigin
set dist = Distance(retreatX,retreatY,hx,hy)
set nearestMine = 0
set nearestBase = 0
loop
set i = i + 1
set temp = Distance(Base[i].x,Base[i].y,hx,hy)
if not b then
if temp < dist and Base[i].owner == team then
set dist = temp
set retreatX = Base[i].x
set retreatY = Base[i].y
endif
endif
if temp < dist2 then
set dist2 = temp
set nearestBase = Base[i]
endif
exitwhen i == 4
endloop
set i = 0
set dist2 = 10000000
loop
set i = i + 1
set temp = Distance(GoldMine[i].x,GoldMine[i].y,hx,hy)
if not b then
if temp < dist and GoldMine[i].owner == team then
set dist = temp
set retreatX = GoldMine[i].x
set retreatY = GoldMine[i].y
endif
endif
if temp < dist2 then
set dist2 = temp
set nearestMine = GoldMine[i]
endif
exitwhen i == 4
endloop
endmethod
private static method UnitFilter takes unit u, integer id returns boolean
return GetOwningPlayer(u) != Game.PLAYER_NEUTRAL_EXTRA and GetUnitAbilityLevel(u,Game.FLAG_NO_AGGRO) == 0 and not Status.UnitHasStatus(STATUS_INVULNERABLE,u) and not IsUnitHidden(u) and UnitAlive(u)
endmethod
public method updateValues takes nothing returns nothing
local player p = Player(this)
local real wa = 9999
local real we = 9999
local real wu = 9999
local real wt = 9999
local unit temp
local real lifet
local real highestE = 0
local real highestA = 0
local real t
local real dtemp
local boolean b
local boolean b2
local boolean tv
local integer id
set closestEnemyDistance = 1200
set inCombat = IsUnitInCombat(playerHero.hero)
set inBase = IsHeroInBase(p)
set hx = GetUnitX(playerHero.hero)
set hy = GetUnitY(playerHero.hero)
set life = GetUnitState(playerHero.hero,UNIT_STATE_LIFE)
set maxLife = GetUnitState(playerHero.hero,UNIT_STATE_MAX_LIFE)
set mana = GetUnitState(playerHero.hero,UNIT_STATE_MANA)
set maxMana = GetUnitState(playerHero.hero,UNIT_STATE_MAX_MANA)
set percentMana = mana / maxMana
set percentLife = life / maxLife
call GroupClear(enumGroup)
call GroupEnumUnitsInRange(enumGroup,hx,hy,AREA_EVALUATION,null)
set threat = 0
set threatThreshold = 0
set enemyHeroCount = 0
set enemyUnitCount = 0
set alliedHeroCount = 0
set alliedUnitCount = 0
set weakEnemy = null
set weakAllied = null
set weakUnit = null
set weakTower = null
set threatEnemy = null
set threatAlly = null
set goldUnit = null
set runeSpot = null
set closestEnemyHero = null
set riskAction = false
if not IsUnitMoving(playerHero.hero) and not inCombat then
set moveCounter = moveCounter + 1
if moveCounter >= 20 then
set moveCounter = 0
call thistype.HeroOrderTP(playerHero,null,playerHero.heroAI.team.startX,playerHero.heroAI.team.startY)
set p = null
return
endif
else
set moveCounter = 0
endif
loop
set temp = FirstOfGroup(enumGroup)
exitwhen temp == null
call GroupRemoveUnit(enumGroup,temp)
set lifet = GetWidgetLife(temp)
set id = GetUnitTypeId(temp)
if id == 'ncop' then
if GetUnitUserData(temp) != 0 then
set runeSpot = temp
endif
else
if UnitFilter(temp,id) then
set b = IsUnitType(temp,UNIT_TYPE_HERO)
set b2 = IsUnitAlly(temp,p)
set t = weightThreat(temp,id)
set tv = IsUnitVisible(temp,p)
if b2 then
if b then
if temp != playerHero.hero then
if IsUnitDisabled(temp) then
set t = t/2
endif
if lifet < wa then
set wa = lifet
set weakAllied = temp
set weakAlliedHp = lifet / GetUnitState(weakAllied,UNIT_STATE_MAX_LIFE)
endif
if highestA < t then
set highestA = t
set .threatAlly = temp
endif
set alliedHeroCount = alliedHeroCount + 1
endif
else
if (id == 'n009' or id == 'n006') then
if not IsUnitInCombat(temp) or DistanceBetweenUnits(playerHero.hero,temp) > 500 then
set t = 0
endif
else
if GetUnitAbilityLevel(temp,'Arel') != 0 then
if not IsUnitInCombat(temp) then
set t = t/2
endif
endif
endif
if not IsUnitType(temp,UNIT_TYPE_SUMMONED) then
set alliedUnitCount = alliedUnitCount + 1
endif
endif
set .threatThreshold = .threatThreshold + t
else
if b then
if IsUnitDisabled(temp) then
set t = 0
endif
if GetUnitAbilityLevel(temp,'ANcl') != 0 then
set t = 0
endif
if tv then
if highestE < t then
set highestE = t
set .threatEnemy = temp
endif
if lifet < we then
set we = lifet
set weakEnemy = temp
set weakEnemyHp = lifet / GetUnitState(weakEnemy,UNIT_STATE_MAX_LIFE)
endif
set dtemp = Distance(GetUnitX(temp),GetUnitY(temp),hx,hy)
if dtemp <= closestEnemyDistance then
set closestEnemyDistance = dtemp
set closestEnemyHero = temp
endif
set enemyHeroCount = enemyHeroCount + 1
endif
set .threat = .threat + t
else
if id == 'n009' or id == 'n006' then
if tv then
if not IsUnitInCombat(temp) then
set t = 0
endif
if lifet < wt then
set wt = lifet
set weakTower = temp
set weakTowerHp = lifet / GetUnitState(weakTower,UNIT_STATE_MAX_LIFE)
endif
endif
set .threat = .threat + t
else
if tv then
if id == 'o005' or id == 'h00I' then
set goldUnit = temp
endif
if lifet < wu then
set wu = lifet
set weakUnit = temp
set weakUnitHp = lifet / GetUnitState(weakUnit,UNIT_STATE_MAX_LIFE)
endif
set enemyUnitCount = enemyUnitCount + 1
set .threat = .threat + t
endif
endif
endif
endif
endif
endif
endloop
if enemyHeroCount != 0 then
call itemBuild.useConsumables()
endif
set p = null
endmethod
private static method TakeRune takes AICore ai returns nothing
local Rune r = GetUnitUserData(ai.runeSpot)
local real d = Distance(r.xc,r.yc,ai.hx,ai.hy)
local integer rid
if r.data == 0 and r != 0 then
set rid = GetItemTypeId(r.rune)
if ai.returnToBase then
if rid == 'rdis' then
if d <= 600 then
if IssueTargetOrderById(ai.playerHero.hero,ORDER_smart,r.rune) then
set ai.busyTimes = 2
endif
endif
endif
else
if ai.enemyHeroCount == 0 then
if d <= 800 then
if IssueTargetOrderById(ai.playerHero.hero,ORDER_smart,r.rune) then
set ai.busyTimes = 2
endif
endif
else
if d <= 500 then
if IssueTargetOrderById(ai.playerHero.hero,ORDER_smart,r.rune) then
set ai.busyTimes = 2
endif
endif
endif
endif
endif
endmethod
private static method ActionsNormal takes AICore ai returns nothing
local ControlBase cb = GetUnitData(ai.playerHero.hero,"BaseControl")
local UnitGuardPath gp = 0
local Team t2 = 2/ai.team
local integer sw = 0
local boolean chooseTarget = true
local boolean attackSafe = false
local unit attack = null
call ai.updateValues()
set ai.threatThreshold = ai.threatThreshold * (ai.courageBase + ai.courageAdd)
set ai.danger = ai.threat > ai.threatThreshold
/*if IsUnitSelected(ai.playerHero.hero,Game.LocalPlayer) then
call BJDebugMsg("T/TT"+"="+R2S(ai.threat)+"/"+R2S(ai.threatThreshold))
endif*/
if ai.runeSpot != null then
call TakeRune(ai)
endif
call ai.updateState()
call ai.updateRetreatTarget()
if (ai.channelingOrder == 0 and ai.busyTimes <= 0) or ai.playerHero.TypeID == 'HSB1' or ai.playerHero.TypeID == 'HWL1' or ai.playerHero.TypeID == 'HMB1' then
call TriggerEvaluate(ai.eventTrig)
endif
if ai.channelingOrder == 0 and ai.busyTimes <= 0 then
if ai.returnToBase then
if RectContainsCoords(ai.team.startReg,ai.hx,ai.hy) then
call ai.idleRandom(ai.healX,ai.healY,300.00)
else
if ai.riskAction then
if ai.closestEnemyHero != null and ai.closestEnemyDistance <= ai.playerHero.AttackRange + 200 then
set attack = ai.closestEnemyHero
set sw = 1
else
if DistanceBetweenUnits(ai.playerHero.hero,ai.weakEnemy) <= ai.playerHero.AttackRange + 200 then
set attack = ai.weakEnemy
set sw = 1
endif
endif
if sw != 1 then
call ai.IssueOrder(null,ORDER_move,ai.healX,ai.healY)
endif
else
call ai.IssueOrder(null,ORDER_move,ai.healX,ai.healY)
endif
endif
else
if ai.danger and cb == 0 and not ai.riskAction then
if Distance(ai.hx,ai.hy,ai.retreatX,ai.retreatY) > 400 then
call ai.retreat()
set ai.busyTimes = 1
set chooseTarget = false
endif
endif
if cb != 0 then
if ai.threat == 0 then
call ai.idleRandom(cb.base.x,cb.base.y,300.00)
set chooseTarget = false
else
set attackSafe = true
endif
endif
if chooseTarget then
if ai.basic then
else
if ai.team.heroesDeath >= ai.team.playerCount - 1 and sw == 0 then
set sw = 5
if Distance(ai.retreatX,ai.retreatY,ai.hx,ai.hy) <= 300 then
if GetRandomInt(1,100) <= 15 then
call ai.idleRandom(ai.retreatX,ai.retreatY,700.00)
endif
else
call ai.IssueOrder(null,ORDER_move,ai.retreatX,ai.retreatY)
endif
endif
if ai.weakTower != null and not (AncientObelisk.enabled and AncientObelisk.owner == 0) then
if ai.weakTowerHp <= 0.15 or (ai.enemyHeroCount == 0 and ai.enemyUnitCount == 0) then
set attack = ai.weakTower
set sw = 1
endif
endif
if ai.enemyHeroCount > 0 and sw == 0 then
if attackSafe then
if Distance(ai.guardX,ai.guardY,GetUnitX(ai.weakEnemy),GetUnitY(ai.weakEnemy)) <= ai.playerHero.AttackRange + ai.guardArea - 100 then
set attack = ai.weakEnemy
set sw = 1
else
if ai.closestEnemyHero != null and ai.closestEnemyDistance <= ai.playerHero.AttackRange + ai.guardArea - 100 then
set attack = ai.closestEnemyHero
set sw = 1
else
call ai.idleRandom(cb.base.x,cb.base.y,300.00)
set ai.busyTimes = 1
endif
endif
else
if ai.riskAction then
if ai.closestEnemyHero != null and ai.closestEnemyDistance <= ai.playerHero.AttackRange + 400 then
set attack = ai.closestEnemyHero
set sw = 1
else
if DistanceBetweenUnits(ai.playerHero.hero,ai.weakEnemy) <= ai.playerHero.AttackRange + 400 then
set attack = ai.weakEnemy
set sw = 1
endif
endif
else
if Distance(ai.hx,ai.hy,GetUnitX(ai.weakEnemy),GetUnitY(ai.weakEnemy)) <= ai.playerHero.AttackRange + 600 then
set attack = ai.weakEnemy
set sw = 1
endif
endif
endif
endif
if ai.enemyUnitCount > 0 and sw == 0 and not (AncientObelisk.enabled and AncientObelisk.owner == 0) then
if Distance(ai.hx,ai.hy,GetUnitX(ai.weakUnit),GetUnitY(ai.weakUnit)) <= ai.playerHero.AttackRange + 500 then
set attack = ai.weakUnit
set sw = 1
endif
endif
if ai.state == STATE_CUSTOM_TARGET and sw == 0 then
if Distance(ai.customTargetX,ai.customTargetY,ai.hx,ai.hy) <= 300 then
set ai.customTargetDuration = ai.customTargetDuration - 0.50
if GetRandomInt(1,100) <= 15 then
call ai.idleRandom(ai.customTargetX,ai.customTargetY,300.00)
endif
else
call ai.IssueOrder(null,ORDER_move,ai.customTargetX,ai.customTargetY)
endif
endif
if ai.state == STATE_TO_BASE and sw == 0 then
if Distance(ai.targetBase.x,ai.targetBase.y,ai.hx,ai.hy) <= 300 then
if GetRandomInt(1,100) <= 15 then
call ai.idleRandom(ai.targetBase.x,ai.targetBase.y,600.00)
endif
else
call ai.IssueOrder(null,ORDER_move,ai.targetBase.x,ai.targetBase.y)
endif
endif
if ai.state == STATE_TO_MINE and sw == 0 then
if Distance(ai.targetMine.x,ai.targetMine.y,ai.hx,ai.hy) <= 300 then
if GetRandomInt(1,100) <= 15 then
call ai.idleRandom(ai.targetMine.x,ai.targetMine.y,500.00)
endif
else
call ai.IssueOrder(null,ORDER_move,ai.targetMine.x,ai.targetMine.y)
endif
endif
if ai.state == STATE_TO_OBELISK and sw == 0 then
if Distance(AncientObelisk.x,AncientObelisk.y,ai.hx,ai.hy) <= 200.00 then
if AncientObelisk.currentHero == null and AncientObelisk.owner == 0 then
call AncientObelisk.Control(ai.playerHero.hero)
else
if GetRandomInt(1,100) <= 15 then
call ai.idleRandom(AncientObelisk.x,AncientObelisk.y,600.00)
endif
endif
else
call ai.IssueOrder(null,ORDER_move,AncientObelisk.x,AncientObelisk.y)
endif
endif
if ai.state == STATE_TO_FINAL and sw == 0 then
if ai.team == 1 then
if Distance(Base[3].x,Base[3].y,ai.hx,ai.hy) <= 500 then
if GetRandomInt(1,100) <= 15 then
call ai.idleRandom(Base[3].x,Base[3].y,600.00)
endif
else
call ai.IssueOrder(null,ORDER_move,Base[3].x,Base[3].y)
endif
elseif ai.team == 2 then
if Distance(Base[1].x,Base[1].y,ai.hx,ai.hy) <= 500 then
if GetRandomInt(1,100) <= 15 then
call ai.idleRandom(Base[1].x,Base[1].y,600.00)
endif
else
call ai.IssueOrder(null,ORDER_move,Base[1].x,Base[1].y)
endif
endif
endif
endif
endif
endif
else
if ai.busyTimes > 0 then
set ai.busyTimes = ai.busyTimes - 1
if ai.busyTimes <= 0 and ai.retreating then
set ai.retreating = false
endif
endif
if ai.channelingOrder > 0 then
if GetUnitCurrentOrder(ai.playerHero.hero) != ai.channelingOrder then
set ai.channelingOrder = 0
endif
endif
endif
if sw == 1 then
if ai.playerHero.TypeID == 'HWD1' then
if AIWD.RTarget != null then
set attack = AIWD.RTarget
endif
endif
if ai.guardArea > 0 then
if Distance(GetUnitX(attack),GetUnitY(attack),ai.guardX,ai.guardY) > ai.guardArea + ai.playerHero.AttackRange then
call ai.IssueOrder(null,ORDER_move,ai.guardX,ai.guardY)
set ai.busyTimes = 2
else
call ai.IssueOrder(attack,ORDER_attack,0,0)
endif
else
call ai.IssueOrder(attack,ORDER_attack,0,0)
endif
endif
set attack = null
endmethod
private method updateStateLMS takes nothing returns nothing
local Team t2 = 2/team
if not reachesTarget then
if state == STATE_CUSTOM_TARGET then
if customTargetDuration <= 0 then
set customTargetDuration = 0
set reachesTarget = true
endif
else
if Distance(hx,hy,GetRectCenterX(AI_Stands[targetBase]),GetRectCenterY(AI_Stands[targetBase])) <= 100 then
set reachesTarget = true
endif
endif
endif
if reachesTarget then
set reachesTarget = false
if state == STATE_CUSTOM_TARGET then
set courageAdd = 0.0
endif
if this.team == 1 then
set targetBase = GetRandomInt(0,7)
set retreatX = GetRectCenterX(AI_Stands[targetBase])
set retreatY = GetRectCenterY(AI_Stands[targetBase])
set state = STATE_TO_BASE
elseif this.team == 2 then
set targetBase = GetRandomInt(0,7)
set retreatX = GetRectCenterX(AI_Stands[targetBase])
set retreatY = GetRectCenterY(AI_Stands[targetBase])
set state = STATE_TO_BASE
endif
endif
endmethod
private static method ActionsLMS takes AICore ai returns nothing
local unit attack = null
local real x
local real y
local integer sw = 0
call ai.updateValues()
set ai.danger = ai.threat > ai.threatThreshold * (ai.courageBase + ai.courageAdd)
call ai.updateStateLMS()
set x = GetRectCenterX(AI_Stands[ai.targetBase])
set y = GetRectCenterY(AI_Stands[ai.targetBase])
if ai.runeSpot != null then
call TakeRune(ai)
endif
if (ai.channelingOrder == 0 and ai.busyTimes <= 0) or ai.playerHero.TypeID == 'HSB1' or ai.playerHero.TypeID == 'HWL1' then
call TriggerEvaluate(ai.eventTrig)
endif
if ai.channelingOrder == 0 and ai.busyTimes <= 0 then
if ai.danger and Distance(ai.hx,ai.hy,ai.retreatX,ai.retreatY) > 300 + ai.playerHero.AttackRange then
call ai.retreat()
set ai.busyTimes = 2
else
if ai.enemyHeroCount > 0 then
if Distance(ai.hx,ai.hy,GetUnitX(ai.weakEnemy),GetUnitY(ai.weakEnemy)) <= ai.playerHero.AttackRange + 500 then
set attack = ai.weakEnemy
set sw = 1
endif
endif
if ai.enemyUnitCount > 0 and sw == 0 then
if Distance(ai.hx,ai.hy,GetUnitX(ai.weakUnit),GetUnitY(ai.weakUnit)) <= ai.playerHero.AttackRange + 500 then
set attack = ai.weakUnit
set sw = 1
endif
endif
if ai.state == STATE_CUSTOM_TARGET and sw == 0 then
if Distance(ai.customTargetX,ai.customTargetY,ai.hx,ai.hy) <= 300 then
set ai.customTargetDuration = ai.customTargetDuration - 0.50
if GetRandomInt(1,100) <= 15 then
call ai.idleRandom(ai.customTargetX,ai.customTargetY,300.00)
endif
else
call ai.IssueOrder(null,ORDER_move,ai.customTargetX,ai.customTargetY)
endif
endif
if Distance(ai.hx,ai.hy,x,y) > 100 and sw == 0 then
call ai.IssueOrder(null,ORDER_move,x,y)
endif
endif
else
if ai.busyTimes > 0 then
set ai.busyTimes = ai.busyTimes - 1
if ai.busyTimes <= 0 and ai.retreating then
set ai.retreating = false
endif
endif
if ai.channelingOrder > 0 then
if GetUnitCurrentOrder(ai.playerHero.hero) != ai.channelingOrder then
set ai.channelingOrder = 0
endif
endif
endif
if sw == 1 then
if ai.playerHero.TypeID == 'HWD1' then
if AIWD.RTarget != null then
set attack = AIWD.RTarget
endif
endif
call ai.IssueOrder(attack,ORDER_attack,0,0)
endif
set attack = null
endmethod
/*private method updateStateOD takes nothing returns nothing
if team == CurrentOwner then
set retreatX = AncientObelisk.x
set retreatY = AncientObelisk.y
call setGuardSpot(AncientObelisk.x,AncientObelisk.y,700)
set state = STATE_TO_OBELISK
else
call setGuardSpot(0,0,0)
if iniPlace <= 2 then
set retreatX = GetUnitX(HORDE_RIVER_RUNE_SPOT)
set retreatY = GetUnitY(HORDE_RIVER_RUNE_SPOT)
else
set retreatX = GetUnitX(ALLIANCE_RIVER_RUNE_SPOT)
set retreatY = GetUnitY(ALLIANCE_RIVER_RUNE_SPOT)
endif
set state = STATE_TO_OBELISK
endif
endmethod*/
/*private static method ActionsOD takes AICore ai returns nothing
local unit attack = null
local integer sw = 0
set ai.danger = ai.threat > ai.threatThreshold * ai.courageBase
call ai.updateValues()
call ai.updateStateOD()
if ai.runeSpot != null then
call TakeRune(ai)
endif
if (ai.channelingOrder == 0 and ai.busyTimes <= 0) or ai.playerHero.TypeID == 'HSB1' or ai.playerHero.TypeID == 'HWL1' then
call TriggerEvaluate(ai.eventTrig)
endif
if ai.channelingOrder == 0 and ai.busyTimes <= 0 then
if ai.danger and Distance(ai.hx,ai.hy,ai.retreatX,ai.retreatY) > 300 + ai.playerHero.AttackRange and ai.team != CurrentOwner then
call ai.retreat()
set ai.busyTimes = 2
else
if Distance(AncientObelisk.x,AncientObelisk.y,ai.hx,ai.hy) <= ai.playerHero.AttackRange + 100 and ai.team != CurrentOwner then
if GetRandomInt(1,100) <= 100 - 10 * ai.enemyHeroCount then
set attack = AncientObelisk.obelisk
set sw = 1
endif
endif
if ai.enemyHeroCount > 0 and sw == 0 then
if Distance(ai.hx,ai.hy,GetUnitX(ai.weakEnemy),GetUnitY(ai.weakEnemy)) <= ai.playerHero.AttackRange + 500 then
set attack = ai.weakEnemy
set sw = 1
endif
endif
if ai.enemyUnitCount > 0 and sw == 0 then
if Distance(ai.hx,ai.hy,GetUnitX(ai.weakUnit),GetUnitY(ai.weakUnit)) <= ai.playerHero.AttackRange + 500 then
set attack = ai.weakUnit
set sw = 1
endif
endif
if ai.team == CurrentOwner and sw == 0 then
if Distance(ai.hx,ai.hy,AncientObelisk.x,AncientObelisk.y) > ai.guardArea and sw == 0 then
call ai.IssueOrder(null,ORDER_move,AncientObelisk.x,AncientObelisk.y)
else
if GetRandomInt(1,100) <= 20 then
call ai.idleRandom(AncientObelisk.x,AncientObelisk.y,600)
endif
endif
else
if Distance(ai.hx,ai.hy,AncientObelisk.x,AncientObelisk.y) > 100 and sw == 0 then
call ai.IssueOrder(null,ORDER_move,AncientObelisk.x,AncientObelisk.y)
endif
endif
endif
else
if ai.busyTimes > 0 then
set ai.busyTimes = ai.busyTimes - 1
if ai.busyTimes <= 0 and ai.retreating then
set ai.retreating = false
endif
endif
if ai.channelingOrder > 0 then
if GetUnitCurrentOrder(ai.playerHero.hero) != ai.channelingOrder then
set ai.channelingOrder = 0
endif
endif
endif
if sw == 1 then
if ai.guardArea > 0 then
if Distance(ai.retreatX,ai.retreatY,GetUnitX(attack),GetUnitY(attack)) > ai.guardArea + ai.playerHero.AttackRange + 100 then
call ai.IssueOrder(null,ORDER_move,ai.retreatX,ai.retreatY)
set ai.busyTimes = 2
else
call ai.IssueOrder(attack,ORDER_attack,0,0)
endif
else
if ai.playerHero.TypeID == 'HWD1' then
if AIWD.RTarget != null then
set attack = AIWD.RTarget
endif
endif
if attack == AncientObelisk.obelisk then
set ai.busyTimes = 2
endif
call ai.IssueOrder(attack,ORDER_attack,0,0)
endif
endif
set attack = null
endmethod*/
private static method Loop takes nothing returns nothing
local integer i = 0
local thistype ai
if Game.Mode == GAME_MODE_NORMAL then
call updateBasePriority(1)
call updateGoldPriority(1)
call updateBasePriority(2)
call updateGoldPriority(2)
if Team[1].AI_Automated then
call AICommander_RefineAbilities.evaluate(1)
call AICommander_WarHallAbilities.evaluate(1)
endif
if Team[2].AI_Automated then
call AICommander_RefineAbilities.evaluate(2)
call AICommander_WarHallAbilities.evaluate(2)
endif
endif
loop
exitwhen i > 11
set ai = thistype[i]
if ai.activated then
if Game.GameStarted and not Game.GameOver and UnitAlive(ai.playerHero.hero) then
if ai.randomBackCounter > 0 then
set ai.randomBackCounter = ai.randomBackCounter - 1
endif
if Game.Mode == GAME_MODE_NORMAL then
call ActionsNormal(ai)
if ai.inBase and Game.GameStarted and not ai.basic then
call ai.itemBuild.purchaseItem(true)
else
if Game.GameStarted then
if BlzGetUnitAbilityCooldownRemaining(Baul[i],'A09S') == 0 then
if ai.itemBuild.purchaseItem(false) then
call BlzStartUnitAbilityCooldown(Baul[i],'A09S',30)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl",ai.playerHero.hero,"overhead"))
endif
endif
endif
endif
elseif Game.Mode == GAME_MODE_LMS then
if Game.RoundStarted then
call ActionsLMS(ai)
else
call ai.itemBuild.purchaseItem(true)
endif
endif
endif
endif
set i = i + 1
endloop
endmethod
public static method create takes Hero h, boolean b, trigger e returns thistype
local player p = GetOwningPlayer(h.hero)
local thistype this = thistype[GetPlayerId(p)]
local real x
local real y
if Timer == null then
set Timer = CreateTimer()
call TimerStart(Timer,PERIODIC,true,function thistype.Loop)
endif
set eventTrig = e
set activated = true
set playerHero = h
set team = GetUnitTeam(h.hero)
set basic = b
if not basic then
if Game.Mode == GAME_MODE_NORMAL then
if team == 1 then
set x = GetRandomReal(GetRectMinX(gg_rct_BHtoB1a),GetRectMaxX(gg_rct_BHtoB1a))
set y = GetRandomReal(GetRectMinY(gg_rct_BHtoB1a),GetRectMaxY(gg_rct_BHtoB1a))
else
set x = GetRandomReal(GetRectMinX(gg_rct_BAtoB3a),GetRectMaxX(gg_rct_BAtoB3a))
set y = GetRandomReal(GetRectMinY(gg_rct_BAtoB3a),GetRectMaxY(gg_rct_BAtoB3a))
endif
call IssuePointOrder(h.hero,"move",x,y)
set returnToBase = true
else
set returnToBase = false
endif
endif
if IsUnitType(h.hero,UNIT_TYPE_RANGED_ATTACKER) then
set ranged = true
else
set ranged = false
endif
set enumGroup = CreateGroup()
set healX = team.startX
set healY = team.startY
set lastTargetX = 0
set lastTargetY = 0
set guardArea = 0
set targetBase = 0
set targetMine = 0
set state = 0
set threatAlly = null
set reachesTarget = true
set retreating = false
set channelingOrder = 0
set busyTimes = 0
set moveCounter = 0
set randomBackCounter = 0
set targetRune = 0
if GetAIDifficulty(p) == AI_DIFFICULTY_NEWBIE then
set courageBase = 1.0
elseif GetAIDifficulty(p) == AI_DIFFICULTY_NORMAL then
set courageBase = 1.2
elseif GetAIDifficulty(p) == AI_DIFFICULTY_INSANE then
set courageBase = 1.6
endif
set courageAdd = 0.0
set abilityBuild = AbilityBuild.create(this)
set upgradeBuild = UpgradeBuild.create(this)
set itemBuild = ItemBuild.create(this)
set h.heroAI = this
if not basic then
call TriggerRegisterUnitEvent(OnAttack,h.hero,EVENT_UNIT_ATTACKED)
endif
set p = null
return this
endmethod
endstruct
module AIHandler
static AICore AI
static trigger eventTrigger
private static method Listener takes nothing returns nothing
static if thistype.onLoop.exists then
call thistype.onLoop()
endif
endmethod
public static method StartAI takes Hero h, boolean b returns nothing
set eventTrigger = CreateTrigger()
set AI = AICore.create(h,b,eventTrigger)
call TriggerAddCondition(eventTrigger,Filter(function thistype.Listener))
endmethod
endmodule
private function onAttack takes nothing returns nothing
local unit t = GetTriggerUnit()
local unit u = GetAttacker()
local integer idt = GetUnitTypeId(t)
local integer idu = GetUnitTypeId(u)
local integer lvl = GetHeroLevel(t)
local Hero h = GetUnitData(t,"HeroIndex")
local ControlBase cb = GetUnitData(t,"BaseControl")
local real dis = Distance(h.heroAI.hx,h.heroAI.hy,h.heroAI.retreatX,h.heroAI.retreatY)
local boolean b = h.heroAI.busyTimes == 0 and h.heroAI.channelingOrder == 0
local integer r
if not h.heroAI.returnToBase and cb == 0 and b and not h.heroAI.riskAction and h.heroAI.randomBackCounter == 0 then
//Tower attacker
if idu == 'n009' or idu == 'n006' and h.heroAI.enemyHeroCount == 0 and h.heroAI.state != STATE_TO_OBELISK then
if h.PrimaryAttribute == 1 or h.PrimaryAttribute == 2 then
if h.heroAI.alliedUnitCount > 0 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 3
set h.heroAI.randomBackCounter = 6
elseif h.heroAI.percentLife < 0.35 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 3
set h.heroAI.randomBackCounter = 6
endif
else
if h.heroAI.alliedUnitCount > 0 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 3
set h.heroAI.randomBackCounter = 6
else
if h.heroAI.percentLife < 0.25 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 3
set h.heroAI.randomBackCounter = 6
endif
endif
endif
set t = null
set u = null
return
endif
//Unit attacker
if not IsUnitType(u,UNIT_TYPE_HERO) and h.heroAI.enemyHeroCount == 0 then
if h.heroAI.state != STATE_TO_OBELISK and GetOwningPlayer(u) != Game.PLAYER_NEUTRAL_HOSTILE then
if h.heroAI.goldUnit != null then
if h.heroAI.percentLife < 0.30 or h.heroAI.alliedUnitCount > 1 and h.heroAI.goldUnit == u then
if dis > 300 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 2
set h.heroAI.randomBackCounter = 6
endif
endif
else
if h.heroAI.alliedUnitCount == 0 and h.heroAI.alliedHeroCount == 0 then
if h.heroAI.enemyUnitCount >= (GetHeroLevel(h.hero)/2) + 2 then
if dis > 300 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 2
set h.heroAI.randomBackCounter = 6
endif
endif
else
if h.heroAI.enemyUnitCount >= h.heroAI.alliedUnitCount and h.heroAI.alliedHeroCount == 0 then
if dis > 300 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 2
set h.heroAI.randomBackCounter = 6
endif
endif
endif
endif
endif
set t = null
set u = null
return
endif
//Hero attacker
if not IsUnitIllusion(u) and IsUnitType(u,UNIT_TYPE_HERO) then
if h.PrimaryAttribute == 1 then
set r = 100 - R2I(h.heroAI.percentLife * 100)
if GetRandomInt(1,100) <= r and GetUnitLifePercent(u) > (h.heroAI.percentLife * 100) + 15.00 and h.heroAI.enemyHeroCount > h.heroAI.alliedHeroCount then
if dis > 300 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 1
set h.heroAI.randomBackCounter = 4
endif
endif
endif
if h.PrimaryAttribute == 2 then
set r = 125 - R2I(h.heroAI.percentLife * 100)
if GetRandomInt(1,100) <= r and GetUnitLifePercent(u) > (h.heroAI.percentLife * 100) + 25.00 and h.heroAI.enemyHeroCount >= h.heroAI.alliedHeroCount then
if dis > 300 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 1
set h.heroAI.randomBackCounter = 4
endif
endif
endif
if h.PrimaryAttribute == 3 then
set r = 75 - R2I(h.heroAI.percentLife * 100)
if GetRandomInt(1,100) <= r and GetUnitLifePercent(u) > (h.heroAI.percentLife * 100) + 10.00 and h.heroAI.enemyHeroCount > h.heroAI.alliedHeroCount then
if dis > 300 then
call h.heroAI.retreat()
set h.heroAI.busyTimes = 1
set h.heroAI.randomBackCounter = 4
endif
endif
endif
set t = null
set u = null
return
endif
endif
endfunction
private function ChooseHeroes takes nothing returns nothing
local player p = Player(TEMP)
if GetPlayerController(p) == MAP_CONTROL_COMPUTER then
call HeroSelectorDoRandom(p)
endif
set p = null
set TEMP = TEMP + 1
if TEMP > 11 then
call DestroyTrigger(GetTriggeringTrigger())
endif
endfunction
private function SetupAI takes nothing returns nothing
local timer t = NewTimer()
set TEMP = 2
call TimerStart(t,1.0,true,function ChooseHeroes)
set t = null
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
set OnAttack = CreateTrigger()
call TriggerAddCondition(OnAttack,function onAttack)
call TriggerRegisterTimerEvent(t,Game.PICK_TIME * 0.75,false)
call TriggerAddCondition(t,function SetupAI)
set t = null
endfunction
endlibrary
scope AIExtras
public function AIAttendObjective takes Team t, Base b, GoldMine g returns nothing
local integer i
local integer j
local Players p
if t == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
set p = Players[i]
if p.isPlaying and p.hero.heroAI != -1 then
if not p.hero.heroAI.returnToBase then
if b != 0 then
if p.hero.heroAI.nearestBase == b then
if p.hero.heroAI.state != 8 and not p.hero.heroAI.returnToBase then
call p.hero.heroAI.IssueOrder(null,ORDER_attack,b.x,b.y)
set p.hero.heroAI.customTargetX = b.x
set p.hero.heroAI.customTargetY = b.y
set p.hero.heroAI.customTargetDuration = 2.0
set p.hero.heroAI.courageAdd = 0.5
set p.hero.heroAI.reachesTarget = false
set p.hero.heroAI.state = 8
endif
elseif b.owner == t then
if p.hero.heroAI.enemyHeroCount == 0 and not p.hero.heroAI.returnToBase then
if BlzGetUnitAbilityCooldownRemaining(p.hero.hero,'A00A') == 0 then
call AICore.HeroOrderTP(p.hero,b.tower,0,0)
endif
endif
endif
elseif g != 0 then
if p.hero.heroAI.nearestMine == g then
if p.hero.heroAI.state != 8 and not p.hero.heroAI.returnToBase then
call p.hero.heroAI.IssueOrder(null,ORDER_attack,g.x,g.y)
set p.hero.heroAI.customTargetX = g.x
set p.hero.heroAI.customTargetY = g.y
set p.hero.heroAI.customTargetDuration = 2.0
set p.hero.heroAI.courageAdd = 0.5
set p.hero.heroAI.reachesTarget = false
set p.hero.heroAI.state = 8
endif
elseif g.owner == t then
if p.hero.heroAI.enemyHeroCount == 0 and not p.hero.heroAI.returnToBase then
if BlzGetUnitAbilityCooldownRemaining(p.hero.hero,'A00A') == 0 then
call AICore.HeroOrderTP(p.hero,g.gold,0,0)
endif
endif
endif
else
if Distance(p.hero.heroAI.hx,p.hero.heroAI.hy,AncientObelisk.x,AncientObelisk.y) <= 2000 then
if p.hero.heroAI.state != 8 and not p.hero.heroAI.returnToBase then
call p.hero.heroAI.IssueOrder(null,ORDER_attack,AncientObelisk.x,AncientObelisk.y)
set p.hero.heroAI.customTargetX = AncientObelisk.x
set p.hero.heroAI.customTargetY = AncientObelisk.y
set p.hero.heroAI.customTargetDuration = 2.0
set p.hero.heroAI.courageAdd = 1.0
set p.hero.heroAI.reachesTarget = false
set p.hero.heroAI.state = 8
endif
else
if p.hero.heroAI.enemyHeroCount == 0 and not p.hero.heroAI.returnToBase and AncientObelisk.owner == t then
if BlzGetUnitAbilityCooldownRemaining(p.hero.hero,'A00A') == 0 then
call AICore.HeroOrderTP(p.hero,AncientObelisk.obelisk,0,0)
endif
endif
endif
endif
endif
endif
set i = i + 1
exitwhen i > j
endloop
endfunction
public function CheckForNearbyObjective takes real x, real y returns integer
local integer i = 0
if not Game.GameStarted then
return i
endif
if Game.Mode == GAME_MODE_NORMAL then
loop
set i = i + 1
if Distance(x,y,Base[i].x,Base[i].y) <= 300 then
return i
endif
if Distance(x,y,GoldMine[i].x,GoldMine[i].y) <= 300 then
return 10 + i
endif
exitwhen i == 4
endloop
if Distance(x,y,AncientObelisk.x,AncientObelisk.y) <= 300 then
return -1
endif
endif
return 0
endfunction
public function AILookAtZone takes Team t, real x, real y, real a, real d returns nothing
local integer i
local integer j
local Players p
if t == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
set p = Players[i]
if p.isPlaying and p.hero.heroAI != -1 then
if Distance(p.hero.heroAI.hx,p.hero.heroAI.hy,x,y) <= a and p.hero.heroAI.state != 8 and not p.hero.heroAI.returnToBase then
call p.hero.heroAI.IssueOrder(null,ORDER_attack,x,y)
set p.hero.heroAI.customTargetX = x
set p.hero.heroAI.customTargetY = y
set p.hero.heroAI.customTargetDuration = d
set p.hero.heroAI.courageAdd = 2.0
set p.hero.heroAI.reachesTarget = false
set p.hero.heroAI.state = 8
endif
endif
set i = i + 1
exitwhen i > j
endloop
endfunction
public function AILeaveZone takes Team t, real x, real y, real a returns nothing
local integer i
local integer j
local Players p
local real xt
local real yt
local real at
if t == 1 then
set i = 2
set j = 6
else
set i = 7
set j = 11
endif
loop
set p = Players[i]
if p.isPlaying and p.hero.heroAI != -1 then
if Distance(p.hero.heroAI.hx,p.hero.heroAI.hy,x,y) <= a then
set at = Angle(x,y,p.hero.heroAI.hx,p.hero.heroAI.hy)
set xt = x + (a + 100) * Cos(at)
set yt = y + (a + 100) * Sin(at)
call p.hero.heroAI.IssueOrder(null,ORDER_move,xt,yt)
set p.hero.heroAI.busyTimes = 2
endif
endif
set i = i + 1
exitwhen i > j
endloop
endfunction
public function Setup takes nothing returns nothing
endfunction
endscope
scope AICommander
private function CommanderMineCast takes GoldMine g, Team t, Team t2, integer ha, integer he, boolean lossing returns boolean
local integer chance = 0
if not g.defenders.passive then
if g == 1 or g == 3 then
set chance = chance + 25
endif
if t2.commander.commanderAssault.mineTarget == g then
set chance = chance + 25
endif
if lossing then
set chance = chance + 25
endif
set chance = chance + 5 * he
set chance = chance + 5 * ha
set chance = chance / 2
if GetRandomInt(1,125) <= chance then
return true
endif
endif
return false
endfunction
private function CommanderTowerCast takes Base b, Team t, Team t2, integer ha, integer he, boolean lossing returns boolean
local real hp = GetUnitLifePercent(b.tower)
local integer pm1 = t.playerCount/2
local integer pm2 = t2.playerCount/2
local integer chance = 0
if IsUnitInCombat(b.tower) and GetUnitCurrentOrder(b.tower) == ORDER_attack then
if b == 1 or b == 3 then
set chance = chance + 25
if b.owner == t2 then
set chance = chance + 25
endif
endif
if t2.commander.commanderAssault.baseTarget == b then
set chance = chance + 25
endif
set chance = chance + (100 - R2I(hp)) / 2
set chance = chance + 10 * he
set chance = chance + 10 * ha
set chance = chance / 2
if GetRandomInt(1,200) <= chance then
return true
endif
endif
return false
endfunction
public function WarHallAbilities takes Team t returns nothing
local real cd1 = BlzGetUnitAbilityCooldownRemaining(t.warHall,'A0BJ') //Bombard
local real cd2 = BlzGetUnitAbilityCooldownRemaining(t.warHall,'A0BK') //Commander Assault
local real cd3 = BlzGetUnitAbilityCooldownRemaining(t.warHall,'A02U') //Call To Arms
local real cd4 = BlzGetUnitAbilityCooldownRemaining(t.warHall,'A0D9') //Sanctuary
local Team t2 = 2/t
local boolean lossing = t.resources < t2. resources
local integer ha
local integer he
local integer i = 0
local integer j = 0
local Base btemp = 0
if lossing then
set i = t2.resources - t.resources
else
set i = t.resources - t2.resources
endif
if cd1 == 0 then
if AncientObelisk.owner == 0 then
set he = AncientObelisk.getCurrentHeroes(t2)
set ha = AncientObelisk.getCurrentHeroes(t)
if IsUnitEnemy(AncientObelisk.currentHero,t.captain) and AncientObelisk.time >= 10.0 and ha != 0 then
call IssuePointOrderById(t.warHall,ORDER_rainoffire,AncientObelisk.x,AncientObelisk.y)
return
endif
endif
endif
if cd3 == 0 then
if t == 1 then
if Base[1].owner == t then
set btemp = 1
elseif Base[2].owner == t then
set btemp = 2
elseif Base[4].owner == t then
set btemp = 4
elseif Base[3].owner == t then
set btemp = 3
endif
elseif t == 2 then
if Base[3].owner == t then
set btemp = 3
elseif Base[4].owner == t then
set btemp = 4
elseif Base[2].owner == t then
set btemp = 2
elseif Base[1].owner == t then
set btemp = 1
endif
endif
if btemp != 0 then
if lossing then
if i > 100 then
call IssueTargetOrderById(t.warHall,ORDER_purge,btemp.tower)
return
endif
else
if i > 150 then
call IssueTargetOrderById(t.warHall,ORDER_purge,btemp.tower)
return
endif
endif
endif
endif
if cd2 == 0 then
loop
set j = j + 1
set ha = Base[j].getCurrentHeroes(t)
set he = Base[j].getCurrentHeroes(t2)
if CommanderTowerCast(Base[j],t,t2,ha,he,lossing) then
call IssuePointOrderById(t.warHall,ORDER_rainofchaos,Base[j].x,Base[j].y)
return
endif
set ha = GoldMine[j].getCurrentHeroes(t)
set he = GoldMine[j].getCurrentHeroes(t2)
if CommanderMineCast(GoldMine[j],t,t2,ha,he,lossing) then
call IssuePointOrderById(t.warHall,ORDER_rainofchaos,GoldMine[j].x,GoldMine[j].y)
return
endif
exitwhen j == 4
endloop
endif
if cd4 == 0 then
endif
endfunction
public function RefineAbilities takes Team t returns nothing
local real cd2
local integer ha
local integer he
local Team t2
local integer i = 0
local real hp
local boolean lossing
if t.commander.assaultActive then
return
endif
if t.AI_Automated then
set t2 = 2/t
set lossing = t.resources < t2. resources
set cd2 = BlzGetUnitAbilityCooldownRemaining(t.commander.heroUnit,'A008') //Refine
if cd2 == 0 then
//Refine Defences
set i = 0
loop
set i = i + 1
if Base[i].owner == t then
if IsUnitInCombat(Base[i].tower) and Base[i].getCurrentHeroes(t2) >= t2.playerCount/2 then
set hp = GetUnitLifePercent(Base[i].tower)
if lossing then
if hp <= 60 and Base[i].getCurrentHeroes(t) == 0 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_auraunholy)
return
endif
if hp <= 10 and Base[i].getCurrentHeroes(t) != 0 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_auraunholy)
return
endif
else
if hp <= 35 and Base[i].getCurrentHeroes(t) == 0 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_auraunholy)
return
endif
if t.heroesDeath >= t.playerCount/2 and t.bases == 1 and hp <= 50 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_auraunholy)
return
endif
endif
endif
endif
if GoldMine[i].owner == t then
if not GoldMine[i].defenders.passive and GoldMine[i].getCurrentHeroes(t2) >= t2.playerCount/2 then
if lossing then
set ha = GoldMine[i].getCurrentHeroes(t)
if ha <= GoldMine[i].getCurrentHeroes(t2) and ha != 0 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_auraunholy)
return
endif
else
if t.heroesDeath >= t.playerCount/2 and t.goldmines >= 3 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_auraunholy)
return
endif
endif
endif
endif
exitwhen i == 4
endloop
//Refine Weapons
set i = 0
loop
set i = i + 1
if Base[i].owner == t then
if IsUnitInCombat(Base[i].tower) then
set hp = GetUnitLifePercent(Base[i].tower)
set he = Base[i].getCurrentHeroes(t2)
set ha = Base[i].getCurrentHeroes(t)
if t2.commander.commanderAssault.baseTarget == Base[i] then
if hp > 50 and he >= ha and ha != 0 and he >= t2.playerCount/2 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_animatedead)
return
endif
endif
if hp > 75 and he >= ha and he >= t2.playerCount/2 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_animatedead)
return
endif
endif
endif
if GoldMine[i].owner == t then
set ha = GoldMine[i].getCurrentHeroes(t)
set he = GoldMine[i].getCurrentHeroes(t2)
if not GoldMine[i].defenders.passive and GoldMine[i].defenders.units.size == 3 then
if he >= t2.playerCount/2 and he > ha and ha != 0 then
call IssueImmediateOrderById(t.commander.heroUnit,ORDER_animatedead)
return
endif
endif
endif
exitwhen i == 4
endloop
endif
endif
endfunction
endscope
library AIRegion uses MiscLibrary
struct AIRegion extends array
private static trigger Enter
private static trigger Leave
private static region array Mines
private static region array Bases
private static region Obelisk
private static group Registered = null
private static method onEnter takes nothing returns nothing
local unit u = GetEnteringUnit()
local region r
local integer i = 1
local Team t
if IsUnitInGroup(u,Registered) then
set r = GetTriggeringRegion()
set t = GetUnitTeam(u)
loop
if r == Bases[i] then
call Base[i].addCurrentHeroes(t,1)
exitwhen true
endif
if r == Mines[i] then
call GoldMine[i].addCurrentHeroes(t,1)
exitwhen true
endif
set i = i + 1
exitwhen i > 4
endloop
if r == Obelisk then
call AncientObelisk.addCurrentHeroes(t,1)
endif
set r = null
endif
set u = null
endmethod
private static method onLeave takes nothing returns nothing
local unit u = GetLeavingUnit()
local region r
local integer i = 1
local Team t
if IsUnitInGroup(u,Registered) then
set r = GetTriggeringRegion()
set t = GetUnitTeam(u)
loop
if r == Bases[i] then
call Base[i].addCurrentHeroes(t,-1)
exitwhen true
endif
if r == Mines[i] then
call GoldMine[i].addCurrentHeroes(t,-1)
exitwhen true
endif
set i = i + 1
exitwhen i > 4
endloop
if r == Obelisk then
call AncientObelisk.addCurrentHeroes(t,-1)
endif
set r = null
endif
set u = null
endmethod
public static method RegisterHero takes unit u returns nothing
if not IsUnitInGroup(u,Registered) then
call GroupAddUnit(Registered,u)
endif
endmethod
public static method Init takes nothing returns nothing
set Enter = CreateTrigger()
set Leave = CreateTrigger()
set Registered = CreateGroup()
set Bases[1] = CreateRegion()
set Bases[2] = CreateRegion()
set Bases[3] = CreateRegion()
set Bases[4] = CreateRegion()
set Mines[1] = CreateRegion()
set Mines[2] = CreateRegion()
set Mines[3] = CreateRegion()
set Mines[4] = CreateRegion()
set Obelisk = CreateRegion()
call RegionAddRect(Bases[1],gg_rct_AIBase1)
call RegionAddRect(Bases[2],gg_rct_AIBase2)
call RegionAddRect(Bases[3],gg_rct_AIBase3)
call RegionAddRect(Bases[4],gg_rct_AIBase4)
call RegionAddRect(Mines[1],gg_rct_AIGoldMine1)
call RegionAddRect(Mines[2],gg_rct_AIGoldMine2)
call RegionAddRect(Mines[3],gg_rct_AIGoldMine3)
call RegionAddRect(Mines[4],gg_rct_AIGoldMine4)
call RegionAddRect(Obelisk,gg_rct_ObeliskArea)
call TriggerRegisterEnterRegion(Enter,Bases[1],null)
call TriggerRegisterEnterRegion(Enter,Bases[2],null)
call TriggerRegisterEnterRegion(Enter,Bases[3],null)
call TriggerRegisterEnterRegion(Enter,Bases[4],null)
call TriggerRegisterEnterRegion(Enter,Mines[1],null)
call TriggerRegisterEnterRegion(Enter,Mines[2],null)
call TriggerRegisterEnterRegion(Enter,Mines[3],null)
call TriggerRegisterEnterRegion(Enter,Mines[4],null)
call TriggerRegisterEnterRegion(Enter,Obelisk,null)
call TriggerRegisterLeaveRegion(Leave,Bases[1],null)
call TriggerRegisterLeaveRegion(Leave,Bases[2],null)
call TriggerRegisterLeaveRegion(Leave,Bases[3],null)
call TriggerRegisterLeaveRegion(Leave,Bases[4],null)
call TriggerRegisterLeaveRegion(Leave,Mines[1],null)
call TriggerRegisterLeaveRegion(Leave,Mines[2],null)
call TriggerRegisterLeaveRegion(Leave,Mines[3],null)
call TriggerRegisterLeaveRegion(Leave,Mines[4],null)
call TriggerRegisterLeaveRegion(Leave,Obelisk,null)
call TriggerAddCondition(Enter,function thistype.onEnter)
call TriggerAddCondition(Leave,function thistype.onLeave)
endmethod
endstruct
endlibrary
library ItemBuild uses Item
globals
private integer array consumables
endglobals
struct ItemBuild extends array
implement Alloc
AICore heroAI
player owner
item startItem1
item startItem2
item consumable1 //curacion1
item consumable2 //curacion2
integer startItemID1
integer startItemID2
integer startItemR1
integer startItemR2
integer purchasedCount
LinkedList itemdatas
Link currentLink
boolean saveForEnchant
boolean completed
integer startBuild
EnchantBuild enchantBuild
public method useConsumables takes nothing returns nothing
local item c = consumable1
local integer id = GetItemTypeId(c)
if c != null then
if id == 'plcl' then
if heroAI.percentLife <= 0.25 then
call UnitUseItem(heroAI.playerHero.hero,c)
endif
endif
endif
set c = consumable2
set id = GetItemTypeId(c)
if c != null then
if id == 'pinv' then
if heroAI.percentLife <= 0.15 then
call UnitUseItem(heroAI.playerHero.hero,c)
endif
endif
endif
set c = null
endmethod
public method purchaseConsumables takes integer g returns integer
local LinkedList inv = GetUnitData(heroAI.playerHero.hero,"UnitItems")
local integer slots = 6 - inv.size
local integer cost = 0
local ItemData idd
//Verify early consumables
if not UnitHasItem(heroAI.playerHero.hero,consumable1) and consumable1 != null then
set consumable1 = null
endif
if not UnitHasItem(heroAI.playerHero.hero,consumable2) and consumable2 != null then
set consumable2 = null
endif
//consumable 1
if consumable1 == null and slots != 0 then
if GetHeroLevel(heroAI.playerHero.hero) < 8 then
set idd = consumables[GetRandomInt(1,2)]
else
set idd = consumables[GetRandomInt(2,3)]
endif
if g >= idd.goldCost then
set consumable1 = CreateItem(idd.itemID,0,0)
call UnitAddItem(heroAI.playerHero.hero,consumable1)
set slots = slots - 1
set cost = cost + idd.goldCost
set g = g - idd.goldCost
endif
endif
if consumable2 == null and slots != 0 then
set idd = consumables[GetRandomInt(4,7)]
if g >= idd.goldCost then
set consumable2 = CreateItem(idd.itemID,0,0)
call UnitAddItem(heroAI.playerHero.hero,consumable2)
set cost = cost + idd.goldCost
set g = g - idd.goldCost
endif
endif
return cost
endmethod
public method purchaseStartingItems takes nothing returns nothing
local ItemData idd
//purchase Starting Items
if startItemID1 != 0 and startItem1 == null then
set idd = GetItemDataByID(startItemID1)
if idd != 0 then
set startItem1 = CreateItem(idd.itemID,0,0)
call UnitAddItem(heroAI.playerHero.hero,startItem1)
endif
endif
if startItemID2 != 0 and startItem2 == null then
set idd = GetItemDataByID(startItemID2)
if idd != 0 then
set startItem2 = CreateItem(idd.itemID,0,0)
call UnitAddItem(heroAI.playerHero.hero,startItem2)
endif
endif
endmethod
public method removeStartingItem takes nothing returns boolean
local Item it
if purchasedCount == startItemR1 then
if startItem1 != null then
set it = GetItemUserData(startItem1)
call it.destroy()
set startItem1 = null
return true
endif
endif
if purchasedCount == startItemR2 then
if startItem2 != null then
set it = GetItemUserData(startItem2)
call it.destroy()
set startItem2 = null
return true
endif
endif
return false
endmethod
public method removeConsumable takes nothing returns boolean
local Item it
if consumable2 != null then
set it = GetItemUserData(consumable2)
call AddPlayerGold(owner,it.goldCost)
call it.destroy()
set consumable2 = null
return true
endif
if consumable1 != null then
set it = GetItemUserData(consumable1)
call AddPlayerGold(owner,it.goldCost)
call it.destroy()
set consumable1 = null
return true
endif
return false
endmethod
public method purchaseItem takes boolean onBase returns boolean
local integer g = GetPlayerState(owner,PLAYER_STATE_RESOURCE_GOLD)
local integer ge = 0
local item i
local LinkedList inv = GetUnitData(heroAI.playerHero.hero,"UnitItems")
local Item it
local ItemData idd
local boolean next = false
if completed or itemdatas.size == 0 then
if not enchantBuild.allEnchanted and onBase then
call enchantBuild.enchantItems(heroAI.playerHero.hero,g,0)
endif
return false
endif
if currentLink == 0 then
set currentLink = itemdatas.head
endif
set idd = currentLink.data
set it = GetUnitItemOfType(heroAI.playerHero.hero,idd.itemID)
if not enchantBuild.allEnchanted and onBase then
call enchantBuild.enchantItems(heroAI.playerHero.hero,g,0)
endif
if it != 0 then
//tiene el item
if g >= 500 and not saveForEnchant then
call it.levelup()
call AddPlayerGold(owner,-500)
set g = g - 500
set next = true
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl",heroAI.playerHero.hero,"origin"))
if it.tier == 3 then
if it.itemID == enchantBuild.weaponItemID or it.itemID == enchantBuild.armorItemID then
set saveForEnchant = true
endif
endif
endif
else
if g >= idd.goldCost and not saveForEnchant then
set purchasedCount = purchasedCount + 1
call removeStartingItem()
if inv.size == bj_MAX_INVENTORY then
if removeConsumable() then
set g = GetPlayerState(owner,PLAYER_STATE_RESOURCE_GOLD)
endif
endif
call AddPlayerGold(owner,-idd.goldCost)
set i = CreateItem(idd.itemID,0,0)
if not UnitAddItem(heroAI.playerHero.hero,i) then
call RemoveItem(i)
//call BJDebugMsg("AI Item Purchase: Failed for "+GetUnitName(heroAI.playerHero.hero)+"-"+I2S(inv.size))
else
set next = true
endif
set i = null
endif
endif
if next then
set currentLink = currentLink.next
if currentLink == 0 then
set completed = true
endif
endif
if onBase then
set ge = purchaseConsumables(g)
if ge != 0 then
call AddPlayerGold(owner,-ge)
endif
endif
return next
endmethod
public method add takes integer id returns nothing
local ItemData it = GetItemDataByID(id)
call itemdatas.addLast(it)
endmethod
public static method create takes AICore ai returns thistype
local thistype this = thistype.allocate()
set itemdatas = LinkedList.create()
set owner = GetOwningPlayer(ai.playerHero.hero)
set heroAI = ai
set currentLink = 0
set purchasedCount = 0
set completed = false
set startItem1 = null
set startItem2 = null
set startItemID1 = 0
set startItemID2 = 0
set startItemR1 = 0
set startItemR2 = 0
set consumable1 = null
set consumable2 = null
set saveForEnchant = false
set enchantBuild = EnchantBuild.create()
set enchantBuild.itemBuild = this
return this
endmethod
endstruct
public function Setup takes nothing returns nothing
//consumable healing 1,2,3,4
set consumables[1] = GetItemDataByID('hslv')
set consumables[2] = GetItemDataByID('rej3')
set consumables[3] = GetItemDataByID('plcl')
set consumables[4] = GetItemDataByID('stwp')
//Consumable Defensive
set consumables[5] = GetItemDataByID('mcri')
set consumables[6] = GetItemDataByID('pinv')
set consumables[7] = GetItemDataByID('pman')
endfunction
endlibrary
scope ItemEnchant
struct EnchantBuild extends array
implement Alloc
ItemBuild itemBuild
integer random1
integer random2
integer weapon
integer armor
integer weaponItemID
integer armorItemID
boolean weaponDone
boolean armorDone
boolean allEnchanted
public method enchantItems takes unit u, integer g, integer h returns nothing
local LinkedList inv
local Item it
local Link link
local Enchant e = 0
local integer r
local boolean ee = g >= 300
local boolean eb = g >= 1000
local integer total = 0
if ee or eb then
set inv = GetUnitData(u,"UnitItems")
set link = inv.head
loop
exitwhen link == 0
set it = link.data
if it.enchant != 0 then
set total = total + 1
if total == 6 then
set allEnchanted = true
endif
endif
if it.itemType >= 2 and it.enchant == 0 then
if it.itemID == armorItemID then
if eb and it.tier == 3 and not armorDone and armor != 0 then
set e = Enchant.GetEnchantByID(armor)
set armorDone = true
set itemBuild.saveForEnchant = false
endif
elseif it.itemID == weaponItemID then
if eb and it.tier == 3 and not weaponDone and weapon != 0 then
set e = Enchant.GetEnchantByID(weapon)
set weaponDone = true
set itemBuild.saveForEnchant = false
endif
else
if ee and GetRandomInt(1,100) <= 10 * (g / 500) then
set r = GetRandomInt(1,2)
if r == 1 then
set e = Enchant.GetEnchantByID(random1)
elseif r == 2 then
set e = Enchant.GetEnchantByID(random2)
endif
endif
endif
if e != 0 then
set it.enchant = e
call BlzSetItemExtendedTooltip(it.itemS,BuildText(it,it.tier))
call e.add(u,it)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl",u,"origin"))
if e.enchantType == ENCHANT_TYPE_ANY then
call AddPlayerGold(GetOwningPlayer(u),-ENCHANT_COST_NORMAL)
else
call AddPlayerGold(GetOwningPlayer(u),-ENCHANT_COST_EFFECT)
endif
endif
endif
set e = 0
set link = link.next
endloop
endif
endmethod
public method SetWeaponEnchantEffect takes integer eid, integer iid returns nothing
set weapon = eid
set weaponItemID = iid
endmethod
public method SetArmorEnchantEffect takes integer eid, integer iid returns nothing
set armor = eid
set armorItemID = iid
endmethod
public static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set weaponDone = false
set armorDone = false
set weaponItemID = 0
set armorItemID = 0
set allEnchanted = false
return this
endmethod
endstruct
endscope
library HeroAIThreat uses BuffManager, TeamLib
globals
private constant real UNIT_FACTOR = 0.20
private constant real HERO_FACTOR = 1.00
private constant real STRUCTURE_FACTOR = 1.00
endglobals
private function BaseViewedThreat takes unit u, boolean hero, boolean structure returns real
local real lifePercent
local real manaPercent
set lifePercent = GetUnitStatePercent(u, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE)
if hero then
set manaPercent = GetUnitStatePercent(u, UNIT_STATE_MANA, UNIT_STATE_MAX_MANA)
return (GetHeroLevel(u) * 10) + (lifePercent * 0.75) + (manaPercent * 0.25)
endif
if structure then
return lifePercent
endif
return lifePercent
endfunction
private function BaseThreatFactor takes unit u, boolean hero, boolean structure returns real
if hero then
return HERO_FACTOR
endif
if structure then
return STRUCTURE_FACTOR
endif
return UNIT_FACTOR
endfunction
module HeroAIThreat
real threat
real threatThreshold
unit threatEnemy
unit threatAlly
static method weightThreat takes unit u, integer id returns real
local boolean hero = IsUnitType(u,UNIT_TYPE_HERO)
local boolean structure = IsUnitType(u,UNIT_TYPE_STRUCTURE)
local real threat = BaseViewedThreat(u,hero,structure)
local real factor = BaseThreatFactor(u,hero,structure)
local Base ba
if structure then
if id == 'n006' or id == 'n009' then
set ba = Base.GetBaseFromTower(u)
if ba != 0 and ba.owner != 0 then
set factor = factor + (ba.baseTroops.level - 1) * 0.20
if UnitHasBuff(u,RefineWeapons.buff) then
set factor = factor + 3.0
endif
if UnitHasBuff(u,RefineDefences.buff) then
set factor = factor + 3.0
endif
endif
endif
if id == 'h007' or id == 'h008' then
set factor = factor + 2.0
endif
else
if id == 'H00W' or id == 'H00T' then
set factor = factor + 2.0
endif
endif
if threat > 0 then
return threat * factor
endif
return 0.
endmethod
method IssueOrder takes unit target, integer order, real x, real y returns nothing
local real xt
local real yt
local real a
local real d
local integer sw = 0
if channelingOrder != 0 or busyTimes != 0 then
return
endif
set lastOrder = order
if target != null then
if GetUnitCurrentOrder(playerHero.hero) != order or target != lastTarget then
set lastTarget = target
set lastTargetX = 0
set lastTargetY = 0
call IssueTargetOrderById(playerHero.hero,order,target)
set sw = 1
endif
else
set lastTarget = null
if x != lastTargetX or y != lastTargetY then
set lastTargetX = x
set lastTargetY = y
call IssuePointOrderById(playerHero.hero,order,x,y)
else
if GetUnitCurrentOrder(playerHero.hero) != order then
call IssuePointOrderById(playerHero.hero,order,x,y)
endif
endif
set sw = 2
endif
if playerHero.TypeID == 'HLM1' then
if AILA.petBusy == 0 and AILA.petOrder == 0 and AILA.pet != null then
if sw == 1 then
call IssueTargetOrderById(AILA.pet,order,target)
elseif sw == 2 then
call IssuePointOrderById(AILA.pet,order,x,y)
endif
endif
elseif playerHero.TypeID == 'HEB1' then
if AIEB.golem1 != null then
if sw == 1 and not AIEB.cast[1] then
call IssueTargetOrderById(AIEB.golem1,order,target)
elseif sw == 2 and not AIEB.cast[1] then
if AIEB.petDist1 > 500 then
call IssuePointOrderById(AIEB.golem1,order,hx,hy)
else
call IssuePointOrderById(AIEB.golem1,order,x,y)
endif
endif
endif
if AIEB.golem2 != null then
if sw == 1 and not AIEB.cast[2] then
call IssueTargetOrderById(AIEB.golem2,order,target)
elseif sw == 2 and not AIEB.cast[2] then
if AIEB.petDist2 > 500 then
call IssuePointOrderById(AIEB.golem2,order,hx,hy)
else
call IssuePointOrderById(AIEB.golem2,order,x,y)
endif
endif
endif
elseif playerHero.TypeID == 'HZE1' then
if AIZE.bc != 0 then
if sw == 1 and AIZE.sb == 0 then
call IssueTargetOrderById(AIZE.bc.clone,order,target)
elseif sw == 2 and AIZE.sb == 0 then
if AIZE.petDist > 700 then
call IssuePointOrderById(AIZE.bc.clone,order,hx,hy)
else
call IssuePointOrderById(AIZE.bc.clone,order,x,y)
endif
endif
endif
endif
endmethod
//hace que el AI patrulle un area, no podra salir de esta por ningun motivo (para los jefes), para desactivar se envia un area de 0
method setGuardSpot takes real x, real y, real area returns nothing
set guardX = x
set guardY = y
set guardArea = area
if area == 0 then
set guardX = 0.00
set guardY = 0.00
endif
endmethod
//Resguarda un area si esta fuera de combate.
method idleRandom takes real x, real y, real radius returns nothing
local real a = GetRandomReal(0,360) * bj_DEGTORAD
local real mx = x + GetRandomReal(50,radius) * Cos(a)
local real my = y + GetRandomReal(50,radius) * Sin(a)
call IssueOrder(null,ORDER_move,mx,my)
endmethod
method retreat takes nothing returns nothing
set retreating = true
call IssueOrder(null,ORDER_move,retreatX,retreatY)
/*if (percentLife <= 0.35 or enemyHeroCount > alliedHeroCount) and Game.Mode == GAME_MODE_NORMAL then
call IssueOrder(null,ORDER_move,team.startX,team.startY)
else
call IssueOrder(null,ORDER_move,retreatX,retreatY)
endif*/
endmethod
endmodule
endlibrary
library AIAbilityBuild uses LinkedList, Perks
struct AbilityBuild extends array
implement Alloc
LinkedList list
AICore AI
public method learnNextSkill takes nothing returns nothing
local Link h = list.head
local integer lvl = GetHeroLevel(AI.playerHero.hero)
if h != 0 then
if lvl == 6 or lvl == 11 or lvl == 16 or lvl == 19 and not AI.basic then
call UpdatePerkIcon(AI.playerHero.hero,lvl,SetPerkBonus(h.data,AI.playerHero.hero,lvl))
call UnitModifySkillPoints(AI.playerHero.hero, -1)
else
call SelectHeroSkill(AI.playerHero.hero,h.data)
call UnitModifySkillPoints(AI.playerHero.hero, -1)
endif
call list.remove(h)
if list.size == 0 then
call list.destroy()
endif
endif
endmethod
public method registerLearnSkill takes integer id returns nothing
call list.addLast(id)
endmethod
public static method create takes AICore ai returns thistype
local thistype this = thistype.allocate()
set list = LinkedList.create()
set AI = ai
return this
endmethod
endstruct
endlibrary
library UpgradeBuild uses MiscLibrary
struct UpgradeBuild extends array
implement Alloc
LinkedList list
AICore ai
integer mastery
public static method Build takes thistype this returns nothing
local string temp
local string array us
local integer a
local integer b
local integer c
set us[0] = "123"
set us[1] = "132"
set us[2] = "213"
set us[3] = "231"
set us[4] = "312"
set us[5] = "321"
set temp = us[GetRandomInt(0,5)]
set a = S2I(SubString(temp,0,1))
set b = S2I(SubString(temp,1,2))
set c = S2I(SubString(temp,2,3))
call .add(a)
call .add(b)
call .add(a)
call .add(b)
call .add(a)
call .add(b)
call .add(c)
call .add(c)
call .add(c)
endmethod
public method learnUpgrade takes nothing returns nothing
local Link h = list.head
if list == 0 or h == 0 then
return
endif
if h.data == 1 then
if ai.playerHero.up1.IncreaseLevel() then
call list.remove(h)
endif
elseif h.data == 2 then
if ai.playerHero.up2.IncreaseLevel() then
call list.remove(h)
endif
elseif h.data == 3 then
if ai.playerHero.up3.IncreaseLevel() then
call list.remove(h)
endif
endif
if list.size == 0 then
call list.destroy()
set list = 0
endif
endmethod
public method add takes integer i returns nothing
call list.addLast(i)
endmethod
public method selectMastery takes nothing returns nothing
call ai.playerHero.up4.SelectMastery(mastery)
endmethod
public static method create takes AICore ai returns thistype
local thistype this = thistype.allocate()
set .ai = ai
set list = LinkedList.create()
set mastery = GetRandomInt(1,3)
return this
endmethod
endstruct
endlibrary