//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
//TESH.scrollpos=27
//TESH.alwaysfold=0
globals
//Player Colors
string array TXTC
//Hero Systems
unit HERO = null
unit HERO_F3 = null
unit PET = null
integer HERO_CLASS = 0
integer HERO_CLASS_ID = 0
integer HERO_ID = 0
integer HERO_UD = 0
integer PET_ID = 0
integer PET_UD = 0
string HERO_NAME = ""
//Expirience rate
real EXP = 1.00
//General dummy unit
integer DUMMY_ID = 'e006'
//AntiFileHeader
boolean CUSTOM_CAMERA_ENABLED = false
integer ABILITIES_UNIT_INDEXER = 'A!!!'
integer UNITS_UNIT_EVENT = 'n!!!'
boolean IS_IN_BUILDING = false
boolean IS_IN_CI = false
boolean IS_PET_ALIVE = false
boolean IS_DAY = false
boolean IS_CINEMA_ON = false
timer BUILDING_CAMERA_TIMER = null
endglobals
library BaseSystems initializer Init uses RegisterPlayerUnitEvent
globals
string MUSIC_INTRO = "war3mapImported\\mp3 Intro Music SotP.mp3"
string MUSIC_QUEST1 = "war3mapImported\\mp3 Quest1 Music SotP.mp3"
string MUSIC_QUEST2 = "Sound\\Music\\mp3Music\\Undead3.mp3"
string MUSIC_WORLD1 = "war3mapImported\\Explore.mp3"
string MUSIC_WORLD2 = "war3mapImported\\ExploreAct2.mp3"
location RevivePos
endglobals
function MsgDisp takes string text returns nothing
call ClearTextMessages()
call DisplayTimedTextToPlayer(Player(0), 0.8, 0.1, 3,"|cffccccff" + text)
endfunction
function StartLoopingSound takes string filepath returns nothing
call StopMusic(false)
call ClearMapMusic()
call PlayMusic(filepath)
endfunction
struct setBBxy extends array
private static method run takes nothing returns nothing
call SetUnitX(HERO_F3, GetUnitX(HERO))
call SetUnitY(HERO_F3, GetUnitY(HERO))
if HERO != null then
if GetUnitX(HERO) > -250.00 and GetUnitX(HERO) < 250.00 and GetUnitY(HERO) > -250.00 and GetUnitY(HERO) < 250.00 then
call SetUnitX(HERO, GetLocationX(RevivePos))
call SetUnitY(HERO, GetLocationY(RevivePos))
call BJDebugMsg("debug: Invalid hero loc detected.")
endif
endif
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0.03, true, function thistype.run)
endmethod
endstruct
private function AttackStop takes nothing returns nothing
if IsPlayerAlly(GetOwningPlayer(GetAttacker()), GetOwningPlayer(GetTriggerUnit())) then
call IssueImmediateOrder(GetAttacker(), "stop")
endif
endfunction
function Init takes nothing returns nothing
local integer i = 0
set TXTC[0] = "|CFFFF0303"
set TXTC[1] = "|c000042FF"
set TXTC[2] = "|C0000FFFF"
set TXTC[3] = "|c00540081"
set TXTC[4] = "|c00FFFC01"
set TXTC[5] = "|c00FEBA0E"
set TXTC[6] = "|c0020C000"
set TXTC[7] = "|c00E55BB0"
set TXTC[8] = "|c00959697"
set TXTC[9] = "|CFF7EBFF1"
set TXTC[10] = "|CFF106246"
set TXTC[11] = "|CFF4E2A04"
call FogModifierStart( CreateFogModifierRect( Player(0) , FOG_OF_WAR_VISIBLE , gg_rct_CI1 , true , false ) )
call FogModifierStart( CreateFogModifierRect( Player(0) , FOG_OF_WAR_VISIBLE , gg_rct_CI2 , true , false ) )
loop
exitwhen i > 14
call SetPlayerName(Player(i), TXTC[i] + GetPlayerName(Player(i)))
set i = i + 1
endloop
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED, 0)
call SetPlayerHandicapXP(Player(0), 0.00)
set RevivePos = GetUnitLoc(gg_unit_ncop_0108)
call SetWaterBaseColor(0,0,0,100)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED, function AttackStop)
endfunction
endlibrary
//TESH.scrollpos=75
//TESH.alwaysfold=0
library CTL /* v1.2.0.0
*************************************************************************************
*
* 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 timer t32r = CreateTimer() //t32 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
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Table // made by Bribe, special thanks to Nestharus, version 3.0.0.0
/*
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 hashtable ht = InitHashtable() //The last hashtable you need
private integer more = 2 //Index generation for Tables (above 2)
private integer less = 0 //Index generation for TableArrays (below 0)
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return 1
endmethod
static method operator list takes nothing returns Table
return 2
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
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
//! 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")
struct Table extends array
// Implement modules for intuitive type-syntax
implement realm
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
method operator handle takes nothing returns handles
return this
endmethod
method operator agent takes nothing returns agents
return this
endmethod
// set this = a[GetSpellAbilityId()]
method operator [] takes integer key returns Table
return LoadInteger(ht, this, key)
endmethod
// set a[389034] = 8192
method operator []= takes integer key, Table a returns nothing
call SaveInteger(ht, this, key, a)
endmethod
// set b = a.has(2493223)
method has takes integer key returns boolean
return HaveSavedInteger(ht, this, key)
endmethod
// call a.remove(294080)
method remove takes integer key returns nothing
call RemoveSavedInteger(ht, this, key)
endmethod
// Remove all data from a Table instance
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
endmethod
// local Table a = Table.create()
static method create takes nothing returns Table
local Table this = dex.list[0]
if this == 0 then
set more = more + 1
set this = more
else
set dex.list[0] = dex.list[this]
call dex.list.remove(this)
endif
debug set dex.list[this] = -1
return this
endmethod
// Removes all data from a Table instance and recycles its index.
//
// call a.destroy()
//
method destroy takes nothing returns nothing
debug if dex.list[this] != -1 then
debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
debug return
debug endif
call this.flush()
set dex.list[this] = dex.list[0]
set dex.list[0] = this
endmethod
endstruct
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 a = dex.size[array_size] //Get the unique recycle list for this array size
local TableArray this = a[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 less = less - array_size
set this = less
else
set a[0] = a[this] //Set the last destroyed to the last-last destroyed
call a.remove(this) //Clear hash 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
//da[integer a].unit[integer b] = unit u
//da[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; assumed you'd call .flush()
//if you want it flushed too. This is public so that if you are flushing
//instances the whole time you don't waste efficiency when disposing the
//TableArray.
//
method destroy takes nothing returns nothing
local Table a = 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 a == 0 then
//Create an array to index recycled instances with their array size
set a = Table.create()
set dex.size[this.size] = a
endif
call dex.size.remove(this) //Clear the array size from hash memory
set a[this] = a[0]
set a[0] = this
endmethod
//All you need to know about this one is that it won't hit the op limit.
private static method clean takes Table a, integer end returns nothing
local integer i = a + 5000
if i < end then
call clean.evaluate(i, end)
set end = i
endif
loop
call a.flush()
set a = a + 1
exitwhen a == 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
local integer end = this.size + this
debug if this == end then
debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
debug return
debug endif
call clean.evaluate(this, end)
call this.destroy()
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Event
//2.0.0.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 q=0
endglobals
struct Event extends array
private static integer w=0
private static trigger array e
static method create takes nothing returns thistype
set w=w+1
set e[w]=CreateTrigger()
return w
endmethod
method registerTrigger takes trigger t returns nothing
call TriggerRegisterVariableEvent(t,SCOPE_PRIVATE+"q",EQUAL,this)
endmethod
method register takes boolexpr c returns nothing
call TriggerAddCondition(e[this],c)
endmethod
method fire takes nothing returns nothing
set q=0
set q=this
call TriggerEvaluate(e[this])
endmethod
endstruct
function CreateEvent takes nothing returns Event
return Event.create()
endfunction
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
//TESH.scrollpos=0
//TESH.alwaysfold=0
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
implement WorldBoundInit
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CombatState requires UnitIndexer, Event, optional TimerUtils
//******** COMBAT STATE ******************************************//
// - This library registers whether or not some unit is in combat.
// - To be registered as in combat, the unit must attack or have been attacked by an enemy unit.
// - Any spell that is cast by an opposing player onto the unit will flag them as in combat.
// - Being in combat only lasts a specific duration, in this case 5 seconds, before the unit leaves combat.
// - Once a unit dies, the dying unit will be taken out of combat.
// Requirements:
// -- UnitIndexer by Nestharus
// -- Event by Nestharus
// - This will allow you to register when a unit enters or leaves combat.
// -- *OPTIONAL* TimerUtils by Vexorian
// - This will recycle timers instead of creating/destroying them, so it is a bit more optimal. As far as speed goes,
// it is pretty negligible. Without TimerUtils, it will use a hashtable.
// API:
// Configurables:
// - COMBAT_DURATION: This determines the time before a unit is considered to be out of combat, default 5 seconds.
// The unit must remain unattacked and attack no one for COMBAT_DURATION to leave combat.
// Data Modify/Retrieve:
// CombatState[whichUnit].inCombat -> returns boolean
// set CombatState[whichUnit].inCombat = flag
// Function Wrappers:
// function GetUnitCombatState takes unit whichUnit returns boolean
// - This returns the combat state of a unit. If it returns true, the unit is in combat. If it returns false, then the unit
// is not in combat.
// function SetUnitCombatState takes unit whichUnit, boolean flag returns nothing
// - This allows you to force a unit in or out of combat, and it will register the corresponding events.
// If you are using Event:
// call CombatState.EnterCombat.register(trigger)
// - Registers when some unit enters combat after being out of combat.
// call CombatState.LeaveCombat.register(trigger)
// - Registers when some unit leaves combat after having been just in combat.
// function GetTriggerCombatUnit takes nothing returns unit
// - When using registering an event, this will basically return the unit who entered or left combat. GetTriggerCombatUnit()
// Credits:
// - Nestharus for UnitIndexer, Event, and optimizations
// - Darthfett for the original combat library
// - Vexorian for TimerUtils
//****************************************************************//
globals
private constant real COMBAT_DURATION = 5
//**************DO NOT EDIT PAST THIS POINT***********************//
private unit combatUnit = null
private hashtable Hash
endglobals
function GetTriggerCombatUnit takes nothing returns unit
return combatUnit
endfunction
private module Init
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
static if not LIBRARY_TimerUtils then
set Hash = InitHashtable()
endif
set thistype.ENTER = Event.create()
set thistype.LEAVE = Event.create()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ATTACKED)
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH)
call UnitIndexer.DEINDEX.register(Condition(function thistype.deindex))
call TriggerAddCondition(t,Condition(function thistype.CombatEnter))
endmethod
endmodule
struct CombatState extends array
private timer combatTimer
private boolean inCombatV
readonly static Event LEAVE = 0
readonly static Event ENTER = 0
static method operator [] takes unit u returns thistype
return GetUnitUserData(u)
endmethod
private static method CombatLeave takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit prev = combatUnit
static if LIBRARY_TimerUtils then
local integer id = GetTimerData(t)
call ReleaseTimer(t)
else
local integer id = LoadInteger(Hash,GetHandleId(t),0)
call PauseTimer(t)
call DestroyTimer(t)
set t = null
endif
set combatUnit = GetUnitById(id)
set thistype(id).inCombatV = false
set thistype(id).combatTimer = null
call thistype.LEAVE.fire()
set combatUnit = prev
set prev = null
endmethod
method operator inCombat takes nothing returns boolean
return this.inCombatV
endmethod
method operator inCombat= takes boolean flag returns nothing
local unit prev = combatUnit
set combatUnit = GetUnitById(this)
if flag then
if this.combatTimer == null then
set this.inCombatV = true
call thistype.ENTER.fire()
static if LIBRARY_TimerUtils then
set this.combatTimer = NewTimer()
call SetTimerData(this.combatTimer,this)
else
set this.combatTimer = CreateTimer()
call SaveInteger(Hash,GetHandleId(this.combatTimer),0,this)
endif
endif
call TimerStart(this.combatTimer,COMBAT_DURATION,false,function thistype.CombatLeave)
elseif (this.inCombatV) then
set this.inCombatV = false
static if LIBRARY_TimerUtils then
call ReleaseTimer(this.combatTimer)
else
call PauseTimer(this.combatTimer)
call DestroyTimer(this.combatTimer)
endif
set this.combatTimer = null
call thistype.LEAVE.fire()
endif
set combatUnit = prev
set prev = null
endmethod
private static method CombatEnter takes nothing returns boolean
local unit u = GetAttacker()
if GetTriggerEventId()==EVENT_PLAYER_UNIT_DEATH then
set thistype[GetTriggerUnit()].inCombat=false
return false
elseif u == null then
set u = GetSpellTargetUnit()
endif
if u != null then
if IsUnitEnemy(u,GetTriggerPlayer()) then
set thistype[GetTriggerUnit()].inCombat=true
set thistype[u].inCombat=true
elseif CombatState[u].inCombat then
set thistype[GetTriggerUnit()].inCombat=true
endif
endif
set u = null
return false
endmethod
private static method deindex takes nothing returns boolean
set thistype(GetIndexedUnitId()).inCombat=false
return false
endmethod
implement Init
endstruct
function GetUnitCombatState takes unit whichUnit returns boolean
return CombatState[whichUnit].inCombat
endfunction
function SetUnitCombatState takes unit whichUnit, boolean flag returns nothing
set CombatState[whichUnit].inCombat = flag
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/**************************
*
* Math
* v1.0.0.0
* By Magtheridon96
*
* - The BJs suck, so I made this.
*
*
*
**************************/
library Math
function RMin takes real a, real b returns real
if a > b then
return b
endif
return a
endfunction
function RMax takes real a, real b returns real
if a > b then
return a
endif
return b
endfunction
function IMin takes integer a, integer b returns integer
if a > b then
return b
endif
return a
endfunction
function IMax takes integer a, integer b returns integer
if a > b then
return a
endif
return b
endfunction
function IAbs takes integer a returns integer
if a > 0 then
return a
endif
return -a
endfunction
function RAbs takes real a returns real
if a > 0 then
return a
endif
return -a
endfunction
function GetDistanceBetween takes real x1, real y1, real x2, real y2 returns real
local real x = x1 - x2
local real y = y1 - y2
return SquareRoot(x*x + y*y)
endfunction
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
/**************************************************************
*
* RegisterPlayerUnitEvent
* v4.1.1.0
* By Magtheridon96
*
* This library was made to replace that GTrigger
* monster by Jesus4Lyf at TheHelper. 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
* return false. They can return nothing as well.
*
* API:
* ----
*
* function RegisterPlayerUnitEvent
* takes
* playerunitevent whichEvent : The event that will be registered.
* code whichFunction : The function that will fire when the event occurs.
* returns
* nothing
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
globals
private trigger array t
endglobals
function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
local integer i = GetHandleId(p)
local integer k = 15
if t[i] == null then
set t[i] = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
exitwhen k == 0
set k = k - 1
endloop
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
endlibrary
//TESH.scrollpos=12
//TESH.alwaysfold=0
//============================================================================
// 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, optional Table
//============================================================================
private module M
static if LIBRARY_Table then
static Table tb
else
static hashtable ht = InitHashtable()
endif
static method onCast takes nothing returns nothing
static if LIBRARY_Table then
call TriggerEvaluate(.tb.trigger[GetSpellAbilityId()])
else
call TriggerEvaluate(LoadTriggerHandle(.ht, 0, GetSpellAbilityId()))
endif
endmethod
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set .tb = Table.create()
endif
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endmodule
//============================================================================
private struct S extends array
implement M
endstruct
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
static if LIBRARY_Table then
if not S.tb.handle.has(abil) then
set S.tb.trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(S.tb.trigger[abil], Filter(onCast))
else
if not HaveSavedHandle(S.ht, 0, abil) then
call SaveTriggerHandle(S.ht, 0, abil, CreateTrigger())
endif
call TriggerAddCondition(LoadTriggerHandle(S.ht, 0, abil), Filter(onCast))
endif
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library BinaryHeap /* v4.0.0.0
*************************************************************************************
*
* Binary Heap
*
************************************************************************************
*
* Interface:
* private static method compare takes thistype value1, thistype value2 returns boolean
* - < for minimum heap
* - > for maximum heap
*
* static readonly thistype root
* - The node with the smallest/biggest value
* readonly thistype node
* - Node stored within heap position (array[heapPosition] = node)
* readonly thistype heap
* - Heap position of node (array[heapPosition] = node)
* static readonly integer size
* - Size of binary heap
* readonly integer value
* - Sorted value (the value of the node)
*
* method modify takes integer sortValue returns nothing
* - Modifies the value of the node
*
* static method insert takes integer sortValue returns thistype
* - Inserts a new node into the heap and returns it
* - Assigns that node the passed in value
* method delete takes nothing returns nothing
* - Deletes node from heap
*
* static method clear takes nothing returns nothing
* - Clears the heap
*
************************************************************************************/
module BinaryHeap
readonly static integer size = 0
readonly thistype node //node
private static thistype instanceCount = 0 //node instance count
private static thistype array recycler //node recycler
readonly thistype value
readonly thistype heap
static method operator root takes nothing returns thistype
return thistype(1).node
endmethod
static method allocate takes thistype value returns thistype
local thistype this = recycler[0]
if (0 == this) then
set this = instanceCount + 1
set instanceCount = this
else
set recycler[0] = recycler[this]
endif
set this.value = value
set node.heap = 0
return this
endmethod
method deallocate takes nothing returns nothing
set recycler[this]=recycler[0]
set recycler[0]=this
endmethod
private method link takes thistype heapPosition returns nothing
set heapPosition.node = this
set heap = heapPosition
endmethod
private method bubbleUp takes nothing returns nothing
local thistype value = this.value
local thistype heapPosition = heap
local thistype parent
/*
* Bubble node up
*/
loop
set parent = heapPosition/2
exitwhen (0 == parent or compare(parent.node.value, value))
set heapPosition.node = parent.node
set heapPosition.node.heap = heapPosition
set heapPosition = parent
endloop
/*
* Update pointers
*/
call link(heapPosition)
endmethod
private method bubbleDown takes nothing returns nothing
local thistype value = this.value
local thistype heapPosition = heap
local thistype left
local thistype right
/*
* Bubble node down
*/
loop
set left = heapPosition*2
set right = left + 1
exitwhen (0 == left.node or compare(value, left.node.value)) and (0 == right.node or compare(value, right.node.value))
if (0 == right.node.value or (0 != left.node and compare(left.node.value, right.node.value))) then
/*
* Go left
*/
set heapPosition.node = left.node
set heapPosition.node.heap = heapPosition
set heapPosition = left
else
/*
* Go right
*/
set heapPosition.node = right.node
set heapPosition.node.heap = heapPosition
set heapPosition = right
endif
endloop
/*
* Update pointers
*/
call link(heapPosition)
endmethod
method modify takes integer value returns nothing
set this.value = value
/*
* Bubble node into correct position
*/
call bubbleUp()
call bubbleDown()
endmethod
static method insert takes thistype value returns thistype
local thistype heapPosition
local thistype this
/*
* Allocate new node
*/
set this = allocate(value)
/*
* Increase heap size
*/
set heapPosition = size + 1
set size = heapPosition
/*
* Store node in last heap position
*/
call link(heapPosition)
/*
* Bubble node into correct position
*/
call bubbleUp()
return this
endmethod
method delete takes nothing returns nothing
local thistype lastNode
debug if (0 == size) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10,"Attempted To Delete Node From Empty Heap")
debug set this = 1/0
debug endif
/*
* Deallocate node
*/
call deallocate()
/*
* Remove last node from last position
*/
set lastNode = thistype(size).node
set thistype(size).node = 0
set size = size - 1
if (lastNode != node) then
/*
* Put last node in deallocated node's position
*/
call lastNode.link(heap)
/*
* Bubble into correct spot
*/
call lastNode.bubbleUp()
call lastNode.bubbleDown()
endif
endmethod
static method clear takes nothing returns nothing
set size = 0
set recycler[0] = 0
set instanceCount = 0
set thistype(1).node = 0
endmethod
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library PriorityEvent /* v2.0.0.1
*************************************************************************************
*
* Creates events that fire given a priority. A higher priority means that those
* events will fire first. A priority of 0 means that those events will fire last.
*
* Priority events can only be created at map init
* Code can only be registered to priority events at map init
*
*************************************************************************************
*
* */uses/*
*
* */ AVL /* hiveworkshop.com/forums/jass-resources-412/snippet-avl-tree-203168/
*
************************************************************************************
*
* struct PriorityEvent extends array
*
* static method create takes nothing returns thistype
* method register takes boolexpr func, integer priority returns nothing
* method fire takes nothing returns nothing
*
************************************************************************************/
private struct PriorityEventTree extends array
method lessThan takes thistype value returns boolean
return integer(this) < integer(value)
endmethod
method greaterThan takes thistype value returns boolean
return integer(this) > integer(value)
endmethod
implement AVL
endstruct
private module PriorityEventMod
private static integer instanceCount = 0
/*
* A queue of code registered with the same priority
*/
private thistype next_p
private thistype last_p
private thistype first_p
/*
* The priorities are stored in the tree list
*/
/*
* Iterate from 0 to count to go over all created events
*/
private static PriorityEventTree count = 0
private static PriorityEventTree array tree
/*
* This is a temporary trigger to store all code of the same priority
* Once the game has started, all code will be merged on to one trigger
*/
private trigger event
/*
* Need to store the code in order to merge all it all on to one trigger
*/
private boolexpr code
/*
* All code is merged on this
*/
private trigger allEvent
/*
* Has the code all been merged?
*/
private static boolean merged = false
static method create takes nothing returns thistype
local thistype this
debug if (merged) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10,"Priority Event Error: Can Only Create Events On Game Init")
debug set this = 1/0
debug endif
/*
* Allocate new event
*/
set this = PriorityEventTree.create()
/*
* Add to array for merging later
*/
set tree[count] = this
set count = count + 1
/*
* Create the merging trigger
*/
set thistype(count).allEvent = CreateTrigger()
return count
endmethod
method register takes boolexpr func, integer priority returns nothing
local thistype node
debug if (merged) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10,"Priority Event Error: Can Only Register Code On Game Init")
debug set node = 1/0
debug endif
/*
* Allocate a new node to store the function
*/
set node = instanceCount + 1
set instanceCount = node
set node.code = func
/*
* Retrieve the priority. This will act as the pointer to
* the queue that the node will be added to.
*/
set this = PriorityEventTree(this).add(priority)
if (null == event) then
/*
* If the queue hasn't been created yet, create it
*/
set event = CreateTrigger()
set first_p = node
set last_p = node
else
/*
* Add node to queue
*/
set last_p.next_p = node
set last_p = node
endif
call TriggerAddCondition(event, func)
endmethod
method fire takes nothing returns nothing
if (merged) then
/*
* If the code has all been merged (game started), evaluate the trigger that contains all code
*/
call TriggerEvaluate(allEvent)
else
/*
* If the code hasn't been merged yet, evaluate all of the triggers along the priority queue
*/
loop
set this = PriorityEventTree(this).prev
exitwhen PriorityEventTree(this).head
call TriggerEvaluate(event)
endloop
endif
endmethod
/*
* This is called when the game starts. It merges all of the registered code
* for each event on to single triggers to improve performance
*/
private static method merge takes nothing returns nothing
local thistype this
local integer current = count
local PriorityEventTree priority
local thistype node
set merged = true
/*
* Iterate over all events
*/
loop
exitwhen 0 == current
set current = current - 1
set this = tree[current]
/*
* Iterate over all priorities
*/
set priority = this
loop
set priority = priority.prev
exitwhen priority.head
/*
* Clean up temporary priority event trigger
*/
call TriggerClearConditions(thistype(priority).event)
call DestroyTrigger(thistype(priority).event)
set thistype(priority).event = null
/*
* Iterate over all registered code on the priority trigger
*/
set node = thistype(priority).first_p
loop
exitwhen 0 == node
/*
* Add to main trigger
*/
call TriggerAddCondition(allEvent, node.code)
set node = node.next_p
endloop
endloop
endloop
call DestroyTimer(GetExpiredTimer())
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0, false, function thistype.merge)
endmethod
endmodule
struct PriorityEvent extends array
implement PriorityEventMod
endstruct
endlibrary
//TESH.scrollpos=149
//TESH.alwaysfold=0
library UnitIndexer /* v4.0.2.6
*************************************************************************************
*
* Assigns unique indexes to units via unit user data.
*
*************************************************************************************
*
* */uses/*
*
* */ WorldBounds /* hiveworkshop.com/forums/jass-functions-413/snippet-worldbounds-180494/
* */ Event /* hiveworkshop.com/forums/submissions-414/snippet-event-186555/
*
************************************************************************************
*
* Functions
*
* function RegisterUnitIndexEvent takes boolexpr codeToRegister, Event unitIndexEvent returns nothing
* function TriggerRegisterUnitIndexEvent takes trigger triggerToRegister, Event unitIndexEvent returns nothing
*
* function GetUnitById takes integer index returns unit
* - Returns unit given a unit index
* function GetUnitId takes unit u returns integer
* - Returns unit index given a unit
*
* function IsUnitIndexed takes unit u returns boolean
* function IsUnitDeindexing takes unit u returns boolean
*
* function GetIndexedUnitId takes nothing returns integer
* function GetIndexedUnit takes nothing returns unit
*
************************************************************************************
*
* module UnitIndexStructMethods
* static method operator [] takes unit u returns thistype
* - Return GetUnitUserData(u)
*
* readonly unit unit
* - The indexed unit of the struct
*
************************************************************************************
*
* module UnitIndexStruct extends UnitIndexStructMethods
*
* - A pseudo module interface that runs a set of methods if they exist and provides
* - a few fields and operators. Runs on static ifs to minimize code.
*
* readonly boolean allocated
* - Is unit allocated for the struct
*
* Interface:
*
* - These methods don't have to exist. If they don't exist, the code
* - that calls them won't even be in the module.
*
* private method index takes nothing returns nothing
* - called when a unit is indexed and passes the filter.
* -
* - thistype this: Unit's index
* private method deindex takes nothing returns nothing
* - called when a unit is deindexed and is allocated for struct
* -
* - thistype this: Unit's index
* private static method filter takes unit unitToIndex returns boolean
* - Determines whether or not to allocate struct for unit
* -
* - unit unitToIndex: Unit being filtered
*
************************************************************************************
*
* struct UnitIndexer extends array
*
* - Controls the unit indexer system.
*
* static constant Event UnitIndexer.INDEX
* static constant Event UnitIndexer.DEINDEX
* - Don't register functions and triggers directly to the events. Register them via
* - RegisterUnitIndexEvent and TriggerRegisterUnitIndexEvent.
*
* static boolean enabled
* - Enables and disables unit indexing. Useful for filtering out dummy units.
*
************************************************************************************
*
* struct UnitIndex extends UnitIndexStructMethods
*
* - Constrols specific unit indexes.
*
* method lock takes nothing returns nothing
* - Locks an index. When an index is locked, it will not be recycled
* - when the unit is deindexed until all locks are removed. Deindex
* - events still fire at the appropriate times, the index just doesn't
* - get thrown into the recycler.
* method unlock takes nothing returns nothing
* - Unlocks an index.
*
************************************************************************************/
globals
private constant integer ABILITIES_UNIT_INDEXER = 'A!!!'
private trigger q=CreateTrigger()
private trigger l=CreateTrigger()
private unit array e
private integer r=0
private integer y=0
private integer o=0
private boolean a=false
private integer array n
private integer array p
private integer array lc
endglobals
function GetIndexedUnitId takes nothing returns integer
return o
endfunction
function GetIndexedUnit takes nothing returns unit
return e[o]
endfunction
//! runtextmacro optional UNIT_LIST_LIB()
private struct PreLoader extends array
public static method run takes nothing returns nothing
call DestroyTimer(GetExpiredTimer())
set a=true
endmethod
public static method eval takes trigger t returns nothing
local integer f=n[0]
local integer d=o
loop
exitwhen 0==f
if (IsTriggerEnabled(t)) then
set o=f
if (TriggerEvaluate(t)) then
call TriggerExecute(t)
endif
else
exitwhen true
endif
set f=n[f]
endloop
set o=d
endmethod
public static method evalb takes boolexpr c returns nothing
local trigger t=CreateTrigger()
local thistype f=n[0]
local integer d=o
call TriggerAddCondition(t,c)
loop
exitwhen 0==f
set o=f
call TriggerEvaluate(t)
set f=n[f]
endloop
call DestroyTrigger(t)
set t=null
set o=d
endmethod
endstruct
//! runtextmacro optional UNIT_EVENT_MACRO()
private module UnitIndexerInit
private static method onInit takes nothing returns nothing
local integer i=15
local boolexpr bc=Condition(function thistype.onLeave)
local boolexpr bc2=Condition(function thistype.onEnter)
local group g=CreateGroup()
local player p
set INDEX=CreateEvent()
set DEINDEX=CreateEvent()
call TriggerRegisterEnterRegion(q,WorldBounds.worldRegion,bc2)
loop
set p=Player(i)
call TriggerRegisterPlayerUnitEvent(l,p,EVENT_PLAYER_UNIT_ISSUED_ORDER,bc)
call SetPlayerAbilityAvailable(p,ABILITIES_UNIT_INDEXER,false)
call GroupEnumUnitsOfPlayer(g,p,bc2)
exitwhen 0==i
set i=i-1
endloop
call DestroyGroup(g)
set bc=null
set g=null
set bc2=null
set p=null
call TimerStart(CreateTimer(),0,false,function PreLoader.run)
endmethod
endmodule
struct UnitIndex extends array
method lock takes nothing returns nothing
debug if (null!=e[this]) then
set lc[this]=lc[this]+1
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"UNIT INDEXER ERROR: ATTEMPT TO LOCK NULL INDEX")
debug endif
endmethod
method unlock takes nothing returns nothing
debug if (0<lc[this]) then
set lc[this]=lc[this]-1
if (0==lc[this] and null==e[this]) then
set n[this]=y
set y=this
endif
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"UNIT INDEXER ERROR: ATTEMPT TO UNLOCK UNLOCKED INDEX")
debug endif
endmethod
method operator unit takes nothing returns unit
return e[this]
endmethod
static method operator [] takes unit whichUnit returns thistype
return GetUnitUserData(whichUnit)
endmethod
endstruct
struct UnitIndexer extends array
readonly static Event INDEX
readonly static Event DEINDEX
static boolean enabled=true
private static method onEnter takes nothing returns boolean
local unit Q=GetFilterUnit()
local integer i
local integer d=o
if (enabled and Q!=e[GetUnitUserData(Q)]) then
if (0==y) then
set r=r+1
set i=r
else
set i=y
set y=n[y]
endif
call UnitAddAbility(Q,ABILITIES_UNIT_INDEXER)
call UnitMakeAbilityPermanent(Q,true,ABILITIES_UNIT_INDEXER)
call SetUnitUserData(Q,i)
set e[i]=Q
static if not LIBRARY_UnitList then
if (not a)then
set p[i]=p[0]
set n[p[0]]=i
set n[i]=0
set p[0]=i
endif
else
set p[i]=p[0]
set n[p[0]]=i
set n[i]=0
set p[0]=i
call GroupAddUnit(g,e[i])
endif
set o=i
call FireEvent(INDEX)
set o=d
endif
set Q=null
return false
endmethod
private static method onLeave takes nothing returns boolean
static if LIBRARY_UnitEvent then
implement optional UnitEventModule
else
local unit u=GetFilterUnit()
local integer i=GetUnitUserData(u)
local integer d=o
if (0==GetUnitAbilityLevel(u,ABILITIES_UNIT_INDEXER) and u==e[i]) then
static if not LIBRARY_UnitList then
if (not a)then
set n[p[i]]=n[i]
set p[n[i]]=p[i]
endif
else
set n[p[i]]=n[i]
set p[n[i]]=p[i]
call GroupRemoveUnit(g,e[i])
endif
set o=i
call FireEvent(DEINDEX)
set o=d
if (0==lc[i]) then
set n[i]=y
set y=i
endif
set e[i]=null
endif
set u=null
endif
return false
endmethod
implement UnitIndexerInit
endstruct
//! runtextmacro optional UNIT_EVENT_MACRO_2()
function RegisterUnitIndexEvent takes boolexpr c,integer ev returns nothing
call RegisterEvent(c, ev)
if (not a and ev==UnitIndexer.INDEX and 0!=n[0]) then
call PreLoader.evalb(c)
endif
endfunction
function TriggerRegisterUnitIndexEvent takes trigger t,integer ev returns nothing
call TriggerRegisterEvent(t,ev)
if (not a and ev == UnitIndexer.INDEX and 0!=n[0]) then
call PreLoader.eval(t)
endif
endfunction
function GetUnitById takes integer W returns unit
return e[W]
endfunction
function GetUnitId takes unit u returns integer
return GetUnitUserData(u)
endfunction
function IsUnitIndexed takes unit u returns boolean
return u==e[GetUnitUserData(u)]
endfunction
function IsUnitDeindexing takes unit u returns boolean
return IsUnitIndexed(u) and 0==GetUnitAbilityLevel(u,ABILITIES_UNIT_INDEXER)
endfunction
module UnitIndexStructMethods
static method operator [] takes unit u returns thistype
return GetUnitUserData(u)
endmethod
method operator unit takes nothing returns unit
return e[this]
endmethod
endmodule
module UnitIndexStruct
implement UnitIndexStructMethods
static if thistype.filter.exists then
static if thistype.index.exists then
static if thistype.deindex.exists then
readonly boolean allocated
else
method operator allocated takes nothing returns boolean
return filter(e[this])
endmethod
endif
else
method operator allocated takes nothing returns boolean
return filter(e[this])
endmethod
endif
elseif (thistype.index.exists) then
static if thistype.deindex.exists then
readonly boolean allocated
else
method operator allocated takes nothing returns boolean
return this==GetUnitUserData(e[this])
endmethod
endif
else
method operator allocated takes nothing returns boolean
return this==GetUnitUserData(e[this])
endmethod
endif
static if thistype.index.exists then
private static method onIndexEvent takes nothing returns boolean
static if thistype.filter.exists then
if (filter(e[o])) then
static if thistype.deindex.exists then
set thistype(o).allocated=true
endif
call thistype(o).index()
endif
else
static if thistype.deindex.exists then
set thistype(o).allocated=true
endif
call thistype(o).index()
endif
return false
endmethod
endif
static if thistype.deindex.exists then
private static method onDeindexEvent takes nothing returns boolean
static if thistype.filter.exists then
static if thistype.index.exists then
if (thistype(o).allocated) then
set thistype(o).allocated=false
call thistype(o).deindex()
endif
else
if (filter(e[o])) then
call thistype(o).deindex()
endif
endif
else
static if thistype.index.exists then
set thistype(o).allocated=false
endif
call thistype(o).deindex()
endif
return false
endmethod
endif
static if thistype.index.exists then
static if thistype.deindex.exists then
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
endmethod
else
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
endmethod
endif
elseif thistype.deindex.exists then
private static method onInit takes nothing returns nothing
call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
endmethod
endif
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library AVL /* v1.1.0.6
*************************************************************************************
*
* An AVL Tree where all nodes are connected by an AVL tree, a linked list, and
* are referenced by a hashtable.
*
*************************************************************************************
*
* */uses/*
*
* */ Table /* hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
*
************************************************************************************
*
* module AVLTree
*
* Interface:
* method lessThan takes thistype value returns boolean
* method greaterThan takes thistype value returns boolean
*
* readonly thistype tree
* - Tree pointer. Accessible from any node on the tree.
* readonly thistype root
* - Root of two children (if root is 0, it's the tree's root)
* readonly thistype left
* readonly thistype right
* readonly thistype down (tree pointer only)
* - The tree has only 1 child, the root
*
* readonly thistype next
* readonly thistype prev
* readonly boolean head
*
* readonly thistype value
* - Value stored in node
*
* static method create takes nothing returns thistype
* method destroy takes nothing returns nothing
*
* method search takes thistype value returns thistype
* - Returns the node containing the value
* - If the value didn't exist, it will return 0
* method searchClose takes thistype value, boolean low returns thistype
* - Searches for the best match to the value.
* -
* - Low = True
* - Search for the closest value <= to the target value
* -
* - Low = False
* - Search for the closest value >= to the target value
*
* method has takes thistype value returns boolean
* - Returns true if a node contains the value
*
* method add takes thistype value returns thistype
* - Returns new node containing added value. If the value
* - was already in the tree, it returns the node that already
* - contained that value.
* method delete takes nothing returns nothing
* - Deletes node
*
* -> Delete the value 15 from the tree if it exists
* -> call search(15).delete()
*
* method clear takes nothing returns thistype
* - Clears the tree of all nodes
* - Returns tree pointer (just in case some node in the tree was passed in rather than the tree)
*
************************************************************************************/
module AVL
private static Table array table //for O(1) searches on specific values
private static thistype c=0 //instance count
private static thistype array b //root
private static thistype array l //left
private static thistype array r //right
private static integer array h //height
private static thistype array p //parent
private static thistype array v //value
private static integer array nn //next node
private static integer array pn //prev node
private static integer array ro //root
method operator tree takes nothing returns thistype
return ro[this]
endmethod
method operator root takes nothing returns thistype
return p[this]
endmethod
method operator down takes nothing returns thistype
return b[this]
endmethod
method operator left takes nothing returns thistype
return l[this]
endmethod
method operator right takes nothing returns thistype
return r[this]
endmethod
method operator value takes nothing returns thistype
return v[this]
endmethod
method operator next takes nothing returns thistype
return nn[this]
endmethod
method operator prev takes nothing returns thistype
return pn[this]
endmethod
method operator head takes nothing returns boolean
return 0==p[this]
endmethod
private method getHeight takes nothing returns integer
//return the bigger leaf height
if (h[l[this]]>h[r[this]]) then
return h[l[this]]+1
endif
return h[r[this]]+1
endmethod
private method updateParent takes integer n returns nothing
//only update the parent of a target leaf if that leaf isn't the original leaf
if (n!=this) then
//update the parent point to
//first leaf
if (0==p[p[this]]) then
set b[p[this]]=n
//left
elseif (l[p[this]]==this) then
set l[p[this]]=n
//right
else
set r[p[this]]=n
endif
//update the leaf point back
//if the leaf isn't null, update the leaf's parent
if (0!=n) then
set p[n]=p[this]
endif
endif
endmethod
private method finishRotate takes thistype n returns nothing
//this code is identical in rotateLeft and rotateRight, so it has
//been abstracted to a method
call updateParent(n)
set p[this]=n
set h[this]=getHeight()
set h[n]=n.getHeight()
endmethod
private method rotateLeft takes nothing returns thistype
local thistype n=r[this]
set r[this]=l[n]
set p[l[n]]=this
set l[n]=this
call finishRotate(n)
return n
endmethod
private method rotateRight takes nothing returns thistype
local thistype n=l[this]
set l[this]=r[n]
set p[r[n]]=this
set r[n]=this
call finishRotate(n)
return n
endmethod
//return the difference between the left and right leaf heights
private method getBalanceFactor takes nothing returns integer
return h[l[this]]-h[r[this]]
endmethod
private static method allocate takes nothing returns thistype
local integer n
if (0==nn[0]) then
set n=c+1
set c=n
else
set n=nn[0] //notice that the recycler uses the next pointer
//the reason it is used is for fast clear/destroy and to save
//a variable
set nn[0]=nn[n]
endif
set l[n]=0 //left leaf
set r[n]=0 //right leaf
set b[n]=0 //down leaf (first node of tree)
set h[n]=1 //height (a node will always have at least a height of 1 for itself)
return n
endmethod
static method create takes nothing returns thistype
local integer n=allocate()
set p[n]=0 //the parent of the tree node is 0
//initialize tree next and prev
set nn[n]=n
set pn[n]=n
//tree value table for O(1) searches on specific values
set table[n]=Table.create()
//tree root is itself (allows one to pass any node from the tree into the methods)
set ro[n]=n
return n
endmethod
//balance from the current node up to the root O(log n)
//balancing is rotations wherever rotations need to be done
private method balance takes nothing returns nothing
local integer f
loop
exitwhen 0==p[this]
set h[this]=getHeight()
set f=getBalanceFactor()
if (2==f) then
if (-1==l[this].getBalanceFactor()) then
call l[this].rotateLeft()
endif
set this=rotateRight()
return
elseif (-2==f) then
if (1==r[this].getBalanceFactor()) then
call r[this].rotateRight()
endif
set this=rotateLeft()
return
endif
set this=p[this]
endloop
endmethod
//goes to the very bottom of a node (for deletion)
private method getBottom takes nothing returns thistype
if (0!=r[this]) then
if (0!=l[this]) then
set this=r[this]
loop
exitwhen 0==l[this]
set this=l[this]
endloop
return this
else
return r[this]
endif
elseif (0!=l[this]) then
return l[this]
endif
return this
endmethod
method search takes thistype val returns thistype
return table[ro[this]][val]
endmethod
method has takes thistype val returns boolean
return table[ro[this]].has(val)
endmethod
method searchClose takes thistype val, boolean low returns thistype
local thistype n
//retrieve tree
set this=ro[this]
//if tree is empty, return 0
if (0==b[this]) then
return 0
endif
//check to see if the node exists in the tree and return it if it does
set n=table[this][val]
if (0!=n) then
return n
endif
//perform a standard tree search for the value to the bottom of the tree
//will always be at most 1 off from the best match
set this=b[this]
loop
if (val.lessThan(v[this])) then
exitwhen 0==l[this]
set this=l[this]
else
exitwhen 0==r[this]
set this=r[this]
endif
endloop
//look at the found value's neighbors on the linked list
if (low) then
//shift down if greater than
if (v[this].greaterThan(val)) then
set this=prev
endif
//return 0 if node wasn't found
if (0==p[this] or v[this].greaterThan(val)) then
return 0
endif
else
//shift up if less than
if (v[this].lessThan(val)) then
set this=next
endif
//return 0 if node wasn't found
if (0==p[this] or v[this].lessThan(val)) then
return 0
endif
endif
return this
endmethod
method add takes thistype val returns thistype
local thistype n
//check if the tree already has the value in it
set this=ro[this]
set n=table[this][val]
//if the tree doesn't have the value in it, add the value
if (0==n) then
set n=this
set this=allocate()
set ro[this]=n //store tree into leaf
set table[n][val]=this //store leaf into value table
set v[this]=val //store value into leaf
//if the tree is empty
if (0==b[n]) then
set b[n]=this //place as first node
set p[this]=n //parent of first node is tree
//add to list
set nn[this]=n
set pn[this]=n
set nn[n]=this
set pn[n]=this
else
//go to the first node in the tree
set n=b[n]
//go to the bottom of the tree with search algorithm
loop
if (val.lessThan(v[n])) then
exitwhen 0==l[n]
set n=l[n]
else
exitwhen 0==r[n]
set n=r[n]
endif
endloop
//add leaf to tree
set p[this]=n
if (val.lessThan(v[n])) then
set l[n]=this
else
set r[n]=this
endif
//update the height of the parent
set h[n]=n.getHeight()
//balance from the parent upwards
call p[n].balance()
//add leaf to list
if (v[n].greaterThan(v[this])) then
set n=pn[n]
endif
set nn[this]=nn[n]
set pn[this]=n
set pn[nn[n]]=this
set nn[n]=this
endif
return this
endif
return n
endmethod
method delete takes nothing returns nothing
local thistype n
local thistype y
//if the leaf to be deleted isn't 0 and the leaf isn't the tree
if (0 != this and 0 != p[this]) then
//remove the leaf from the value table
call table[ro[this]].remove(v[this])
set n=getBottom() //retrieve the bottom leaf
set y=p[n] //store the parent here for balancing later
//move the found leaf into the deleted leaf's position
call n.updateParent(0)
call updateParent(n)
if (this!=n) then
set l[n]=l[this]
set p[l[n]]=n
set r[n]=r[this]
set p[r[n]]=n
set p[n]=p[this]
set h[n]=h[this]
endif
//balance from the found leaf's old parent upwards
call y.balance()
//remove deleted leaf from list
set nn[pn[this]]=nn[this]
set pn[nn[this]]=pn[this]
set nn[this]=nn[0]
set nn[0]=this
endif
endmethod
method clear takes nothing returns thistype
//quick clear
set this=ro[this]
if (nn[this] != this) then
set nn[pn[this]]=nn[0]
set nn[0]=nn[this]
set nn[this]=this
set pn[this]=this
set b[this] = 0
call table[this].flush()
endif
return this
endmethod
method destroy takes nothing returns nothing
//quick destroy
set this=ro[this]
set nn[pn[this]]=nn[0]
set nn[0]=this
call table[this].destroy()
endmethod
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library DamageEvent /* v3.1.1.3
*************************************************************************************
*
* Simple light damage detection. Will not run 0 damage events as only invalid attacks and spells can cause these.
* Can instance spells and attacks with fireSpell and fireAttack methods.
*
*************************************************************************************
*
* */uses/*
*
* */ UnitIndexer /* hiveworkshop.com/forums/jass-functions-413/unit-indexer-172090/
* */ PriorityEvent /* hiveworkshop.com/forums/submissions-414/snippet-priority-event-213573/
* */ BinaryHeap /* hiveworkshop.com/forums/jass-resources-412/snippet-binary-heap-199353/
*
************************************************************************************
*
* SETTINGS
*/
globals
/*************************************************************************************
*
* How many units can refresh at a given moment (when a trigger is rebuilt).
* larger size means less triggers but harder refreshes.
*
*************************************************************************************/
private constant integer TRIGGER_SIZE = 80
endglobals
/*
*************************************************************************************
*
* struct DamageEvent extends array
*
* Fields
* ------------------
* static constant PriorityEvent ANY
*
* readonly static UnitIndex targetId
* readonly static UnitIndex sourceId
* readonly static unit target
* readonly static unit source
* readonly static real amount
* readonly static integer depth
* - if depth == 1, then current damage is the original attack, not a modifier
*
* static boolean enabled
*
* readonly static integer damageType
* - useful for custom attack types (spell, hero, chaos, etc)
* readonly static integer damageId
* - useful for things like ability ids
* readonly static integer instance
* - useful for passing in a struct
*
* Methods
* ------------------
* static method unitDamageTarget takes unit attacker, widget target, real amount, integer damageType, integer damageId, integer instance returns boolean
*
*************************************************************************************
*
* module ExtendDamageEvent extends DamageEvent, AdvDamageEvent (if exists)
*
* module DamageEvent extends DamageEvent, AdvDamageEvent (if exists)
*
* Interface
* ------------------
* private static constant method PRIORITY takes nothing returns integer (optional)
* - without this declared, the priority will be set to 0 (no priority)
* private static method onDamage takes nothing returns nothing (optional)
* private static method filter takes nothing returns boolean (optional)
*
*************************************************************************************/
private struct DamageEventProperties extends array
static method operator target takes nothing returns unit
return GetUnitById(DamageEvent.targetId)
endmethod
static method operator source takes nothing returns unit
return GetUnitById(DamageEvent.sourceId)
endmethod
endstruct
//! runtextmacro optional ADV_DAMAGE_EVENT_EXT_CODE()
globals
private boolexpr damageCondition
endglobals
private struct DamageTrigger extends array
private static integer instanceCount = 0
private thistype first
private thistype next
private thistype prev
readonly thistype parent
private integer inactiveUnits
readonly integer activeUnits
private trigger damageTrigger
private method registerUnit takes UnitIndex whichUnit returns boolean
if (activeUnits < TRIGGER_SIZE) then
call TriggerRegisterUnitEvent(damageTrigger, GetUnitById(whichUnit), EVENT_UNIT_DAMAGED)
set activeUnits = activeUnits + 1
return true
endif
return false
endmethod
private method unregisterUnit takes UnitIndex whichUnit returns nothing
set inactiveUnits = inactiveUnits + 1
set activeUnits = activeUnits - 1
endmethod
private method createTrigger takes nothing returns nothing
set damageTrigger = CreateTrigger()
call TriggerAddCondition(damageTrigger, damageCondition)
endmethod
private method remakeTrigger takes nothing returns nothing
call DestroyTrigger(damageTrigger)
call createTrigger()
endmethod
private method rebuildTrigger takes nothing returns nothing
local thistype current = first
call remakeTrigger()
/*
* Iterate over all units registered to the trigger and reregister them
*/
set current.prev.next = 0
loop
exitwhen 0 == current
call TriggerRegisterUnitEvent(damageTrigger, GetUnitById(current), EVENT_UNIT_DAMAGED)
set current = current.next
endloop
set first.prev.next = current
endmethod
private method remake takes nothing returns nothing
if (inactiveUnits == TRIGGER_SIZE) then
set inactiveUnits = 0
call rebuildTrigger()
endif
endmethod
private method addToList takes thistype whichUnit returns nothing
set whichUnit.parent = this
if (0 == first) then
set first = whichUnit
set whichUnit.next = whichUnit
set whichUnit.prev = whichUnit
else
set this = first
set whichUnit.prev = prev
set whichUnit.next = this
set prev.next = whichUnit
set prev = whichUnit
endif
endmethod
method add takes thistype whichUnit returns boolean
if (0 == this) then
return false
endif
if (registerUnit(whichUnit)) then
call addToList(whichUnit)
return true
endif
return false
endmethod
private method removeFromList takes thistype whichUnit returns nothing
set whichUnit.parent = 0
set whichUnit.prev.next = whichUnit.next
set whichUnit.next.prev = whichUnit.prev
if (first == whichUnit) then
set first = whichUnit.next
if (first == whichUnit) then
set first = 0
endif
endif
endmethod
static method remove takes thistype whichUnit returns nothing
local thistype this = whichUnit.parent
call removeFromList(whichUnit)
call unregisterUnit(whichUnit)
call remake()
endmethod
private static method allocate takes nothing returns thistype
set instanceCount = instanceCount + 1
return instanceCount
endmethod
static method create takes nothing returns thistype
local thistype this = allocate()
call createTrigger()
return this
endmethod
endstruct
private struct DamageTriggerHeapInner extends array
private static method compare takes DamageTrigger trig1, DamageTrigger trig2 returns boolean
return trig1.activeUnits <= trig2.activeUnits
endmethod
implement BinaryHeap
endstruct
private struct DamageTriggerHeap extends array
private static DamageTriggerHeapInner array parent
static method add takes UnitIndex whichUnit returns nothing
local DamageTrigger damageTrigger = DamageTriggerHeapInner.root.value
if (not damageTrigger.add(whichUnit)) then
set damageTrigger = DamageTrigger.create()
call damageTrigger.add(whichUnit)
set parent[damageTrigger] = DamageTriggerHeapInner.insert(damageTrigger)
else
call parent[damageTrigger].modify(damageTrigger)
endif
endmethod
static method remove takes UnitIndex whichUnit returns nothing
local DamageTrigger damageTrigger = DamageTrigger(whichUnit).parent
call DamageTrigger.remove(whichUnit)
call parent[damageTrigger].modify(damageTrigger)
endmethod
endstruct
private module DamageEventMod
readonly static PriorityEvent ANY
readonly static UnitIndex targetId
readonly static UnitIndex sourceId
static real amount
static boolean enabled
private static integer array damageType_p
private static integer array damageId_p
private static integer array instance_p
private static integer runInstanceCount_p
private static integer runAttackCount_p
private static method allocateAttack takes integer damageType, integer damageId, integer instance returns nothing
set runInstanceCount_p = runInstanceCount_p + 1
set damageType_p[runInstanceCount_p] = damageType
set damageId_p[runInstanceCount_p] = damageId
set instance_p[runInstanceCount_p] = instance
endmethod
static method unitDamageTarget takes unit attacker, widget target, real amount, integer damageType, integer damageId, integer instance returns boolean
if (enabled) then
call allocateAttack(damageType, damageId, instance)
return UnitDamageTarget(attacker, target, amount, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
endif
return false
endmethod
static method operator damageType takes nothing returns integer
return damageType_p[runInstanceCount_p]
endmethod
static method operator damageId takes nothing returns integer
return damageId_p[runInstanceCount_p]
endmethod
static method operator instance takes nothing returns integer
return instance_p[runInstanceCount_p]
endmethod
static method operator depth takes nothing returns integer
return runAttackCount_p
endmethod
private static delegate DamageEventProperties damageEventProperties = 0
private static method damage takes nothing returns boolean
local integer previousTargetId
local integer previousSourceId
local real previousAmount
//! runtextmacro optional ADV_DAMAGE_EVENT_LOC_BEFORE()
if (enabled and 0 != GetEventDamage()) then
/*
* Setup spell
*/
set runAttackCount_p = runAttackCount_p + 1
if (runAttackCount_p != runInstanceCount_p) then
set runInstanceCount_p = runInstanceCount_p + 1
endif
/*
* Store previous amounts
*/
set previousTargetId = targetId
set previousSourceId = sourceId
set previousAmount = amount
/*
* Update amounts to new amounts
*/
set targetId = GetUnitUserData(GetTriggerUnit())
set sourceId = GetUnitUserData(GetEventDamageSource())
set amount = GetEventDamage()
/*
* Fire event
*/
//! runtextmacro optional ADV_DAMAGE_EVENT_EXT()
call ANY.fire()
/*
* Restore previous amounts
*/
set targetId = previousTargetId
set sourceId = previousSourceId
set amount = previousAmount
//! runtextmacro optional ADV_DAMAGE_EVENT_LOC_AFTER()
/*
* Remove spell
*/
set damageType_p[runInstanceCount_p] = 0
set damageId_p[runInstanceCount_p] = 0
set instance_p[runInstanceCount_p] = 0
set runInstanceCount_p = runInstanceCount_p - 1
set runAttackCount_p = runAttackCount_p - 1
endif
return false
endmethod
private static method index takes nothing returns boolean
call UnitIndex(GetIndexedUnitId()).lock()
call DamageTriggerHeap.add(GetIndexedUnitId())
return false
endmethod
private static method deindex takes nothing returns boolean
call DamageTriggerHeap.remove(GetIndexedUnitId())
call UnitIndex(GetIndexedUnitId()).unlock()
return false
endmethod
private static method onInit takes nothing returns nothing
set enabled = true
set runInstanceCount_p = 0
set runAttackCount_p = 0
set damageCondition = Condition(function thistype.damage)
set ANY = PriorityEvent.create()
call RegisterUnitIndexEvent(Condition(function thistype.index), UnitIndexer.INDEX)
call RegisterUnitIndexEvent(Condition(function thistype.deindex), UnitIndexer.DEINDEX)
set targetId = 0
set sourceId = 0
set amount = 0
endmethod
endmodule
struct DamageEvent extends array
implement DamageEventMod
endstruct
module ExtendDamageEvent
static if AdvDamageEvent_p.onDamage_p_core.exists then
private static delegate AdvDamageEvent advDamageEvent = 0
else
private static delegate DamageEvent damageEvent = 0
endif
endmodule
module DamageEvent
implement ExtendDamageEvent
static if thistype.onDamage.exists then
private static method onDamage_p takes nothing returns boolean
static if thistype.filter.exists then
if (filter()) then
call onDamage()
endif
else
call onDamage()
endif
return false
endmethod
private static method onInit takes nothing returns nothing
static if thistype.PRIORITY.exists then
call DamageEvent.ANY.register(Condition(function thistype.onDamage_p), PRIORITY())
else
call DamageEvent.ANY.register(Condition(function thistype.onDamage_p), 0)
endif
endmethod
endif
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library StunSystem uses Table
//********************************************************************************
// Stun - Version 1.2.0.0 - By iAyanami aka Ayanami
//********************************************************************************
//
// Stun:
// - An easy to use system that stuns units
// - Able to keep track of the remaining stun duration
//
// Requirements:
// - JASS NewGen
// - Table
//
// Functions:
// - Stun.apply takes unit whichUnit, real duration, boolean stack returns nothing
// * whichUnit is the target to be stunned
// * duration is the duration of the stun
// * stack is to determine if the stun should be a stacking one or not
// * true - the stun will stack, the duration of the stun will add up with the previous duration
// * false - the stun will not stack, the unit will be stunned for the longer stun duration
//
// - Stun.getDuration takes unit whichUnit returns real
// * whichUnit is the target to check
// * returns the remaining stun duration
//
// - Stun.stop takes unit whichUnit returns nothing
// * removes stun from the target
//
// How to import:
// - Copy the whole "Stun" Trigger Folder into your map
// - Save the map. Close and re-opem the map.
// - You should have a new unit (Stun Dummy), ability (Stun (System)) and buff (Stun (System)) created
// - Read through the Configuration part of the code
//
// Credits:
// - Bribe for Table
//
//********************************************************************************
// CONFIGURABLES
//********************************************************************************
globals
private constant real PERIOD = 0.03125
private constant integer ABILID = 'ASTN'
private constant integer BUFFID = 'BSTN'
private constant integer STUNID = 'sTUN'
endglobals
//********************************************************************************
// CODE
//********************************************************************************
module Init
private static method onInit takes nothing returns nothing
set table = Table.create()
set caster = CreateUnit(Player(13), STUNID, 0, 0, 0)
call UnitAddAbility(caster, ABILID)
endmethod
endmodule
struct Stun extends array
private unit u
private real dur
private thistype next
private thistype prev
private static Table table
private static timer t = CreateTimer()
private static unit caster
private static integer count = 0
// remove the stun and deallocate
private method destroy takes nothing returns nothing
call UnitRemoveAbility(this.u, BUFFID)
if this.next != 0 then
set this.next.prev = this.prev
endif
set this.prev.next = this.next
set this.dur = 0
set this.prev = thistype(0).prev
set thistype(0).prev = this
if thistype(0).next == 0 then
call PauseTimer(t)
endif
call table.remove(GetHandleId(this.u))
endmethod
// iterating through all instances every PERIOD
private static method iterate takes nothing returns nothing
local thistype this = thistype(0)
loop
set this = this.next
exitwhen this == 0
if this.dur <= 0 or IsUnitType(this.u, UNIT_TYPE_DEAD) or GetUnitTypeId(this.u) == 0 then
call this.destroy()
else
set this.dur = this.dur - PERIOD
endif
endloop
endmethod
// immediately removes stun for the specified unit
// ex: call Stun.stop(whichTarget)
static method stop takes unit u returns nothing
local integer id = GetHandleId(u)
if table.has(id) then
call thistype(table[id]).destroy()
endif
endmethod
// gets the duration left for stun, not stunned units always return 0
// ex: local real r = Stun.getDuration(whichTarget)
static method getDuration takes unit u returns real
return thistype(table[GetHandleId(u)]).dur
endmethod
// stunning specified target and to see if the stun is a stacking one or not
// ex: call Stun.apply(whichTarget, 5.0, false)
static method apply takes unit u, real dur, boolean b returns nothing
local thistype this
local integer id = GetHandleId(u)
if table.has(id) then
set this = table[id]
else
if thistype(0).prev == 0 then
set count = count + 1
set this = count
else
set this = thistype(0).prev
set thistype(0).prev = thistype(0).prev.prev
endif
if thistype(0).next == 0 then
call TimerStart(t, PERIOD, true, function thistype.iterate)
else
set thistype(0).next.prev = this
endif
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
set table[id] = this
set this.u = u
set this.dur = 0
call IssueTargetOrder(caster, "firebolt", this.u)
endif
if b and dur > 0 then
set this.dur = this.dur + dur
else
if this.dur < dur then
set this.dur = dur
endif
endif
endmethod
implement Init
endstruct
endlibrary
//TESH.scrollpos=176
//TESH.alwaysfold=0
library AdvancedTextTag /* ver 2.1 - vuongkkk */
globals
public constant real PERIOD = 0.025
constant integer TT_NORMAL = 0
constant integer TT_CRITICAL = 1
constant integer TT_CURVED = 2
constant integer TT_WHIRL = 3
constant integer TT_SPELL = 4
endglobals
function SetTextTagVelocityEx takes texttag tag, real speed, real angle returns nothing
call SetTextTagVelocity(tag, speed*Cos(angle* bj_DEGTORAD)*.071/128, speed*Sin(angle* bj_DEGTORAD)*.071/128)
endfunction
private function Parabol takes real h, real d, real x returns real
return (4 * h / d) * (d - x) * (x / d)
endfunction
struct DTexttag extends array
private static integer timerInstanceCount = 0
private static thistype instanceCount = 0
private static integer array recycler
private static timer T = CreateTimer()
private static trigger trig=CreateTrigger()
private triggercondition la
readonly texttag tag
real age
real fadepoint
real lifespan
string text
real size
method setupText takes string text, real size returns nothing
set .text = text
set .size = size
call SetTextTagText(tag, text, size * .0023)
endmethod
real angle
real speed
method setupVelocity takes real speed, real angle returns nothing
set .angle = angle
set .speed = speed
call SetTextTagVelocity(tag, speed*Cos(angle* bj_DEGTORAD)*.071/128, speed*Sin(angle* bj_DEGTORAD)*.071/128)
endmethod
real posX
real posY
real posZ
method setupPosition takes real x, real y, real z returns nothing
call SetTextTagPos(tag, x , y, z)
endmethod
static integer Al
static real A
static real Spd
static thistype current
readonly thistype next
private thistype prev
private method remove takes nothing returns nothing
call DestroyTextTag(tag)
call TriggerRemoveCondition(trig, la)
set prev.next = next
set next.prev = prev
endmethod
private static method update takes nothing returns nothing
local thistype this = thistype(0).next
loop
exitwhen 0 == this
if age < lifespan-PERIOD then
set age = age + PERIOD
set this = next
else
call remove()
set recycler[this] = recycler[0]
set recycler[0] = this
set this = next
set timerInstanceCount = timerInstanceCount - 1
endif
endloop
set current=thistype(0).next
if (0 == timerInstanceCount) then
call PauseTimer(T)
else
call TriggerEvaluate(trig)
endif
endmethod
static method allocate takes boolexpr func returns thistype
local thistype this = recycler[0]
local texttag tt=CreateTextTag()
if GetHandleId(tt)==0 then
set this = thistype(0).next
call remove()
set tt=CreateTextTag()
endif
if (0 == this) then
set this = instanceCount + 1
set instanceCount = this
else
set recycler[0] = recycler[this]
endif
set next = 0
set prev = thistype(0).prev
set thistype(0).prev.next = this
set thistype(0).prev = this
set tag=tt
set age=0
set fadepoint = 0
call SetTextTagVisibility(tt, true)
call SetTextTagPermanent(tag,false)
set la=TriggerAddCondition(trig, func)
if (0 == timerInstanceCount) then
call TimerStart(T, PERIOD, true, function thistype.update)
endif
set timerInstanceCount = timerInstanceCount + 1
return this
endmethod
endstruct
private struct CriticalStyle extends array
static boolexpr cons
static method onLoop takes nothing returns boolean
local DTexttag dtt=DTexttag.current
local real period=dtt.lifespan/6
if dtt.age < period then
call SetTextTagVelocityEx(dtt.tag,dtt.speed+Parabol(36.0,period*2, dtt.age),dtt.angle)
call SetTextTagText(dtt.tag,dtt.text, (dtt.size+Parabol(9.0,period, dtt.age))*.0023)
endif
set DTexttag.current=dtt.next
return false
endmethod
private static method onInit takes nothing returns nothing
set thistype.cons=Condition(function thistype.onLoop)
endmethod
endstruct
private struct CurvedStyle extends array
static boolexpr cons
static method onLoop takes nothing returns boolean
local DTexttag dtt=DTexttag.current
if dtt.age < dtt.lifespan/2 then
set DTexttag.Spd=dtt.speed+Parabol(46.0,dtt.lifespan, dtt.age)
else
set DTexttag.Spd=(dtt.speed+36.0)*(1+0.05*(dtt.age-dtt.lifespan/2)/PERIOD)
endif
call SetTextTagVelocityEx(dtt.tag,DTexttag.Spd, dtt.angle+Parabol(18.0,dtt.lifespan, dtt.age))
call SetTextTagText(dtt.tag,dtt.text,(dtt.size+Parabol(10.0,dtt.lifespan, dtt.age))*.0023)
set DTexttag.current=dtt.next
return false
endmethod
private static method onInit takes nothing returns nothing
set thistype.cons=Condition(function thistype.onLoop)
endmethod
endstruct
private struct WhirlStyle extends array
static boolexpr cons
static method onLoop takes nothing returns boolean
local DTexttag dtt=DTexttag.current
call SetTextTagVelocityEx(dtt.tag,dtt.speed+Parabol(42.0,dtt.lifespan, dtt.age)+dtt.age*1.01, dtt.angle+Parabol(460.0,dtt.lifespan, dtt.age))
call SetTextTagText(dtt.tag,dtt.text,(dtt.size+Parabol(9.0,dtt.lifespan, dtt.age))*.0023)
set DTexttag.current=dtt.next
return false
endmethod
private static method onInit takes nothing returns nothing
set thistype.cons=Condition(function thistype.onLoop)
endmethod
endstruct
function CreateAdvancedTextTag takes integer wtype, string mes, real x, real y returns nothing
local DTexttag dtt
if wtype == TT_NORMAL then
set bj_lastCreatedTextTag = CreateTextTag()
call SetTextTagText(bj_lastCreatedTextTag, mes, 12*.0023)
call SetTextTagPos(bj_lastCreatedTextTag, x, y, 0.)
call SetTextTagVelocityEx(bj_lastCreatedTextTag,110,90)
call SetTextTagLifespan(bj_lastCreatedTextTag,2.)
call SetTextTagFadepoint(bj_lastCreatedTextTag,1.)
call SetTextTagPermanent(bj_lastCreatedTextTag,false)
call SetTextTagVisibility(bj_lastCreatedTextTag,true)
elseif wtype == TT_CRITICAL then
set dtt=DTexttag.allocate(CriticalStyle.cons)
set dtt.lifespan= 2.2
call dtt.setupVelocity(46.00, 90)
call dtt.setupText(mes, 13.0)
call dtt.setupPosition(x, y, 0.)
elseif wtype == TT_CURVED then
set dtt=DTexttag.allocate(CurvedStyle.cons)
set dtt.fadepoint= 0.9
set dtt.lifespan= 1.8
call dtt.setupText(mes, 7.0)
call dtt.setupVelocity(49.00, 90)
call dtt.setupPosition(x, y, 0.)
elseif wtype == TT_WHIRL then
set dtt=DTexttag.allocate(WhirlStyle.cons)
set dtt.fadepoint= 0.01
set dtt.lifespan= 1.9
call dtt.setupText(mes, 7.0)
call dtt.setupVelocity(29.00, 0)
call dtt.setupPosition(x, y, 0.)
elseif wtype == TT_SPELL then
set dtt=DTexttag.allocate(CurvedStyle.cons)
set dtt.fadepoint= 0.9
set dtt.lifespan= 1.8
call dtt.setupText(mes, 6.0)
call dtt.setupVelocity(49.00, 90)
call dtt.setupPosition(x, y+50, 0.)
endif
endfunction
endlibrary
//TESH.scrollpos=196
//TESH.alwaysfold=0
/*********************************************
*
* DamageSystem
* v1.0.0.0
* By Magtheridon96 // Edited by -Kobas- (Replaced GetRandomReal(0,1) with GetRandomReal(0,100)), added Math lib
*
* API:
* ----
*
* struct Unit extends array
*
* real criticalChance
* real criticalMultiplier
*
* real spellCriticalChance
* real spellCriticalMultiplier
*
* real spellPower
*
* real fireResistance
* real coldResistance
* real poisonResistance
* real lightningResistance
*
* real fireDamage
* real coldDamage
* real poisonDamage
* real lightningDamage
*
* real bashChance
* real bashDuration
*
* real evasion
*
* real reflectChance
* real reflectPercent
*
* static method operator [] takes unit u returns thistype
* - Pass in the unit and get the struct instance
*
* method setResistance takes real fire, real cold, real poison, real lightnin returns nothing
* method setDamage takes real fire, real cold, real poison, real lightnin returns nothing
* method setBash takes real chance, real dur returns nothing
* method setCritical takes real critChan, real critMult returns nothing
* method setSpellCritical takes real critChan, real critMult returns nothing
* method setReflect takes real chance, real percent returns nothing
* method setEvasion takes real evas returns nothing
* method setSpellPower takes real pow returns nothing
* - These functions allow you to modify unit stat values
*
* method damageTarget takes unit target, real amount, integer damageType returns nothing
* - This function will deal spell damage
*
* function IsReflectedDamage takes nothing returns boolean
* - Calling this on damage events will determine whether the damage is reflected or not
* function IsPoisonDPS takes nothing returns boolean
* - Calling this on damage events will determine whether the damage is poison damage per second or not
* function IsFireSplashDamage takes nothing returns boolean
* - Calling this on damage events will determine whether the damage is fire splash damage per second or not
* function IsAttackDamage takes nothing returns boolean
* - Calling this on damage events will determine whether the damage is from an attack or not
*
*********************************************/
library DamageSystem requires UnitIndexer, DamageEvent, AdvancedTextTag, Math
globals
/*
* DamageType Declarations
*/
private constant integer DAMAGE_NORMAL = 1
private constant integer DAMAGE_FIRE = 2
private constant integer DAMAGE_COLD = 3
private constant integer DAMAGE_POISON = 4
private constant integer DAMAGE_LIGHTNING = 5
/*
* Damage Configuration
*/
private constant real FIRE_AOE = 150.
private constant real POISON_INTERVAL = 1.
private constant integer POISON_DAMAGE_COUNT = 5
/*
* Ability Raw Codes
*/
private constant integer SLOW_ABIL = 'A00O'
/*
* What are the symbols for Critical/Bash/Reflection?
*/
private constant string CRIT_CHAR = "!"
private constant string BASH_CHAR = "?"
private constant string REFLECT_CHAR = "#"
/*
* Color configuration
*/
private constant string CRIT_COLOR = "|cffff0000"
private constant string BASH_COLOR = "|cffc3dbff"
private constant string REFLECT_COLOR = "|cffffffff"
private constant string HEAL_COLOR = "|cff33ff33"
private constant string ENEMY_COLOR = "|cffff0000"
endglobals
globals
private boolean poisonEvent = false
private boolean reflectEvent = false
private boolean fireSplashEvent = false
private boolean damageTargetEvent = false
endglobals
globals
private constant integer ANTI_DEATH_ABIL = 'A002'
endglobals
function GiveAntiDeath takes unit whichUnit returns nothing
call UnitAddAbility(whichUnit, ANTI_DEATH_ABIL)
endfunction
function RemoveAntiDeath takes unit whichUnit returns nothing
call UnitRemoveAbility(whichUnit, ANTI_DEATH_ABIL)
endfunction
private struct PoisonDPS extends array
private static timer tmr = CreateTimer()
private static integer stack = 0
private static thistype array next
private static thistype array prev
private static unit array source
private static real array amount
private static integer array count
private static boolean array active
private method destroy takes nothing returns nothing
set source[this] = null
set active[this] = false
set next[prev[this]] = next[this]
set prev[next[this]] = prev[this]
set stack = stack - 1
if stack == 0 then
call PauseTimer(tmr)
endif
endmethod
private static method iterate takes nothing returns nothing
local thistype this = next[0]
loop
exitwhen this == 0
if not IsUnitType(GetUnitById(this), UNIT_TYPE_DEAD) then
set poisonEvent = true
call UnitDamageTarget(source[this], GetUnitById(this), amount[this], false, false, null, DAMAGE_TYPE_NORMAL, null)
set poisonEvent = false
else
call this.destroy()
endif
set count[this] = count[this] - 1
if count[this] == 0 then
call this.destroy()
endif
set this = next[this]
endloop
endmethod
static method push takes unit src, unit trg, real amn returns nothing
local thistype this = GetUnitUserData(trg)
if not active[this] then
set next[this] = 0
set prev[this] = prev[0]
set next[prev[0]] = this
set prev[0] = this
set source[this] = src
set amount[this] = amn
set active[this] = true
set stack = stack + 1
if stack == 1 then
call TimerStart(tmr, POISON_INTERVAL, true, function thistype.iterate)
endif
endif
set count[this] = POISON_DAMAGE_COUNT
endmethod
endstruct
struct Unit extends array
private static string array colors
private static unit damageDummy
real criticalChance
real criticalMultiplier
real spellCriticalChance
real spellCriticalMultiplier
real spellPower
real fireResistance
real coldResistance
real poisonResistance
real lightningResistance
real fireDamage
real coldDamage
real poisonDamage
real lightningDamage
real bashChance
real bashDuration
real evasion
real reflectChance
real reflectPercent
static method operator [] takes unit u returns thistype
return GetUnitUserData(u)
endmethod
method setResistance takes real fire, real cold, real poison, real lightnin returns nothing
set this.fireResistance = fire/100
set this.coldResistance = cold/100
set this.poisonResistance = poison/100
set this.lightningResistance = lightnin/100//RMin(1, lightnin)
endmethod
method setDamage takes real fire, real cold, real poison, real lightnin returns nothing
set this.fireDamage = fire
set this.coldDamage = cold
set this.poisonDamage = poison
set this.lightningDamage = lightnin
endmethod
method setBash takes real chance, real dur returns nothing
set this.bashChance = chance
set this.bashDuration = dur
endmethod
method setCritical takes real critChan, real critMult returns nothing
set this.criticalChance = critChan
set this.criticalMultiplier = critMult
endmethod
method setSpellCritical takes real critChan, real critMult returns nothing
set this.spellCriticalChance = critChan
set this.spellCriticalMultiplier = critMult
endmethod
method setReflect takes real chance, real percent returns nothing
set this.reflectChance = chance
set this.reflectPercent = percent
endmethod
method setEvasion takes real evas returns nothing
set this.evasion = evas
endmethod
method setSpellPower takes real pow returns nothing
set this.spellPower = pow
endmethod
/*
* Recursion safe data manager
*/
private static integer array v
private static integer cc = 0
private static method new takes nothing returns nothing
set cc=cc+1
endmethod
private static method push takes integer value returns nothing
set v[cc]=v[cc]+value
endmethod
private static method pop takes nothing returns integer
return v[cc]
endmethod
private static method clear takes nothing returns nothing
set v[cc]=0
endmethod
private static method remove takes nothing returns nothing
set cc=cc+1
endmethod
method damageTarget takes unit target, real amount, integer damageType returns nothing
local unit source = GetUnitById(this)
local thistype targetId = GetUnitUserData(target)
local player sourceOwner = GetOwningPlayer(source)
local real a = amount
local unit u
local real x
local real y
set damageTargetEvent = true
if amount < 0 then
set amount = -amount
call SetWidgetLife(target, GetWidgetLife(target) + amount)
call CreateAdvancedTextTag(TT_CURVED,HEAL_COLOR + "+" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
else
if damageType == DAMAGE_NORMAL then
/*
* Check to see if spell critical should be applied
*/
if GetRandomReal(0, 100) < this.spellCriticalChance then
set amount = amount * this.spellCriticalMultiplier
call UnitDamageTarget(source, target, amount, false, false, null, DAMAGE_TYPE_NORMAL, null)
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CRITICAL, ENEMY_COLOR + "-" + I2S(R2I(amount)) + CRIT_CHAR, GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CRITICAL, CRIT_COLOR + "-" + I2S(R2I(amount)) + CRIT_CHAR, GetUnitX(target),GetUnitY(target))
endif
else
call UnitDamageTarget(source, target, amount, false, false, null, DAMAGE_TYPE_NORMAL, null)
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_NORMAL, ENEMY_COLOR + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_NORMAL, "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
endif
endif
elseif damageType == DAMAGE_POISON then
/*
* Set amount depending on resistance and deal damage
*/
set amount = 0.5 + amount - amount * targetId.poisonResistance
call UnitDamageTarget(source, target, amount, false, false, null, DAMAGE_TYPE_NORMAL, null)
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CURVED, ENEMY_COLOR + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CURVED, colors[DAMAGE_POISON] + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
endif
elseif damageType == DAMAGE_FIRE then
/*
* Set amount depending on resistance and deal damage
*/
set amount = 0.5 + amount - amount * targetId.fireResistance
call UnitDamageTarget(source, target, amount, false, false, null, DAMAGE_TYPE_NORMAL, null)
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CURVED, ENEMY_COLOR + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CURVED, colors[DAMAGE_FIRE] + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
endif
/*
* Let the damage detection function run for this system
* and flag the damage events as fire AoE splash damage
*/
set fireSplashEvent = true
set damageTargetEvent = false
/*
* Pick units in a small range and deal half the damage to them
*/
set x = GetUnitX(target)
set y = GetUnitY(target)
call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, FIRE_AOE + 197., null)
loop
set u = FirstOfGroup(bj_lastCreatedGroup)
exitwhen u == null
call GroupRemoveUnit(bj_lastCreatedGroup, u)
if u != target and IsUnitEnemy(u, sourceOwner) and not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and IsUnitInRangeXY(u, x, y, FIRE_AOE) then
call UnitDamageTarget(source, u, a/2+.5, false, false, null, DAMAGE_TYPE_NORMAL, null)
endif
endloop
set damageTargetEvent = true
set fireSplashEvent = false
elseif damageType == DAMAGE_COLD then
/*
* Set amount depending on resistance and deal damage
*/
set amount = 0.5 + amount - amount * targetId.coldResistance
call UnitDamageTarget(source, target, amount, false, false, null, DAMAGE_TYPE_NORMAL, null)
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CURVED, ENEMY_COLOR + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CURVED, colors[DAMAGE_COLD] + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
endif
/*
* Order dummy to slow target
*/
call IssueTargetOrder(damageDummy, "frostnova", target)
elseif damageType == DAMAGE_LIGHTNING then
/*
* Set amount depending on resistance and deal damage
*/
set amount = 0.5 + amount - amount * targetId.lightningResistance
call UnitDamageTarget(source, target, amount, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CURVED, ENEMY_COLOR + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CURVED, colors[DAMAGE_LIGHTNING] + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
endif
endif
endif
set damageTargetEvent = false
set source = null
set sourceOwner = null
endmethod
private static method onDamage takes nothing returns boolean
local string textTarget = ""
local string s = ""
local real a = 0
local real x
local real y
local unit u
/*
* Only for readability
*/
local real amount = DamageEvent.amount
local unit source = DamageEvent.source
local unit target = DamageEvent.target
local player sourceOwner = GetOwningPlayer(source)
local thistype targetId = DamageEvent.targetId
local thistype this = DamageEvent.sourceId
if not damageTargetEvent then
if poisonEvent then
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CURVED, "|cffff0000-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CURVED, colors[DAMAGE_POISON] + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
endif
else
if reflectEvent then
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CURVED, "|cffff0000-" + I2S(R2I(amount)) + REFLECT_CHAR, GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CURVED, REFLECT_COLOR + "-" + I2S(R2I(amount)) + REFLECT_CHAR, GetUnitX(target),GetUnitY(target))
endif
else
if fireSplashEvent then
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CURVED, "|cffff0000-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CURVED, colors[DAMAGE_FIRE] + "-" + I2S(R2I(amount)), GetUnitX(target),GetUnitY(target))
endif
else
set DamageEvent.enabled = false
if GetRandomReal(0, 100) < targetId.evasion then
call GiveAntiDeath(target)
call SetWidgetLife(target, GetWidgetLife(target) + amount)
call RemoveAntiDeath(target)
call CreateAdvancedTextTag(TT_CURVED, ENEMY_COLOR + "miss", GetUnitX(source),GetUnitY(source))
set DamageEvent.amount = 0
else
call new()
if GetRandomReal(0, 100) < this.criticalChance then
set a = amount * this.criticalMultiplier
call UnitDamageTarget(source, target, a - amount, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
if target == HERO or target == PET then
set textTarget = textTarget + "-" + I2S(R2I(a)) + CRIT_CHAR
elseif source == HERO or source == PET then
set s = "-" + I2S(R2I(a)) + CRIT_CHAR
set textTarget = textTarget + CRIT_COLOR + s + "|r"
call push(StringLength(s))
endif
set DamageEvent.amount = DamageEvent.amount + a - amount
else
set textTarget = textTarget + "-" + I2S(R2I(amount))
endif
/*
* Start dealing elemental damage
*/
if this.fireDamage > 0 then
set a = this.fireDamage - this.fireDamage * targetId.fireResistance
if target == HERO or target == PET then
set textTarget = textTarget + " -" + I2S(R2I(a))
elseif source == HERO or source == PET then
set s = " -" + I2S(R2I(a))
set textTarget = textTarget + colors[DAMAGE_FIRE] + s + "|r"
call push(StringLength(s))
endif
call UnitDamageTarget(source, target, a, false, false, null, DAMAGE_TYPE_NORMAL, null)
set DamageEvent.amount = DamageEvent.amount + a
set fireSplashEvent = true
set DamageEvent.enabled = true
/*
* Cache target coordinates
*/
set x = GetUnitX(target)
set y = GetUnitY(target)
/*
* Pick units in a small range and deal half the damage to them
*/
call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, FIRE_AOE + 197., null)
loop
set u = FirstOfGroup(bj_lastCreatedGroup)
exitwhen u == null
call GroupRemoveUnit(bj_lastCreatedGroup, u)
if u != target and IsUnitEnemy(u, sourceOwner) and not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and IsUnitInRangeXY(u, x, y, FIRE_AOE) then
call UnitDamageTarget(source, u, this.fireDamage - this.fireDamage * thistype(GetUnitUserData(u)).fireResistance, false, false, null, DAMAGE_TYPE_NORMAL, null)
endif
endloop
set DamageEvent.enabled = false
set fireSplashEvent = false
endif
if this.coldDamage > 0 then
set a = this.coldDamage - this.coldDamage * targetId.coldResistance
if target == HERO or target == PET then
set textTarget = textTarget + " -" + I2S(R2I(a))
elseif source == HERO or source == PET then
set s = " -" + I2S(R2I(a))
set textTarget = textTarget + colors[DAMAGE_COLD] + s + "|r"
call push(StringLength(s))
endif
call UnitDamageTarget(source, target, a, false, false, null, DAMAGE_TYPE_NORMAL, null)
set DamageEvent.amount = DamageEvent.amount + a
/*
* Apply the cold slow effect on the target
*/
call SetUnitX(damageDummy, GetUnitX(target))
call SetUnitY(damageDummy, GetUnitY(target))
call IssueTargetOrder(damageDummy, "frostnova", target)
endif
if this.poisonDamage > 0 then
set a = this.poisonDamage - this.poisonDamage * targetId.poisonResistance
if target == HERO or target == PET then
set textTarget = textTarget + " -" + I2S(R2I(a))
elseif source == HERO or source == PET then
set s = " -" + I2S(R2I(a))
set textTarget = textTarget + colors[DAMAGE_POISON] + s + "|r"
call push(StringLength(s))
endif
call UnitDamageTarget(source, target, a, false, false, null, DAMAGE_TYPE_NORMAL, null)
set DamageEvent.amount = DamageEvent.amount + a
/*
* Add the target to the Poison DPS struct
*/
call PoisonDPS.push(source, target, a)
endif
if this.lightningDamage > 0 then
set a = this.lightningDamage - this.lightningDamage * targetId.lightningResistance
if target == HERO or target == PET then
set textTarget = textTarget + " -" + I2S(R2I(a))
elseif source == HERO or source == PET then
set s = " -" + I2S(R2I(a))
set textTarget = textTarget + colors[DAMAGE_LIGHTNING] + s + "|r"
call push(StringLength(s))
endif
call UnitDamageTarget(source, target, a, false, false, null, DAMAGE_TYPE_UNIVERSAL, null)
set DamageEvent.amount = DamageEvent.amount + a
endif
if GetRandomReal(0, 100) < targetId.reflectChance then
set a = DamageEvent.amount * targetId.reflectPercent
/*
* Flag the reflecting event boolean to tell this system that the next
* damage event to execute will be the one caused by the reflected damage,
* and then we enable DamageEvent so the next event can actually run (for all
* other systems but this one.
*/
set reflectEvent = true
set DamageEvent.enabled = true
call UnitDamageTarget(target, source, a, false, false, null, DAMAGE_TYPE_NORMAL, null)
set DamageEvent.enabled = false
set reflectEvent = false
endif
/*
* This will handle bash chance and stunning.
*/
if GetRandomReal(0, 100) < this.bashChance then
call Stun.apply(target, this.bashDuration, false)
if target == HERO or target == PET then
set textTarget = textTarget + "\n" + R2SW(this.bashDuration, 3, 1) + BASH_CHAR
elseif source == HERO or source == PET then
set textTarget = textTarget + "\n" + BASH_COLOR + R2SW(this.bashDuration, 3, 1) + BASH_CHAR + "|r"
endif
endif
if textTarget != "" then
if target == HERO or target == PET then
call CreateAdvancedTextTag(TT_CURVED, "|cffff0000" + textTarget, GetUnitX(target),GetUnitY(target))
elseif source == HERO or source == PET then
call CreateAdvancedTextTag(TT_CURVED, textTarget, GetUnitX(target),GetUnitY(target))
endif
endif
call clear()
call remove()
endif
set DamageEvent.enabled = true
endif
endif
endif
endif
set source = null
set target = null
set sourceOwner = null
return false
endmethod
private static method onInit takes nothing returns nothing
call DamageEvent.ANY.register(Condition(function thistype.onDamage), 0x7FFFFFFF)
set damageDummy = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), DUMMY_ID, 0, 0, 0)
call UnitAddAbility(damageDummy, SLOW_ABIL)
set colors[DAMAGE_NORMAL] = "|cffffffff"
set colors[DAMAGE_FIRE] = "|cffff9900"
set colors[DAMAGE_COLD] = "|cff3333ff"
set colors[DAMAGE_POISON] = "|cffa0ff00"
set colors[DAMAGE_LIGHTNING] = "|cffffff33"
endmethod
endstruct
function IsReflectedDamage takes nothing returns boolean
return reflectEvent
endfunction
function IsPoisonDPS takes nothing returns boolean
return poisonEvent
endfunction
function IsFireSlashDamage takes nothing returns boolean
return fireSplashEvent
endfunction
function IsAttackDamage takes nothing returns boolean
return not reflectEvent and not poisonEvent and not fireSplashEvent and not damageTargetEvent
endfunction
endlibrary
//TESH.scrollpos=9
//TESH.alwaysfold=0
/************************************
*
* UnitRegeneration
* v1.0.0.0
* By Magtheridon96
*
* API:
* ----
*
* struct UnitRegeneration extends array
*
* static boolean enabled
*
* method enable takes nothing returns nothing
* method disable takes nothing returns nothing
*
* method operator life takes nothing returns real
* method operator life= takes real r returns nothing
*
* method operator mana takes nothing returns real
* method operator mana= takes real r returns nothing
*
************************************/
library UnitRegeneration requires UnitIndexer, CTL
function GetUnitMaxMana takes unit u returns real
return GetUnitState(u, UNIT_STATE_MAX_MANA)
endfunction
function GetUnitMaxLife takes unit u returns real
return GetUnitState(u, UNIT_STATE_MAX_LIFE)
endfunction
function SetUnitMaxLife takes unit u, real r returns nothing
call SetUnitState(u, UNIT_STATE_MAX_LIFE, r)
endfunction
function SetUnitMaxMana takes unit u, real r returns nothing
call SetUnitState(u, UNIT_STATE_MAX_MANA, r)
endfunction
function GetUnitMana takes unit u returns real
return GetUnitState(u, UNIT_STATE_MANA)
endfunction
function SetUnitMana takes unit u, real r returns nothing
call SetUnitState(u, UNIT_STATE_MANA, r)
endfunction
struct UnitRegeneration extends array
private static thistype array next
private static thistype array prev
private static boolean array running
private static real array hpRegen
private static real array mpRegen
private static real array hpRegenPercent
private static real array mpRegenPercent
static boolean enabled = true
method enable takes nothing returns nothing
set running[this] = true
endmethod
method disable takes nothing returns nothing
set running[this] = false
endmethod
method operator life takes nothing returns real
return hpRegen[this]*32
endmethod
method operator life= takes real r returns nothing
set hpRegen[this]=r/32
endmethod
method operator lifePercent takes nothing returns real
return hpRegenPercent[this]*32
endmethod
method operator lifePercent= takes real r returns nothing
set hpRegenPercent[this]=r/32
endmethod
method operator mana takes nothing returns real
return mpRegen[this]*32
endmethod
method operator mana= takes real r returns nothing
set mpRegen[this]=r/32
endmethod
method operator manaPercent takes nothing returns real
return mpRegenPercent[this]*32
endmethod
method operator manaPercent= takes real r returns nothing
set mpRegenPercent[this]=r/32
endmethod
implement CT32
local thistype this = next[0]
local real current
local real max
if enabled then
loop
exitwhen this == 0
if not IsUnitType(this.unit, UNIT_TYPE_DEAD) then
set current = GetWidgetLife(this.unit)
set max = GetUnitMaxLife(this.unit)
if max != current then
call SetWidgetLife(this.unit, current + hpRegen[this] + max * hpRegenPercent[this])
endif
set current = GetUnitMana(this.unit)
if GetUnitMaxMana(this.unit) != current then
call SetUnitMana(this.unit, current + mpRegen[this] + mpRegen[this] * mpRegenPercent[this])
endif
endif
set this = next[this]
endloop
endif
implement CT32End
private static method deindex takes nothing returns nothing
set next[prev[GetIndexedUnitId()]] = next[GetIndexedUnitId()]
set prev[next[GetIndexedUnitId()]] = prev[GetIndexedUnitId()]
endmethod
private static method index takes nothing returns nothing
set next[GetIndexedUnitId()] = 0
set prev[GetIndexedUnitId()] = prev[0]
set next[prev[0]] = GetIndexedUnitId()
set prev[0] = GetIndexedUnitId()
endmethod
implement UnitIndexStruct
endstruct
endlibrary
//TESH.scrollpos=144
//TESH.alwaysfold=0
library MoveSpeedX /* v1.0.0.1
*************************************************************************************
*
* This library allows you to set unit movement speeds beyond 522 without bugs.
* This is an extension of the library MoveSpeedX, but is formatted for GUI use.
*
************************************************************************************
*
* SETTINGS
*/
globals
private constant real PERIOD = 0.03125
// This is the period on which all units will be run.
// If you lower this value, movement bonuses will be smoother,
// but will require more processing power (lag more).
// Also, the lower this is, the higher the move speed can be
// before it starts bugging on waypoints. The lowest valid
// period is 0.00125. A period of 0.00625 is very robust.
private constant real MARGIN = 0.01
// This is the margin of approximation when comparing reals.
// You will most likely not need to change this.
endglobals
/*
************************************************************************************
*
* Functions
*
* function GetUnitMoveSpeedX takes unit whichUnit returns real
* - Returns a unit movement speed. The GUI function will
* - not return the correct value. This function will always
* - return the correct value regardless of whether the unit
* - has a movement speed beyond 522.
*
************************************************************************************
*
* REQUIREMENTS
*
* 1. JassNewGen Pack v5d
* 2. JassHelper 0.A.2.B
*
* HOW TO IMPLEMENT
*
* 1. Copy the trigger MoveSpeedXGUI.
* 2. Paste it into your map.
* 3. Open "Advanced -> Gameplay Constants".
* 4. Checkmark "Use Custom Gameplay Constants".
* 5. Find the field, "Movement - Unit Speed - Maximum", change
* that to 522.
* 6. Find the field, "Movement - Unit Speed - Minimum", hold
* shift and click, and change it to 0.
* 7. Read HOW TO USE.
*
************************************************************************************
*
* HOW TO USE
*
* This system will automatically work by itself. You can use the
* normal GUI function for modifying unit movement speeds. Simply
* use "Unit - Set Movement Speed", input whatever value you want,
* and you are good to go! It will handle values beyond 522 by itself.
*
* HOWEVER, the GUI function will not return correct values if a unit
* has a movement speed greater than 522. To fix this, use the function
* GetUnitMoveSpeedX to return the correct value. A sample is given in
* the trigger "Speed Change" in the test map.
*
************************************************************************************
*
* NOTES
*
* The unit may move randomly about one point before finally stopping. If
* this occurs, try changing PERIOD or reduce the unit movement speed.
*
* This also will not factor in bonuses.
*
************************************************************************************/
private function ApproxEqual takes real A, real B returns boolean
return (A >= (B - MARGIN)) and (A <= (B + MARGIN))
endfunction
private module M
private static integer ic = 0
private static integer ir = 0
static hashtable hash = InitHashtable()
thistype next
thistype prev
unit curr
real speed
real x
real y
method destroy takes nothing returns nothing
set this.next.prev = this.prev
set this.prev.next = this.next
set .prev = ir
set ir = this
call RemoveSavedInteger(hash, 0, GetHandleId(.curr))
endmethod
private static method periodic takes nothing returns nothing
local thistype this = thistype(0).next // first instance in list
local real nx = 0 // the x-coordinate after tick
local real ny = 0 // the y-coordinate after tick
local real dx = 0 // distance between new-x and old-x
local real dy = 0 // distance between new-y and old-y
local real d = 0 // distance between new point and old point
local unit u // unit being affected
loop
exitwhen this == 0
set u = .curr
set nx = GetUnitX(u)
set ny = GetUnitY(u)
if (not IsUnitPaused(u)) and GetUnitAbilityLevel(u, 'BSTN') == 0 and GetUnitAbilityLevel(u, 'BPSE') == 0 then
if not ApproxEqual(nx, .x) or not ApproxEqual(ny, .y) then
set dx = nx - .x
set dy = ny - .y
set d = SquareRoot(dx * dx + dy * dy)
set .x = nx + dx / d * .speed
set .y = ny + dy / d * .speed
call SetUnitX(u, .x)
call SetUnitY(u, .y)
endif
endif
set this = this.next
endloop
set u = null
endmethod
static method create takes unit whichUnit, real newSpeed returns thistype
local thistype this = ir
if this == 0 then
set ic = ic + 1
set this = ic
else
set ir = .prev
endif
set this.next = thistype(0).next
set thistype(0).next.prev = this
set thistype(0).next = this
set this.prev = 0
set this.curr = whichUnit
set this.speed = (newSpeed - 522) * PERIOD
set this.x = GetUnitX(whichUnit)
set this.y = GetUnitY(whichUnit)
call SaveInteger(hash, 0, GetHandleId(whichUnit), this)
return this
endmethod
static method update takes unit whichUnit, real newSpeed returns nothing
local thistype this = 0
if HaveSavedInteger(hash, 0, GetHandleId(whichUnit)) then
set this = LoadInteger(hash, 0, GetHandleId(whichUnit))
if newSpeed > 522 then
set this.speed = (newSpeed-522)*PERIOD
else
call this.destroy()
endif
elseif newSpeed > 522 then
call thistype.create(whichUnit, newSpeed)
endif
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), PERIOD, true, function thistype.periodic)
endmethod
endmodule
private struct MoveSpeedStruct extends array
implement M
endstruct
function GetUnitMoveSpeedX takes unit whichUnit returns real
if HaveSavedInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit)) then
return (MoveSpeedStruct(LoadInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit))).speed/PERIOD)+522
endif
return GetUnitMoveSpeed(whichUnit)
endfunction
function SetUnitMoveSpeedX takes unit whichUnit, real newSpeed returns nothing
call MoveSpeedStruct.update(whichUnit, newSpeed)
endfunction
hook SetUnitMoveSpeed SetUnitMoveSpeedX
endlibrary
//TESH.scrollpos=15
//TESH.alwaysfold=0
library Bonus uses UnitIndexer
globals
constant integer BONUS_TYPE_STR = 1
constant integer BONUS_TYPE_AGI = 2
constant integer BONUS_TYPE_INT = 3
constant integer BONUS_TYPE_ARMOR = 4
constant integer BONUS_TYPE_DAMAGE = 5
constant integer BONUS_TYPE_ATTACK_SPEED = 6
constant integer BONUS_TYPE_LIFE = 7
constant integer BONUS_TYPE_MANA = 8
endglobals
private module Init
private static method onInit takes nothing returns nothing
local integer int = 1
local integer i = 0
local integer b = 1
local unit dummy = CreateUnit(Player(15), 'e006', 0, 0, 0)
loop
set twoPow[i] = int
exitwhen i == 30
set i = i + 1
set int = int * 2
endloop
set ABIL[BONUS_TYPE_STR] = 'A5A@'
set ABIL[BONUS_TYPE_ARMOR] = 'A5B@'
set ABIL[BONUS_TYPE_AGI] = 'A5D@'
set ABIL[BONUS_TYPE_INT] = 'A5E@'
set ABIL[BONUS_TYPE_DAMAGE] = 'A5C@'
set ABIL[BONUS_TYPE_ATTACK_SPEED] = 'A5F@'
set ABIL[BONUS_TYPE_LIFE] = 'A5G@'
set ABIL[BONUS_TYPE_MANA] = 'A5H@'
set LEVEL[BONUS_TYPE_ARMOR] = 10
set LEVEL[BONUS_TYPE_DAMAGE] = 15
set LEVEL[BONUS_TYPE_STR] = 10
set LEVEL[BONUS_TYPE_AGI] = 10
set LEVEL[BONUS_TYPE_INT] = 10
set LEVEL[BONUS_TYPE_ATTACK_SPEED] = 9
set LEVEL[BONUS_TYPE_LIFE] = 15
set LEVEL[BONUS_TYPE_MANA] = 20
loop
exitwhen ABIL[b] == 0
set int = ABIL[b] + LEVEL[i]
loop
call UnitAddAbility(dummy,int)
exitwhen int == ABIL[b]
set int = int - 1
endloop
set b = b + 1
endloop
call RemoveUnit(dummy)
set dummy = null
call RegisterUnitIndexEvent(Condition(function thistype.index), UnitIndexer.INDEX)
call RegisterUnitIndexEvent(Condition(function thistype.deindex), UnitIndexer.DEINDEX)
endmethod
endmodule
struct Bonus extends array
private static integer array ABIL
private static integer array LEVEL
private static integer array twoPow
private static Table array bonus
static method operator [] takes unit u returns thistype
return GetUnitUserData(u)
endmethod
method operator unit takes nothing returns unit
return GetUnitById(this)
endmethod
private static method index takes nothing returns boolean
if bonus[GetIndexedUnitId()] == 0 then
set bonus[GetIndexedUnitId()] = Table.create()
endif
return false
endmethod
private static method deindex takes nothing returns boolean
call bonus[GetIndexedUnitId()].flush()
return false
endmethod
private static method compute takes unit u, integer abil, integer levels, integer amount returns nothing
local boolean n = amount < 0
if n then
set amount = amount + twoPow[levels]
else
call UnitMakeAbilityPermanent(u, false, abil)
call UnitRemoveAbility(u, abil)
endif
set abil = abil + levels
set levels = twoPow[levels]
loop
set levels = levels / 2
if amount >= levels then
call UnitAddAbility(u, abil)
call UnitMakeAbilityPermanent(u, true, abil)
set amount = amount - levels
else
call UnitMakeAbilityPermanent(u, false, abil)
call UnitRemoveAbility(u, abil)
endif
set abil = abil - 1
exitwhen levels == 1
endloop
if n then
call UnitAddAbility(u, abil)
call UnitMakeAbilityPermanent(u, true, abil)
endif
endmethod
method getBonus takes integer b returns integer
return bonus[this][b]
endmethod
method setBonus takes integer b, integer v returns nothing
set bonus[this][b]=v
call compute(this.unit,ABIL[b],LEVEL[b],v)
endmethod
method removeBonus takes integer b returns nothing
call this.setBonus(b,0)
endmethod
method addBonus takes integer b, integer v returns nothing
call this.setBonus(b,this.getBonus(b)+v)
endmethod
implement Init
endstruct
endlibrary
//TESH.scrollpos=39
//TESH.alwaysfold=0
library Status uses UnitIndexer, CTL
globals
private constant integer ABIL_SILENCE='A501'
private constant integer ABIL_DISARM='A502'
private constant integer ABIL_IMMOBOLISE='A505'
private constant integer ABIL_INVISIBLE='A507'
private constant integer ABIL_GHOST='A508'
private constant integer ABIL_DOOM='A509'
private constant integer ABIL_IMMUNITY='A50B'
private constant integer ABIL_HEX='A50C'
private constant integer ABIL_NEVER_MISS='A50F'
private constant integer ABIL_ALWAYS_MISS='A50H'
private constant integer ABIL_UNTOUCHABLE='A50J'
private constant integer ABIL_BANISH='A50K'
private constant integer ABIL_PHASE='A50L'
private constant integer ABIL_RESISTANT_SKIN='A50Q'
private constant integer ABIL_REFLECT_PIERCING='A50S'
private constant integer ABIL_DISABLE='A50T'
private constant integer BUFF_SILENCE='B501'
private constant integer BUFF_DOOM='B509'
private constant integer BUFF_DISARM='B502'
private constant integer BUFF_IMMOBOLISE_GROUND='B505'
private constant integer BUFF_IMMOBOLISE_AIR='B506'
private constant integer BUFF_HEX='B50C'
private constant integer BUFF_BANISH='B50K'
private constant integer BUFF_PHASE='B50L'
private constant integer BUFF_DISABLE='B50T'
private constant integer OID_STOP=851972 //stop
private constant integer OID_SILENCE=852668 //soulburn
private constant integer OID_DISARM=852585 //drunkenhaze
private constant integer OID_IMMOBOLISE=852106 //ensnare
private constant integer OID_DOOM=852583 //doom
private constant integer OID_HEX=852502 //hex
private constant integer OID_BANISH=852486 //banish
private constant integer OID_PHASE=852129 //windwalk
private constant integer OID_DISABLE=852252 //creepthunderbolt (hurlboulder)
private unit CASTER_DISARM = null
endglobals
private module Init
private static method onInit takes nothing returns nothing
local integer i = 0
local unit dummy = CreateUnit(Player(15), 'e006', 0, 0, 0)
set thistype.dummyCaster = CreateUnit(Player(15), 'e006', 0, 0, 0)
call UnitAddAbility(thistype.dummyCaster,ABIL_DISABLE)
call UnitAddAbility(thistype.dummyCaster,ABIL_SILENCE)
call UnitAddAbility(thistype.dummyCaster,ABIL_DISARM)
call UnitAddAbility(thistype.dummyCaster,ABIL_IMMOBOLISE)
call UnitAddAbility(thistype.dummyCaster,ABIL_DOOM)
call UnitAddAbility(thistype.dummyCaster,ABIL_HEX)
call UnitAddAbility(thistype.dummyCaster,ABIL_BANISH)
loop
call SetPlayerAbilityAvailable(Player(i),ABIL_IMMUNITY,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_NEVER_MISS,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_ALWAYS_MISS,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_UNTOUCHABLE,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_RESISTANT_SKIN,false)
call SetPlayerAbilityAvailable(Player(i),ABIL_REFLECT_PIERCING,false)
exitwhen i == 9
set i = i + 1
endloop
call UnitAddAbility(dummy,ABIL_INVISIBLE)
call UnitAddAbility(dummy,ABIL_GHOST)
call UnitAddAbility(dummy,ABIL_IMMUNITY)
call UnitAddAbility(dummy,ABIL_NEVER_MISS)
call UnitAddAbility(dummy,ABIL_ALWAYS_MISS)
call UnitAddAbility(dummy,ABIL_UNTOUCHABLE)
call UnitAddAbility(dummy,ABIL_PHASE)
call UnitAddAbility(dummy,ABIL_RESISTANT_SKIN)
call UnitAddAbility(dummy,ABIL_REFLECT_PIERCING)
call RemoveUnit(dummy)
set dummy = null
endmethod
endmodule
struct Status extends array
private static method index takes nothing returns nothing
local thistype this = GetIndexedUnitId()
call UnitShareVision(this.unit, Player(15), true)
set this.disableLevel = 0
set this.silenceLevel = 0
set this.doomLevel = 0
set this.disarmLevel = 0
set this.immoboliseLevel = 0
set this.invisibleLevel = 0
set this.ghostLevel = 0
set this.immunityLevel = 0
set this.hexLevel = 0
set this.neverMissLevel = 0
set this.alwaysMissLevel = 0
set this.untouchableLevel = 0
set this.banishLevel = 0
set this.phaseLevel = 0
set this.resistantSkinLevel = 0
set this.reflectPiercingLevel = 0
endmethod
implement UnitIndexStruct
private static unit dummyCaster=null
implement Init
// Disable
private integer disableLevel
method addDisable takes nothing returns nothing
set this.disableLevel=this.disableLevel+1
if this.disableLevel>0 then
call IssueTargetOrderById(thistype.dummyCaster,OID_DISABLE,this.unit)
endif
endmethod
method removeDisable takes nothing returns nothing
set this.disableLevel=this.disableLevel-1
if this.disableLevel==0 then
call UnitRemoveAbility(this.unit,BUFF_DISABLE)
endif
endmethod
method isDisabled takes nothing returns boolean
return this.disableLevel>0
endmethod
// Silence
private integer silenceLevel
method addSilence takes nothing returns nothing
set this.silenceLevel=this.silenceLevel+1
if this.silenceLevel>0 then
call IssueTargetOrderById(thistype.dummyCaster,OID_SILENCE,this.unit)
endif
endmethod
method removeSilence takes nothing returns nothing
set this.silenceLevel=this.silenceLevel-1
if this.silenceLevel==0 then
call UnitRemoveAbility(this.unit,BUFF_SILENCE)
endif
endmethod
method isSilenced takes nothing returns boolean
return this.silenceLevel>0
endmethod
private integer doomLevel
method addDoom takes nothing returns nothing
set this.doomLevel=this.doomLevel+1
if this.doomLevel>0 then
call IssueTargetOrderById(thistype.dummyCaster,OID_DOOM,this.unit)
endif
endmethod
method removeDoom takes nothing returns nothing
set this.doomLevel=this.doomLevel-1
if this.doomLevel==0 then
call UnitRemoveAbility(this.unit,BUFF_DOOM)
endif
endmethod
method isDoomed takes nothing returns boolean
return this.doomLevel>0
endmethod
private integer disarmLevel
method addDisarm takes nothing returns nothing
set this.disarmLevel=this.disarmLevel+1
if this.disarmLevel>0 then
call IssueTargetOrderById(thistype.dummyCaster,OID_DISARM,this.unit)
endif
endmethod
method removeDisarm takes nothing returns nothing
set this.disarmLevel=this.disarmLevel-1
if this.disarmLevel==0 then
call UnitRemoveAbility(this.unit,BUFF_DISARM)
endif
endmethod
method isDisarmed takes nothing returns boolean
return this.disarmLevel>0
endmethod
// Immobolise
private integer immoboliseLevel
method addImmobolise takes nothing returns nothing
set this.immoboliseLevel=this.immoboliseLevel+1
if this.immoboliseLevel>0 then
call IssueTargetOrderById(thistype.dummyCaster,OID_IMMOBOLISE,this.unit)
endif
endmethod
method removeImmobolise takes nothing returns nothing
set this.immoboliseLevel=this.immoboliseLevel-1
if this.immoboliseLevel==0 then
call UnitRemoveAbility(this.unit,BUFF_IMMOBOLISE_GROUND)
call UnitRemoveAbility(this.unit,BUFF_IMMOBOLISE_AIR)
endif
endmethod
method isImmobolised takes nothing returns boolean
return this.immoboliseLevel>0
endmethod
// Invisibility
private integer invisibleLevel
method addInvisible takes nothing returns nothing
set this.invisibleLevel=this.invisibleLevel+1
if this.invisibleLevel>0 then
call UnitAddAbility(this.unit,ABIL_INVISIBLE)
call UnitMakeAbilityPermanent(this.unit,true,ABIL_INVISIBLE)
endif
endmethod
method removeInvisible takes nothing returns nothing
set this.invisibleLevel=this.invisibleLevel-1
if this.invisibleLevel==0 then
call UnitMakeAbilityPermanent(this.unit,false,ABIL_INVISIBLE)
call UnitRemoveAbility(this.unit,ABIL_INVISIBLE)
endif
endmethod
method isInvisible takes nothing returns boolean
return this.invisibleLevel>0
endmethod
// Ghost
private integer ghostLevel
method addGhost takes nothing returns nothing
set this.ghostLevel=this.ghostLevel+1
if this.ghostLevel>0 then
call UnitAddAbility(this.unit,ABIL_GHOST)
call UnitMakeAbilityPermanent(this.unit,true,ABIL_GHOST)
endif
endmethod
method removeGhost takes nothing returns nothing
set this.ghostLevel=this.ghostLevel-1
if this.ghostLevel==0 then
call UnitMakeAbilityPermanent(this.unit,false,ABIL_GHOST)
call UnitRemoveAbility(this.unit,ABIL_GHOST)
endif
endmethod
method isGhost takes nothing returns boolean
return this.ghostLevel>0
endmethod
// Spell Immunity
private integer immunityLevel
method addImmunity takes nothing returns nothing
set this.immunityLevel=this.immunityLevel+1
if this.immunityLevel>0 then
call UnitAddAbility(this.unit,ABIL_IMMUNITY)
call UnitMakeAbilityPermanent(this.unit,true,ABIL_IMMUNITY)
endif
endmethod
method removeImmunity takes nothing returns nothing
set this.immunityLevel=this.immunityLevel-1
if this.immunityLevel==0 then
call UnitMakeAbilityPermanent(this.unit,false,ABIL_IMMUNITY)
call UnitRemoveAbility(this.unit,ABIL_IMMUNITY)
endif
endmethod
method isImmune takes nothing returns boolean
return this.immunityLevel>0
endmethod
// Hex
private integer hexLevel
method addHex takes nothing returns nothing
set this.hexLevel=this.hexLevel+1
if this.hexLevel>0 then
call IssueTargetOrderById(thistype.dummyCaster,OID_HEX,this.unit)
endif
endmethod
method removeHex takes nothing returns nothing
set this.hexLevel=this.hexLevel-1
if this.hexLevel==0 then
call UnitRemoveAbility(this.unit,BUFF_HEX)
endif
endmethod
method isHexed takes nothing returns boolean
return this.hexLevel>0
endmethod
// Never Miss
private integer neverMissLevel
method addNeverMiss takes nothing returns nothing
set this.neverMissLevel=this.neverMissLevel+1
if this.neverMissLevel>0 then
call UnitAddAbility(this.unit,ABIL_NEVER_MISS)
call UnitMakeAbilityPermanent(this.unit,true,ABIL_NEVER_MISS)
endif
endmethod
method removeNeverMiss takes nothing returns nothing
set this.neverMissLevel=this.neverMissLevel-1
if this.neverMissLevel==0 then
call UnitMakeAbilityPermanent(this.unit,false,ABIL_NEVER_MISS)
call UnitRemoveAbility(this.unit,ABIL_NEVER_MISS)
endif
endmethod
method isNeverMiss takes nothing returns boolean
return this.neverMissLevel>0
endmethod
// Always Miss
private integer alwaysMissLevel
method addAlwaysMiss takes nothing returns nothing
set this.alwaysMissLevel=this.alwaysMissLevel+1
if this.alwaysMissLevel>0 then
call UnitAddAbility(this.unit,ABIL_ALWAYS_MISS)
call UnitMakeAbilityPermanent(this.unit,true,ABIL_ALWAYS_MISS)
endif
endmethod
method removeAlwaysMiss takes nothing returns nothing
set this.alwaysMissLevel=this.alwaysMissLevel-1
if this.alwaysMissLevel==0 then
call UnitMakeAbilityPermanent(this.unit,false,ABIL_ALWAYS_MISS)
call UnitRemoveAbility(this.unit,ABIL_ALWAYS_MISS)
endif
endmethod
method isAlwaysMiss takes nothing returns boolean
return this.alwaysMissLevel>0
endmethod
// Untouchable
private integer untouchableLevel
method addUntouchable takes nothing returns nothing
set this.untouchableLevel=this.untouchableLevel+1
if this.untouchableLevel>0 then
call UnitAddAbility(this.unit,ABIL_UNTOUCHABLE)
call UnitMakeAbilityPermanent(this.unit,true,ABIL_UNTOUCHABLE)
endif
endmethod
method removeUntouchable takes nothing returns nothing
set this.untouchableLevel=this.untouchableLevel-1
if this.untouchableLevel==0 then
call UnitMakeAbilityPermanent(this.unit,false,ABIL_UNTOUCHABLE)
call UnitRemoveAbility(this.unit,ABIL_UNTOUCHABLE)
endif
endmethod
method isUntouchable takes nothing returns boolean
return this.untouchableLevel>0
endmethod
// Banish
private integer banishLevel
method addBanish takes nothing returns nothing
set this.banishLevel=this.banishLevel+1
if this.banishLevel>0 then
call IssueTargetOrderById(thistype.dummyCaster,OID_BANISH,this.unit)
endif
endmethod
method removeBanish takes nothing returns nothing
set this.banishLevel=this.banishLevel-1
if this.banishLevel==0 then
call UnitRemoveAbility(this.unit,BUFF_BANISH)
endif
endmethod
method isBanished takes nothing returns boolean
return this.banishLevel>0
endmethod
// Phase
private integer phaseLevel
method addPhase takes nothing returns nothing
set this.phaseLevel=this.phaseLevel+1
if this.phaseLevel>0 then
call SetPlayerAbilityAvailable(GetOwningPlayer(this.unit),ABIL_PHASE,true)
if UnitAddAbility(this.unit,ABIL_PHASE) then
call UnitMakeAbilityPermanent(this.unit,true,ABIL_PHASE)
endif
call IssueImmediateOrderById(this.unit,OID_PHASE)
call SetPlayerAbilityAvailable(GetOwningPlayer(this.unit),ABIL_PHASE,false)
endif
endmethod
method removePhase takes nothing returns nothing
set this.phaseLevel=this.phaseLevel-1
if this.phaseLevel==0 then
call UnitRemoveAbility(this.unit,BUFF_PHASE)
endif
endmethod
method isPhased takes nothing returns boolean
return this.phaseLevel>0
endmethod
// Resistant Skin
private integer resistantSkinLevel
method addResistantSkin takes nothing returns nothing
set this.resistantSkinLevel=this.resistantSkinLevel+1
if this.resistantSkinLevel>0 then
call UnitAddAbility(this.unit,ABIL_RESISTANT_SKIN)
call UnitMakeAbilityPermanent(this.unit,true,ABIL_RESISTANT_SKIN)
endif
endmethod
method removeResistantSkin takes nothing returns nothing
set this.resistantSkinLevel=this.resistantSkinLevel-1
if this.resistantSkinLevel==0 then
call UnitMakeAbilityPermanent(this.unit,false,ABIL_RESISTANT_SKIN)
call UnitRemoveAbility(this.unit,ABIL_RESISTANT_SKIN)
endif
endmethod
method isResistantSkin takes nothing returns boolean
return this.resistantSkinLevel>0
endmethod
// Reflect Piercing
private integer reflectPiercingLevel
method addReflectPiercing takes nothing returns nothing
set this.reflectPiercingLevel=this.reflectPiercingLevel+1
if this.reflectPiercingLevel>0 then
call UnitAddAbility(this.unit,ABIL_REFLECT_PIERCING)
call UnitMakeAbilityPermanent(this.unit,true,ABIL_REFLECT_PIERCING)
endif
endmethod
method removeReflectPiercing takes nothing returns nothing
set this.reflectPiercingLevel=this.reflectPiercingLevel-1
if this.reflectPiercingLevel==0 then
call UnitMakeAbilityPermanent(this.unit,false,ABIL_REFLECT_PIERCING)
call UnitRemoveAbility(this.unit,ABIL_REFLECT_PIERCING)
endif
endmethod
method isReflectPiercing takes nothing returns boolean
return this.reflectPiercingLevel>0
endmethod
endstruct
endlibrary
//TESH.scrollpos=226
//TESH.alwaysfold=0
library ItemBonus initializer Init requires DamageSystem, MoveSpeedX
globals
private unit DUMMY_HERO = null
endglobals
private function Init takes nothing returns nothing
set DUMMY_HERO = gg_unit_H02A_0342
endfunction
struct ItemBonus extends array
integer strength
integer intelligence
integer agility
integer damage
integer armor
integer life
integer mana
real attackSpeed
real movementSpeed
real manaRegeneration
real lifeRegeneration
real manaRegenerationPercent
real lifeRegenerationPercent
real criticalChance
real criticalMultiplier
real spellCriticalChance
real spellCriticalMultiplier
real spellPower
real fireResistance
real coldResistance
real poisonResistance
real lightningResistance
real fireDamage
real coldDamage
real poisonDamage
real lightningDamage
real bashChance
real bashDuration
real evasion
real reflectChance
real reflectPercent
string effectPath
string attachmentPoint
integer AddedAbility
effect dummySFX
effect heroSFX
static method operator [] takes integer itemId returns thistype
return itemId - 'I000'
endmethod
method saveStats takes integer strengthB, integer intelligenceB, integer agilityB, integer damageB, integer armorB, integer lifeB, integer manaB, real attackSpeedB, real movementSpeedB, real manaRegenerationB, real lifeRegenerationB, real lifeRegenerationPercentB, real manaRegenerationPercentB returns nothing
set this.strength = strengthB
set this.intelligence = intelligenceB
set this.agility = agilityB
set this.damage = damageB
set this.armor = armorB
set this.life = lifeB
set this.mana = manaB
set this.attackSpeed = attackSpeedB
set this.movementSpeed = movementSpeedB
set this.manaRegeneration = manaRegenerationB
set this.lifeRegeneration = lifeRegenerationB
set this.manaRegenerationPercent = manaRegenerationPercentB
set this.lifeRegenerationPercent = lifeRegenerationPercentB
endmethod
method saveStatsPet takes integer damageB, integer armorB, integer lifeB, integer manaB, real attackSpeedB, real movementSpeedB, real manaRegenerationB, real lifeRegenerationB, real lifeRegenerationPercentB, real manaRegenerationPercentB returns nothing
set this.damage = damageB
set this.armor = armorB
set this.life = lifeB
set this.mana = manaB
set this.attackSpeed = attackSpeedB
set this.movementSpeed = movementSpeedB
set this.manaRegeneration = manaRegenerationB
set this.lifeRegeneration = lifeRegenerationB
set this.manaRegenerationPercent = manaRegenerationPercentB
set this.lifeRegenerationPercent = lifeRegenerationPercentB
endmethod
method saveDamageStats takes real criticalChanceB, real criticalMultiplierB, real spellCriticalChanceB, real spellCriticalMultiplierB, real spellPowerB, real fireResistanceB, real coldResistanceB, real poisonResistanceB, real lightningResistanceB, real fireDamageB, real coldDamageB, real lightningDamageB, real poisonDamageB, real bashChanceB, real bashDurationB, real evasionB, real reflectChanceB, real reflectPercentB returns nothing
set this.criticalChance = criticalChanceB
set this.criticalMultiplier = criticalMultiplierB
set this.spellCriticalChance = spellCriticalChanceB
set this.spellCriticalMultiplier = spellCriticalMultiplierB
set this.spellPower = spellPowerB
set this.fireResistance = fireResistanceB
set this.coldResistance = coldResistanceB
set this.poisonResistance = poisonResistanceB
set this.lightningResistance = lightningResistanceB
set this.fireDamage = fireDamageB
set this.coldDamage = coldDamageB
set this.poisonDamage = poisonDamageB
set this.lightningDamage = lightningDamageB
set this.bashChance = bashChanceB
set this.bashDuration = bashDurationB
set this.evasion = evasionB
set this.reflectChance = reflectChanceB
set this.reflectPercent = reflectPercentB
endmethod
method saveEffect takes integer a, string effectPathB, string attachmentPointB returns nothing
set this.effectPath = effectPathB
set this.attachmentPoint = attachmentPointB
set this.AddedAbility = a
endmethod
static method load takes integer id returns nothing
local thistype this = id - 'I000'
set Unit(HERO_UD).criticalChance = Unit(HERO_UD).criticalChance + this.criticalChance
set Unit(HERO_UD).criticalMultiplier = Unit(HERO_UD).criticalMultiplier + this.criticalMultiplier
set Unit(HERO_UD).spellCriticalChance = Unit(HERO_UD).spellCriticalChance + this.spellCriticalChance
set Unit(HERO_UD).spellCriticalMultiplier = Unit(HERO_UD).spellCriticalMultiplier + this.spellCriticalMultiplier
set Unit(HERO_UD).spellPower = Unit(HERO_UD).spellPower + this.spellPower
set Unit(HERO_UD).fireResistance = Unit(HERO_UD).fireResistance + this.fireResistance/100
set Unit(HERO_UD).coldResistance = Unit(HERO_UD).coldResistance + this.coldResistance/100
set Unit(HERO_UD).poisonResistance = Unit(HERO_UD).poisonResistance + this.poisonResistance/100
set Unit(HERO_UD).lightningResistance = Unit(HERO_UD).lightningResistance + this.lightningResistance/100
set Unit(HERO_UD).bashChance = Unit(HERO_UD).bashChance + this.bashChance
set Unit(HERO_UD).bashDuration = Unit(HERO_UD).bashDuration + this.bashDuration
set Unit(HERO_UD).evasion = Unit(HERO_UD).evasion + this.evasion
set Unit(HERO_UD).reflectChance = Unit(HERO_UD).reflectChance + this.reflectChance
set Unit(HERO_UD).reflectPercent = Unit(HERO_UD).reflectPercent + this.reflectPercent
set Unit(HERO_UD).fireDamage = Unit(HERO_UD).fireDamage + this.fireDamage
set Unit(HERO_UD).coldDamage = Unit(HERO_UD).coldDamage + this.coldDamage
set Unit(HERO_UD).poisonDamage = Unit(HERO_UD).poisonDamage + this.poisonDamage
set Unit(HERO_UD).lightningDamage = Unit(HERO_UD).lightningDamage + this.lightningDamage
call Bonus(HERO_UD).addBonus(BONUS_TYPE_STR, this.strength)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_AGI, this.agility)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_INT, this.intelligence)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_DAMAGE, this.damage)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_ARMOR, this.armor)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_LIFE, this.life)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_MANA, this.mana)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_ATTACK_SPEED, R2I((100*this.attackSpeed)))
set UnitRegeneration(HERO_UD).life = UnitRegeneration(HERO_UD).life + this.lifeRegeneration
set UnitRegeneration(HERO_UD).mana = UnitRegeneration(HERO_UD).mana + this.manaRegeneration
set UnitRegeneration(HERO_UD).lifePercent = UnitRegeneration(HERO_UD).lifePercent + this.lifeRegenerationPercent
set UnitRegeneration(HERO_UD).manaPercent = UnitRegeneration(HERO_UD).manaPercent + this.manaRegenerationPercent
call SetUnitMoveSpeedX(HERO, GetUnitMoveSpeedX(HERO) + this.movementSpeed)
if this.effectPath != "" and this.attachmentPoint != "" then
set this.heroSFX = AddSpecialEffectTarget(this.effectPath, HERO, this.attachmentPoint)
set this.dummySFX = AddSpecialEffectTarget(this.effectPath, DUMMY_HERO, this.attachmentPoint)
endif
call UnitAddAbility(HERO, this.AddedAbility)
call UnitMakeAbilityPermanent(HERO, true, this.AddedAbility)
endmethod
static method loadPet takes integer id returns nothing
local thistype this = id - 'I000'
set Unit(PET_UD).criticalChance = Unit(PET_UD).criticalChance + this.criticalChance
set Unit(PET_UD).criticalMultiplier = Unit(PET_UD).criticalMultiplier + this.criticalMultiplier
set Unit(PET_UD).spellCriticalChance = Unit(PET_UD).spellCriticalChance + this.spellCriticalChance
set Unit(PET_UD).spellCriticalMultiplier = Unit(PET_UD).spellCriticalMultiplier + this.spellCriticalMultiplier
set Unit(PET_UD).spellPower = Unit(PET_UD).spellPower + this.spellPower
set Unit(PET_UD).fireResistance = Unit(PET_UD).fireResistance + this.fireResistance/100
set Unit(PET_UD).coldResistance = Unit(PET_UD).coldResistance + this.coldResistance/100
set Unit(PET_UD).poisonResistance = Unit(PET_UD).poisonResistance + this.poisonResistance/100
set Unit(PET_UD).lightningResistance = Unit(PET_UD).lightningResistance + this.lightningResistance/100
set Unit(PET_UD).bashChance = Unit(PET_UD).bashChance + this.bashChance
set Unit(PET_UD).bashDuration = Unit(PET_UD).bashDuration + this.bashDuration
set Unit(PET_UD).evasion = Unit(PET_UD).evasion + this.evasion
set Unit(PET_UD).reflectChance = Unit(PET_UD).reflectChance + this.reflectChance
set Unit(PET_UD).reflectPercent = Unit(PET_UD).reflectPercent + this.reflectPercent
set Unit(PET_UD).fireDamage = Unit(PET_UD).fireDamage + this.fireDamage
set Unit(PET_UD).coldDamage = Unit(PET_UD).coldDamage + this.coldDamage
set Unit(PET_UD).poisonDamage = Unit(PET_UD).poisonDamage + this.poisonDamage
set Unit(PET_UD).lightningDamage = Unit(PET_UD).lightningDamage + this.lightningDamage
call Bonus(PET_UD).addBonus(BONUS_TYPE_DAMAGE, this.damage)
call Bonus(PET_UD).addBonus(BONUS_TYPE_ARMOR, this.armor)
call Bonus(PET_UD).addBonus(BONUS_TYPE_LIFE, this.life)
call Bonus(PET_UD).addBonus(BONUS_TYPE_MANA, this.mana)
call Bonus(PET_UD).addBonus(BONUS_TYPE_ATTACK_SPEED, R2I((100*this.attackSpeed)))
set UnitRegeneration(PET_UD).life = UnitRegeneration(PET_UD).life + this.lifeRegeneration
set UnitRegeneration(PET_UD).mana = UnitRegeneration(PET_UD).mana + this.manaRegeneration
set UnitRegeneration(PET_UD).lifePercent = UnitRegeneration(PET_UD).lifePercent + this.lifeRegenerationPercent
set UnitRegeneration(PET_UD).manaPercent = UnitRegeneration(PET_UD).manaPercent + this.manaRegenerationPercent
call SetUnitMoveSpeedX(PET, GetUnitMoveSpeedX(PET) + this.movementSpeed)
endmethod
static method remove takes integer id returns nothing
local thistype this = id - 'I000'
set Unit(HERO_UD).criticalChance = Unit(HERO_UD).criticalChance - this.criticalChance
set Unit(HERO_UD).criticalMultiplier = Unit(HERO_UD).criticalMultiplier - this.criticalMultiplier
set Unit(HERO_UD).spellCriticalChance = Unit(HERO_UD).spellCriticalChance - this.spellCriticalChance
set Unit(HERO_UD).spellCriticalMultiplier = Unit(HERO_UD).spellCriticalMultiplier - this.spellCriticalMultiplier
set Unit(HERO_UD).spellPower = Unit(HERO_UD).spellPower - this.spellPower
set Unit(HERO_UD).fireResistance = Unit(HERO_UD).fireResistance - this.fireResistance
set Unit(HERO_UD).coldResistance = Unit(HERO_UD).coldResistance - this.coldResistance
set Unit(HERO_UD).poisonResistance = Unit(HERO_UD).poisonResistance - this.poisonResistance
set Unit(HERO_UD).lightningResistance = Unit(HERO_UD).lightningResistance - this.lightningResistance
set Unit(HERO_UD).bashChance = Unit(HERO_UD).bashChance - this.bashChance
set Unit(HERO_UD).bashDuration = Unit(HERO_UD).bashDuration - this.bashDuration
set Unit(HERO_UD).evasion = Unit(HERO_UD).evasion - this.evasion
set Unit(HERO_UD).reflectChance = Unit(HERO_UD).reflectChance - this.reflectChance
set Unit(HERO_UD).reflectPercent = Unit(HERO_UD).reflectPercent - this.reflectPercent
set Unit(HERO_UD).fireDamage = Unit(HERO_UD).fireDamage - this.fireDamage
set Unit(HERO_UD).coldDamage = Unit(HERO_UD).coldDamage - this.coldDamage
set Unit(HERO_UD).poisonDamage = Unit(HERO_UD).poisonDamage - this.poisonDamage
set Unit(HERO_UD).lightningDamage = Unit(HERO_UD).lightningDamage - this.lightningDamage
call Bonus(HERO_UD).addBonus(BONUS_TYPE_STR, -this.strength)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_AGI, -this.agility)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_INT, -this.intelligence)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_DAMAGE, -this.damage)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_ARMOR, -this.armor)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_LIFE, -this.life)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_MANA, -this.mana)
call Bonus(HERO_UD).addBonus(BONUS_TYPE_ATTACK_SPEED, -R2I((100*this.attackSpeed)))
set UnitRegeneration(HERO_UD).life = UnitRegeneration(HERO_UD).life - this.lifeRegeneration
set UnitRegeneration(HERO_UD).mana = UnitRegeneration(HERO_UD).mana - this.manaRegeneration
set UnitRegeneration(HERO_UD).lifePercent = UnitRegeneration(HERO_UD).lifePercent - this.lifeRegenerationPercent
set UnitRegeneration(HERO_UD).manaPercent = UnitRegeneration(HERO_UD).manaPercent - this.manaRegenerationPercent
call SetUnitMoveSpeedX(HERO, GetUnitMoveSpeedX(HERO) - this.movementSpeed)
if this.heroSFX != null then
call DestroyEffect(this.heroSFX)
call DestroyEffect(this.dummySFX)
endif
call UnitRemoveAbility(HERO, this.AddedAbility)
endmethod
static method removePet takes integer id returns nothing
local thistype this = id - 'I000'
set Unit(PET_UD).criticalChance = Unit(PET_UD).criticalChance - this.criticalChance
set Unit(PET_UD).criticalMultiplier = Unit(PET_UD).criticalMultiplier - this.criticalMultiplier
set Unit(PET_UD).spellCriticalChance = Unit(PET_UD).spellCriticalChance - this.spellCriticalChance
set Unit(PET_UD).spellCriticalMultiplier = Unit(PET_UD).spellCriticalMultiplier - this.spellCriticalMultiplier
set Unit(PET_UD).spellPower = Unit(PET_UD).spellPower - this.spellPower
set Unit(PET_UD).fireResistance = Unit(PET_UD).fireResistance - this.fireResistance
set Unit(PET_UD).coldResistance = Unit(PET_UD).coldResistance - this.coldResistance
set Unit(PET_UD).poisonResistance = Unit(PET_UD).poisonResistance - this.poisonResistance
set Unit(PET_UD).lightningResistance = Unit(PET_UD).lightningResistance - this.lightningResistance
set Unit(PET_UD).bashChance = Unit(PET_UD).bashChance - this.bashChance
set Unit(PET_UD).bashDuration = Unit(PET_UD).bashDuration - this.bashDuration
set Unit(PET_UD).evasion = Unit(PET_UD).evasion - this.evasion
set Unit(PET_UD).reflectChance = Unit(PET_UD).reflectChance - this.reflectChance
set Unit(PET_UD).reflectPercent = Unit(PET_UD).reflectPercent - this.reflectPercent
set Unit(PET_UD).fireDamage = Unit(PET_UD).fireDamage - this.fireDamage
set Unit(PET_UD).coldDamage = Unit(PET_UD).coldDamage - this.coldDamage
set Unit(PET_UD).poisonDamage = Unit(PET_UD).poisonDamage - this.poisonDamage
set Unit(PET_UD).lightningDamage = Unit(PET_UD).lightningDamage - this.lightningDamage
call Bonus(PET_UD).addBonus(BONUS_TYPE_DAMAGE, -this.damage)
call Bonus(PET_UD).addBonus(BONUS_TYPE_ARMOR, -this.armor)
call Bonus(PET_UD).addBonus(BONUS_TYPE_LIFE, -this.life)
call Bonus(PET_UD).addBonus(BONUS_TYPE_MANA, -this.mana)
call Bonus(PET_UD).addBonus(BONUS_TYPE_ATTACK_SPEED, -R2I((100*this.attackSpeed)))
set UnitRegeneration(PET_UD).life = UnitRegeneration(PET_UD).life - this.lifeRegeneration
set UnitRegeneration(PET_UD).mana = UnitRegeneration(PET_UD).mana - this.manaRegeneration
set UnitRegeneration(PET_UD).lifePercent = UnitRegeneration(PET_UD).lifePercent - this.lifeRegenerationPercent
set UnitRegeneration(PET_UD).manaPercent = UnitRegeneration(PET_UD).manaPercent - this.manaRegenerationPercent
call SetUnitMoveSpeedX(PET, GetUnitMoveSpeedX(PET) - this.movementSpeed)
endmethod
endstruct
endlibrary
//TESH.scrollpos=23
//TESH.alwaysfold=0
/************************************
*
* SaveLoad
* v1.0.0.0
* By Magtheridon96
*
* - Saves and Loads data from a Gamecache
*
* API:
* ----
*
* struct SaveLoad extends array
*
* static method operator [] takes string s returns integer
* - Load an integer using a string as an index
*
* static method operator []= takes string s, integer i returns nothing
* - Save an integer using a string as an index
*
************************************/
library SaveLoad
globals
private constant string GAMECACHE_NAME = "SotP.w3v"
private constant string NAME_KEY = "~<!0KOBAS_IS_AWESOME0!>~"
private constant string HEADER = "V_C098345360968575"
private constant string SECURITY = "+901(8D}V<B987*(&*69"
endglobals
private module Init
private static gamecache cache = null
private static method onInit takes nothing returns nothing
set cache = InitGameCache(GAMECACHE_NAME)
if GetStoredString(cache, "0", "0") != HEADER or GetStoredString(cache, NAME_KEY, I2S(StringHash(NAME_KEY))) != GetPlayerName(Player(0)) then
call FlushGameCache(cache)
set cache = InitGameCache(GAMECACHE_NAME)
call StoreString(cache, "0", "0", HEADER)
call StoreString(cache, NAME_KEY, I2S(StringHash(NAME_KEY)), GetPlayerName(Player(0)))
endif
endmethod
static method operator [] takes string s returns integer
return GetStoredInteger(cache, s, SECURITY)
endmethod
static method operator []= takes string s, integer i returns nothing
call StoreInteger(cache, s, SECURITY, i)
endmethod
endmodule
struct SaveLoad extends array
implement Init
endstruct
/*
- Save:
set SaveLoad["strength"] = GetHeroStr(HERO)
set SaveLoad["myGayInteger"] = vengeancekael
- Load:
call SetHeroStr(HERO, SaveLoad["strength"])
set vengeancekael = SaveLoad["myGayInteger"]
*/
endlibrary
//TESH.scrollpos=27
//TESH.alwaysfold=0
/******************************************************************************
*
* TIMED LIGHTNINGS by Maker v1.0.1.1
*
* Allows the creation of lightnings with expiration timer.
* Supports:
* o Fading lightnings in and out
* o Attaching to units
* o Attaching to points
* o Linear movement in x-, y- and z-axes
*
*
* Methods
*
* P2U
* From a static point attached to a unit
* static method P2U takes lightning l, unit t, real time, real x1, real y1, real z1, real z2, real startAlpha, real endAlpha returns nothing
*
* The lightning, target unit, duration, origin x, origin y, origin z, end z
*
*
* P2UEx
* From a moving point attached to a unit
* static method P2UEx takes lightning l, unit a, real t, real zu, real x1, real y1, real z1, real x2, real y2, real z2, real startAlpha, real endAlpha returns nothing
*
* The lightning, target unit, duration, target z, origin start x, origin start y, origin start z, origin end x, origin end y, origin end z
*
* U2P
* From attached to a unit to a static point
* static method U2P takes lightning l, unit s, real t, real x1, real y1, real x2, real y2, real z1, real z2, real startAlpha, real endAlpha returns nothing
*
* The lightning, source unit, duration, origin x, origin y, point x , point y, source z, point z
*
* U2PEx
* From attached to a unit to a moving point
* static method U2PEx takes lightning l, unit a, real t, real zu, real x1, real y1, real z1, real x2, real y2, real z2, real startAlpha, real endAlpha returns nothing
*
* The lightning, source unit, duration, source z, point start x, point start y, point start z, point end x, point end y, point end z
*
* U2U
* From attached to a unit to attached to a unit
* static method U2U takes lightning l, unit s, unit t, real time, real z1, real z2, real startAlpha, real endAlpha returns nothing
*
* The lightning, source unit, target unit, duration, source z, target z
*
* P2P
* From a static point to a static point
* static method P2P takes lightning l, real t, real startAlpha, real endAlpha returns nothing
*
* The lightning, duration
*
* P2PEx
* From a moving point to a moving point
* static method P2PEx takes lightning l, real t, real x1, real y1, real z1, real x2, real y2, real z2, real x3, real y3, real z3, real x4, real y4, real z4, real startAlpha, real endAlpha returns nothing
*
* The lightning, duration, origin start x, origin start y, origin start z, origin end x, origin end y, origin end z, target start x, target start y, target start z, target end x, target end y, target end z
*
*
* Alpha values are between 1 and 0. 1 is fully visible, 0 is transparent.
*
*******************************************************************************/
library TimedLightnings
globals
private constant real TO = 0.03125000 // Update interval
private integer CT = 0 // Lightning count
private timer TMR = CreateTimer()
private location loc = Location(0,0)
endglobals
struct TimedL extends array
lightning l
real av // aplha value
real da // transparency change rate
real x1
real x2
real y1
real y2
real z1
real z2
real dx1
real dy1
real dz1
real dx2
real dy2
real dz2
unit s // source
unit t // target
integer time // how many ticks, time
integer next // next node
integer prev // previous node
boolean moves
private static integer rlast = 0 // previous created
private static thistype first // first node
private static integer ic = 0
private static integer ir = 0
private thistype rn
private static thistype dat
private static thistype dat2
private static thistype dat3
private static method destroyL takes nothing returns nothing
/*-Link previous node with next one-*/
set dat3 = dat2.prev
set dat3.next = dat2.next
/*-----Set new last created node----*/
if dat2 == rlast then
set rlast = dat3
endif
/*-Link next node with previous one-*/
set dat3 = dat2.next
set dat3.prev = dat2.prev
/*--------Set new first node--------*/
if dat2 == first then
set first = dat3
endif
call DestroyLightning(dat2.l)
set CT = CT - 1
if CT == 0 then
call PauseTimer(TMR)
endif
set dat2.rn=ir
set ir=dat2
endmethod
private static method looping takes nothing returns nothing
local real z1
local real z2
set dat = first
loop
set z1 = 0
set z2 = 0
set dat.time = dat.time - 1
if dat.da != 0 then
set dat.av = dat.av - dat.da
call SetLightningColor(dat.l, 1, 1, 1, dat.av)
endif
if dat.s == null then
if dat.dx1 != 0 then
set dat.x1 = dat.x1 + dat.dx1
endif
if dat.dy1 != 0 then
set dat.y1 = dat.y1 + dat.dy1
endif
if dat.dz1 != 0 then
set dat.z1 = dat.z1 + dat.dz1
endif
else
set dat.x1 = GetUnitX(dat.s)
set dat.y1 = GetUnitY(dat.s)
set z1 = GetUnitFlyHeight(dat.s)
endif
if dat.t == null then
if dat.dx2 != 0 then
set dat.x2 = dat.x2 + dat.dx2
endif
if dat.dy2 != 0 then
set dat.y2 = dat.y2 + dat.dy2
endif
if dat.dz2 != 0 then
set dat.z2 = dat.z2 + dat.dz2
endif
else
set dat.x2 = GetUnitX(dat.t)
set dat.y2 = GetUnitY(dat.t)
set z2 = GetUnitFlyHeight(dat.t)
endif
if dat.moves then
call MoveLocation(loc, dat.x1, dat.y1)
set z1 = GetLocationZ(loc) + dat.z1 + z1
call MoveLocation(loc, dat.x2, dat.y2)
set z2 = GetLocationZ(loc) + dat.z2 + z2
call MoveLightningEx(dat.l, true, dat.x1, dat.y1, z1, dat.x2, dat.y2, z2)
endif
if dat.time == 0 then
set dat2 = dat
set dat = dat.next
call destroyL()
else
set dat = dat.next
endif
exitwhen dat == 0
endloop
endmethod
private static method InitAdd takes nothing returns nothing
/* Add node to list, make this the last on list */
if rlast != 0 then
set dat2 = rlast
set dat2.next = dat
endif
/* Link this with previous node */
set dat.prev = rlast
/* Make this the last created node */
set rlast = dat
set CT = CT + 1
if CT == 1 then
/* Make this the first node */
set first = dat
call TimerStart(TMR, TO, true, function thistype.looping)
endif
endmethod
private static method Recycle takes nothing returns nothing
if 0==ir then
set ic=ic+1
set dat=ic
else
set dat=ir
set ir=dat.rn
endif
endmethod
static method P2U takes lightning l, unit t, real time, real x1, real y1, real z1, real z2, real startAlpha, real endAlpha returns nothing
local thistype this
call Recycle()
set this = dat
set .x1 = x1
set .y1 = y1
set .z1 = z1
set .z2 = z2
set .s = null
set .t = t
set .next = 0 // Nodes are added to the end of the list, there is no next node
set .l = l
set .time = R2I(time/TO) // Calculates how many loops does the lightning lasts
set .av = startAlpha
set .da = (startAlpha-endAlpha)*TO/time // Transparency change speed
set .moves = true
call InitAdd()
endmethod
static method U2P takes lightning l, unit s, real t, real x1, real y1, real x2, real y2, real z1, real z2, real startAlpha, real endAlpha returns nothing
local thistype this
call Recycle()
set this = dat
set .x1 = x1
set .y1 = y1
set .x2 = x2
set .y2 = y2
set .z1 = z1
set .z2 = z2
set .s = s
set .t = null
set .next = 0
set .l = l
set .time = R2I(t/TO)
set .av = startAlpha
set .da = (startAlpha-endAlpha)*TO/t
set .moves = true
call InitAdd()
endmethod
static method U2U takes lightning l, unit s, unit t, real time, real z1, real z2, real startAlpha, real endAlpha returns nothing
local thistype this
call Recycle()
set this = dat
set .z1 = z1
set .z2 = z2
set .s = s
set .t = t
set .next = 0
set .l = l
set .time = R2I(time/TO)
set .av = startAlpha
set .da = (startAlpha-endAlpha)*TO/time
set .moves = true
call InitAdd()
endmethod
static method P2P takes lightning l, real t, real startAlpha, real endAlpha returns nothing
local thistype this
call Recycle()
set this = dat
set .s = null
set .t = null
set .next = 0
set .l = l
set .time = R2I(t/TO)
set .av = startAlpha
set .da = (startAlpha-endAlpha)*TO/t
set .moves = false
call InitAdd()
endmethod
static method P2UEx takes lightning l, unit a, real t, real zu, real x1, real y1, real z1, real x2, real y2, real z2, real startAlpha, real endAlpha returns nothing
local thistype this
local real n = TO/t
call Recycle()
set this = dat
set .x1 = x1
set dx1 = (x2-x1)*n
set .y1 = y1
set dy1 = (y2-y1)*n
set .z1 = z1
set dz1 = (z2-z1)*n
set .z2 = zu
set .s = null
set .t = a
set .next = 0
set .l = l
set .time = R2I(t/TO)
set .av = startAlpha
set .da = (startAlpha-endAlpha)*n
set .moves = true
call InitAdd()
endmethod
static method U2PEx takes lightning l, unit a, real t, real zu, real x1, real y1, real z1, real x2, real y2, real z2, real startAlpha, real endAlpha returns nothing
local thistype this
local real n = TO/t
call Recycle()
set this = dat
set .x2 = x1
set .dx2 = (x2-x1)*n
set .y2 = y1
set .dy2 = (y2-y1)*n
set .z2 = z1
set .dz2 = (z2-z1)*n
set .z1 = zu
set .s = a
set .t = null
set .next = 0
set .l = l
set .time = R2I(t/TO)
set .av = startAlpha
set .da = (startAlpha-endAlpha)*n
set .moves = true
call thistype.InitAdd()
endmethod
static method P2PEx takes lightning l, real t, real x1, real y1, real z1, real x2, real y2, real z2, real x3, real y3, real z3, real x4, real y4, real z4, real startAlpha, real endAlpha returns nothing
local thistype this
local real n = TO/t
call Recycle()
set this = dat
set .x1 = x1
set .x2 = x3
set .y1 = y1
set .y2 = y3
set .z1 = z1
set .z2 = z3
set .dx1 = (x2-x1)*n
set .dy1 = (y2-y1)*n
set .dz1 = (z2-z1)*n
set .dx2 = (x4-x3)*n
set .dy2 = (y4-y3)*n
set .dz2 = (z4-z3)*n
set .s = null
set .t = null
set .next = 0
set .l = l
set .time = R2I(t/TO)
set .av = startAlpha
set .da = (startAlpha-endAlpha)*n
set .moves = true
call InitAdd()
endmethod
endstruct
endlibrary
//TESH.scrollpos=9
//TESH.alwaysfold=0
library DisplaySpellName uses AdvancedTextTag
function DisplayUnitSpellName takes nothing returns nothing
local integer id = GetSpellAbilityId()
if IsUnitType(GetTriggerUnit(), UNIT_TYPE_ANCIENT) then
//We ignore ancient units that are related to map dummy units
return
endif
if id == 'A008' then
//We ignore Eat Food
return
elseif id == 'A100' then
//We ignore Load Item
return
elseif id == 'A017' then
//We ignore Read Book
return
elseif id == 'A03A' then
//We ignore Teleport
return
elseif id == 'A02E' then
//We ignore Interact
return
elseif id == 'A00C' then
//We ignore Rest
return
elseif id == 'A016' then
//WE ignore SpiritualBondSpell
//Instead we fire it manually
return
endif
if GetOwningPlayer(GetTriggerUnit()) == Player(0) then
// Lime Green
call CreateAdvancedTextTag(TT_SPELL, "|c0000FF00" + GetObjectName(id), GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()))
else
// Red
call CreateAdvancedTextTag(TT_SPELL, "|c00FF0303" + GetObjectName(id), GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()))
endif
endfunction
function SetupDisplaySpellNameSystem takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterUnitEvent(trig, HERO, EVENT_UNIT_SPELL_EFFECT)
call TriggerRegisterUnitEvent(trig, PET , EVENT_UNIT_SPELL_EFFECT)
call TriggerRegisterPlayerUnitEvent(trig, Player(8), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(trig, Player(9), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(trig, Player(10), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(trig, Player(11), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(trig, function DisplayUnitSpellName)
set trig = CreateTrigger()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct HeroAvatarHotkeys extends array
static trigger T = CreateTrigger()
private static method camera takes nothing returns nothing
if IS_IN_CI then
call CameraSetupApplyForceDuration(gg_cam___HeroCustomInventory, true, 0 )
else
call DestroyLeaderboard(bj_lastCreatedLeaderboard)
endif
endmethod
private static method run takes nothing returns nothing
local integer id = GetUnitTypeId(GetTriggerUnit())
if id == 'H01R' then //Custom Interface
call SelectUnit(GetTriggerUnit(), false)
call ExpandMinimap(true)
if IS_IN_BUILDING then
call PauseTimer(BUILDING_CAMERA_TIMER)
endif
set IS_IN_CI = true
endif
endmethod
static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t, Player(0), EVENT_PLAYER_UNIT_SELECTED , null)
call TriggerAddAction( t, function thistype.run )
call TriggerRegisterTimerEvent(T, 0.03, true)
call TriggerAddAction( T, function thistype.camera )
set t = null
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
library WeatherSystem
globals
private weathereffect RAIN
private weathereffect FOG
private weathereffect bj_lastStartedWeather
endglobals
private function CheckDayTime takes nothing returns nothing
local real time = GetFloatGameState(GAME_STATE_TIME_OF_DAY)
if time > 6.00 and time <= 18.00 then
set IS_DAY = true
//Day time high Zmax remove fog
call SetTerrainFogEx(0, 0.00, 50000.00, 0, 0, 0, 0)
else
set IS_DAY = false
if IS_IN_BUILDING or IS_IN_CI /* or IS_CINEMA_ON */then
//Night time but we are not outside or we don't need fog
call SetTerrainFogEx(0, 0.00, 50000.00, 0, 0, 0, 0)
else
//Night time, Zmax is low, dark fog is there
call SetTerrainFogEx(0, 0.00, 5000.00, 0, 0, 0, 0)
endif
endif
endfunction
function EnableRain takes nothing returns nothing
call EnableWeatherEffect( FOG , false )
call EnableWeatherEffect( RAIN , true )
//call FireWeatherSwap(0,64,192)
set bj_lastStartedWeather = RAIN
endfunction
function EnableFog takes nothing returns nothing
call EnableWeatherEffect( FOG , true )
call EnableWeatherEffect( RAIN , false )
//call FireWeatherSwap(192,192,192)
set bj_lastStartedWeather = FOG
endfunction
function EnableNormal takes nothing returns nothing
call EnableWeatherEffect( FOG , false )
call EnableWeatherEffect( RAIN , false )
//call FireWeatherSwap(0,0,0)
set bj_lastStartedWeather = null
endfunction
function WeatherChange takes nothing returns nothing
local real r = GetRandomReal(0,1)
if r<0.1 then
call EnableFog()
elseif r>=0.1 and r<0.3 then
call EnableRain()
else
call EnableNormal()
endif
endfunction
private function GenerateWeatherMap takes nothing returns rect
return Rect(GetCameraBoundMinX(), 3500, GetCameraBoundMaxX(), GetCameraBoundMaxY())
endfunction
function SetupWeatherSystem takes nothing returns nothing
set RAIN = AddWeatherEffect(GenerateWeatherMap(), 'RLhr')
set FOG = AddWeatherEffect(GenerateWeatherMap(), 'FDwl')
call EnableWeatherEffect( RAIN, false )
call EnableWeatherEffect( FOG , false )
call TimerStart(CreateTimer(), 120.00, true, function WeatherChange)
call TimerStart(CreateTimer(), 1.00, true, function CheckDayTime)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CameraSystem
globals
private boolean enabled = false
private boolean rotateRight = false
private boolean rotateLeft = false
private boolean zoomIn = false
private boolean zoomOut = false
private real rotation = 90.00
private real zoom = 1650.00
endglobals
function ExpandMinimap takes boolean flag returns nothing
if flag then
call SetCameraBounds(-22016.00, -6144.00, -22016.00, 30720.00, 14848.00, 30720.00, 14848.00, -6144.00)
else
call SetCameraBounds(-22016.00, 1128.00, -22016.00, 30720.00, 14848.00, 30720.00, 14848.00, 1128.00)
endif
call ResetToGameCamera(0.00)
call SetCameraPosition(GetUnitX(HERO), GetUnitY(HERO))
set enabled = false
endfunction
private function SwitchEsc takes nothing returns boolean
if IS_CINEMA_ON or IS_IN_BUILDING or IS_IN_CI then
return false
endif
if enabled then
set enabled = false
call ClearTextMessages()
call DisplayTimedTextToPlayer(Player(0), 0, 0, 3,"|cffccccffCamera Setup Disabled|r")
else
set enabled = true
call ClearTextMessages()
call DisplayTimedTextToPlayer(Player(0), 0, 0, 3,"|cffccccffCamera Setup Enabled:|r")
call DisplayTimedTextToPlayer(Player(0), 0, 0, 3,"|cffccccffKey UP:|r Zoom In")
call DisplayTimedTextToPlayer(Player(0), 0, 0, 3,"|cffccccffKey DOWN:|r Zoom Out")
call DisplayTimedTextToPlayer(Player(0), 0, 0, 3,"|cffccccffKey LEFT:|r Rotate Left")
call DisplayTimedTextToPlayer(Player(0), 0, 0, 3,"|cffccccffKey RIGHT:|r Rotate Right")
endif
return false
endfunction
private function PressRight takes nothing returns nothing
if enabled then
set rotateRight = true
set rotateLeft = false
endif
endfunction
private function PressLeft takes nothing returns nothing
if enabled then
set rotateRight = false
set rotateLeft = true
endif
endfunction
private function ReleaseRight takes nothing returns nothing
if enabled then
set rotateRight = false
endif
endfunction
private function ReleaseLeft takes nothing returns nothing
if enabled then
set rotateLeft = false
endif
endfunction
private function PressUp takes nothing returns nothing
if enabled then
set zoomIn = true
set zoomOut = false
endif
endfunction
private function PressDown takes nothing returns nothing
if enabled then
set zoomIn = false
set zoomOut = true
endif
endfunction
private function ReleaseUp takes nothing returns nothing
if enabled then
set zoomIn = false
endif
endfunction
private function ReleaseDown takes nothing returns nothing
if enabled then
set zoomOut = false
endif
endfunction
private function SetCamera takes nothing returns nothing
if enabled and not IS_IN_BUILDING and not IS_IN_CI and GetWidgetLife(HERO) > 0.405 then
if rotateRight then
set rotation = rotation + 3.5
if rotation > 360. then
set rotation = 0.
endif
elseif rotateLeft then
set rotation = rotation - 3.5
if rotation < 0. then
set rotation = 360.
endif
elseif zoomIn then
set zoom = zoom - 50
if zoom < 300. then
set zoom = 300.
endif
elseif zoomOut then
set zoom = zoom + 50
if zoom > 2500. then
set zoom = 2500.
endif
endif
call SetCameraField(CAMERA_FIELD_ROTATION, rotation, 0.50)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, zoom, 0.50)
call SetCameraPosition(GetUnitX(HERO), GetUnitY(HERO))
endif
endfunction
function SetupCameraSystem takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_ARROW_RIGHT_DOWN)
call TriggerAddAction(trig, function PressRight)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_ARROW_LEFT_DOWN)
call TriggerAddAction(trig, function PressLeft)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_ARROW_RIGHT_UP)
call TriggerAddAction(trig, function ReleaseRight)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_ARROW_LEFT_UP)
call TriggerAddAction(trig, function ReleaseLeft)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_ARROW_UP_DOWN)
call TriggerAddAction(trig, function PressUp)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_ARROW_DOWN_DOWN)
call TriggerAddAction(trig, function PressDown)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_ARROW_UP_UP)
call TriggerAddAction(trig, function ReleaseUp)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_ARROW_DOWN_UP)
call TriggerAddAction(trig, function ReleaseDown)
set trig = CreateTrigger()
call TriggerRegisterPlayerEvent(trig, Player(0), EVENT_PLAYER_END_CINEMATIC)
call TriggerAddAction(trig, function SwitchEsc)
set trig = null
call TimerStart(CreateTimer(), 0.031250000, true, function SetCamera)
endfunction
endlibrary
//TESH.scrollpos=-1
//TESH.alwaysfold=0
library CustomMissileSystem requires DamageSystem
globals
private hashtable HASH = InitHashtable()
private constant real bj_2PI = 2 * bj_PI
private integer COUNTER = 0
private group G = CreateGroup()
private timer T = CreateTimer()
private boolean B = false
endglobals
function fixAngle takes real a returns real
loop
exitwhen a < bj_2PI and a >= 0.
if a < 0 then
set a = a + bj_2PI
elseif a > bj_2PI then
set a = a - bj_2PI
endif
endloop
return a
endfunction
function UA2R takes unit u1, unit u2 returns real
return fixAngle(Atan2(GetUnitY(u2) - GetUnitY(u1), GetUnitX(u2) - GetUnitX(u1)))
endfunction
function LA2R takes location l1, location l2 returns real
return fixAngle(Atan2(GetLocationY(l2) - GetLocationY(l1), GetLocationX(l2) - GetLocationX(l1)))
endfunction
function A2R takes real x1, real x2, real y1, real y2 returns real
return fixAngle(Atan2(y2 - y1, x2 - x1))
endfunction
function DoLoop takes nothing returns nothing
local unit u = GetEnumUnit()
local integer id = GetHandleId(u)
local unit caster = LoadUnitHandle(HASH, id, 0)
local real damage = LoadReal( HASH, id, 1)
local real speed = LoadReal( HASH, id, 2)
local real angle = LoadReal( HASH, id, 3)
local real radius = LoadReal( HASH, id, 4)
local real dist = LoadReal( HASH, id, 5)
local boolean onlyOne = LoadBoolean( HASH, id, 6)
local integer dmgType = LoadInteger( HASH, id, 8)
local real max_d = LoadReal( HASH, id, 9)
local real x
local real y
local unit temp_unit = null
local group temp_group = CreateGroup()
if GetWidgetLife(u) > 0.405 and dist < max_d then
set x = GetUnitX(u) + speed * Cos(angle)
set y = GetUnitY(u) + speed * Sin(angle)
call SetUnitX(u, x)
call SetUnitY(u, y)
set B = false
call GroupEnumUnitsInRange(temp_group, x, y, radius, null)
loop
set temp_unit = FirstOfGroup(temp_group)
exitwhen temp_unit == null
if onlyOne then
if GetWidgetLife(temp_unit) > 0.405 and IsUnitEnemy(temp_unit, GetOwningPlayer(caster)) and not B then
set B = true
call Unit[caster].damageTarget(temp_unit, damage, dmgType)
endif
else
if GetWidgetLife(temp_unit) > 0.405 and IsUnitEnemy(temp_unit, GetOwningPlayer(caster)) then
call Unit[caster].damageTarget(temp_unit, damage, dmgType)
endif
endif
call GroupRemoveUnit(temp_group, temp_unit)
endloop
if B then
call SaveReal(HASH, id, 5, 100000)
else
call SaveReal(HASH, id, 5, dist + speed)
endif
else
call DestroyEffect(LoadEffectHandle(HASH, id, 7))
call UnitApplyTimedLife(u, 0, 2)
call GroupRemoveUnit(G, u)
set COUNTER = COUNTER - 1
if COUNTER == 0 then
call PauseTimer(T)
endif
call FlushChildHashtable(HASH, id)
endif
call DestroyGroup(temp_group)
set temp_group = null
set u = null
endfunction
function IssueMove takes nothing returns nothing
call ForGroup(G, function DoLoop)
endfunction
function FireMissile takes unit caster, real damage, damagetype dmgType, real heigh, real speed, real angle, real radius, string sfx, boolean onlyOne, real max_d returns nothing
local unit u = CreateUnit(Player(15), DUMMY_ID, GetUnitX(caster), GetUnitY(caster), bj_RADTODEG*angle)
local integer id = GetHandleId(u)
set speed = speed/40
call UnitAddAbility(u, 'Arav')
call SetUnitFlyHeight(u, heigh, 0)
call SaveUnitHandle( HASH, id, 0, caster )
call SaveReal( HASH, id, 1, damage )
call SaveReal( HASH, id, 2, speed )
call SaveReal( HASH, id, 3, angle )
call SaveReal( HASH, id, 4, radius )
call SaveReal( HASH, id, 5, 0/*dist*/)
call SaveBoolean( HASH, id, 6, onlyOne )
call SaveEffectHandle( HASH, id, 7, AddSpecialEffectTarget(sfx, u, "origin"))
if dmgType == DAMAGE_TYPE_FIRE then
call SaveInteger( HASH, id, 8, 2)
elseif dmgType == DAMAGE_TYPE_COLD then
call SaveInteger( HASH, id, 8, 3)
elseif dmgType == DAMAGE_TYPE_POISON then
call SaveInteger( HASH, id, 8, 4)
elseif dmgType == DAMAGE_TYPE_LIGHTNING then
call SaveInteger( HASH, id, 8, 5)
else
call SaveInteger( HASH, id, 8, 1)
endif
call SaveReal( HASH, id, 9, max_d )
call GroupAddUnit(G, u)
set COUNTER = COUNTER + 1
if COUNTER == 1 then
call TimerStart(T, 0.031250, true, function IssueMove)
endif
set u = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library BuildingInOutSystem initializer Init uses SpellEffectEvent, CameraSystem
globals
hashtable BIO_HASH = InitHashtable()
camerasetup array CAMERA
camerasetup APPLY_CAMERA = null
endglobals
function SetBuildingCamera takes nothing returns nothing
call CameraSetupApplyForceDuration(APPLY_CAMERA, true, 0 )
endfunction
private function Run takes nothing returns nothing
local integer id = GetHandleId(GetSpellTargetUnit())
local integer cam = LoadInteger(BIO_HASH, id, 0)
if LoadInteger(BIO_HASH, id, -1) == 0 then
//System isn't triggered
return
endif
//Move Unit
call SetUnitX(HERO, GetUnitX(LoadUnitHandle(BIO_HASH, id, 0)))
call SetUnitY(HERO, GetUnitY(LoadUnitHandle(BIO_HASH, id, 0)))
call SetUnitX(PET, GetUnitX(HERO))
call SetUnitY(PET, GetUnitY(HERO))
//Fix camera
if GetUnitY(HERO) < 0.00 then
call ExpandMinimap(true)
call ClearTextMessages()
call DisplayTimedTextToPlayer(Player(0), 0.8, 0.1, 3,"|cffccccff" + LoadStr(BIO_HASH, id, 1))
set APPLY_CAMERA = CAMERA[cam]
call TimerStart(BUILDING_CAMERA_TIMER, 0.03, true, function SetBuildingCamera )
set IS_IN_BUILDING = true
else
call ClearTextMessages()
call DisplayTimedTextToPlayer(Player(0), 0.8, 0.1, 3,"|cffccccff" + LoadStr(BIO_HASH, id, 1))
call PauseTimer(BUILDING_CAMERA_TIMER)
set APPLY_CAMERA = null
set IS_IN_BUILDING = false
call ExpandMinimap(false)
endif
endfunction
private function SaveBuilding takes integer id, unit u1, unit u2, boolean b, string s, camerasetup cam returns nothing
call SaveInteger( BIO_HASH, GetHandleId(u1), -1 , 1)
call SaveInteger( BIO_HASH, GetHandleId(u1), 0, id)
call SaveStr( BIO_HASH, GetHandleId(u1), 1, s )
if b then
call ShowUnit(u1, false)
endif
call SaveUnitHandle(BIO_HASH, GetHandleId(u1), 0, u2)
call SaveUnitHandle(BIO_HASH, id, 0, u1)
set CAMERA[id] = cam
endfunction
function UnlockBuilding takes integer id returns nothing
call ShowUnit(LoadUnitHandle(BIO_HASH, id, 0), true)
endfunction
function SetupBuildingInOutSystem takes nothing returns nothing
//---------------|-id-|---from-unit-----|------to unit-----|locked|--------area name-----------------|------camera-------------|
call SaveBuilding( 1, gg_unit_n00X_0036, gg_unit_n00X_0015, false, "Martin's House" , gg_cam_Camera_Intro_01 )
call SaveBuilding( 2, gg_unit_n00X_0015, gg_unit_n00X_0036, false, "The Ancient Forest" , null )
call SaveBuilding( 3, gg_unit_n00X_0018, gg_unit_n00X_0046, false, "Town Guard's Barracks" , gg_cam_House_01 )
call SaveBuilding( 4, gg_unit_n00X_0046, gg_unit_n00X_0018, false, "Waterwille Village" , null )
call SaveBuilding( 5, gg_unit_n00X_0113, gg_unit_n00X_0009, true , "Ruinned House Basement" , gg_cam_Basement_01 )
call SaveBuilding( 6, gg_unit_n00X_0009, gg_unit_n00X_0113, true , "Waterwille Village" , null )
call SaveBuilding( 7, gg_unit_n00X_0140, gg_unit_n00X_0114, true , "Cave" , gg_cam_Cave_01 )
call SaveBuilding( 8, gg_unit_n00X_0114, gg_unit_n00X_0140, true , "The Ancient Forest" , null )
call SaveBuilding( 9, gg_unit_n00X_0340, gg_unit_n00X_0337, true , "The Ancient Santuary" , gg_cam_Cave_02 )
call SaveBuilding( 10, gg_unit_n00X_0337, gg_unit_n00X_0340, true , "The Lands Between" , null )
call SaveBuilding( 11, gg_unit_n00X_0386, gg_unit_n00X_0385, false, "The Den of Volves" , gg_cam_Cave_03 )
call SaveBuilding( 12, gg_unit_n00X_0385, gg_unit_n00X_0386, false, "The Lands Between" , null )
call SaveBuilding( 13, gg_unit_n00X_0252, gg_unit_n00X_0223, false, "Abandoned Bandit Cave" , gg_cam_Cave_04 )
call SaveBuilding( 14, gg_unit_n00X_0223, gg_unit_n00X_0252, false, "The Lands Between" , null )
call SaveBuilding( 15, gg_unit_n00X_0253, gg_unit_n00X_0016, true , "Tom Watson's House" , gg_cam_House_02 )
call SaveBuilding( 16, gg_unit_n00X_0016, gg_unit_n00X_0253, true , "Waterwille Village" , null )
call SaveBuilding( 17, gg_unit_n00X_0043, gg_unit_n00X_0233, true , "Tom Watson's House Basement" , gg_cam_Basement_02 )
call SaveBuilding( 18, gg_unit_n00X_0233, gg_unit_n00X_0043, true , "Tom Watson's House" , gg_cam_House_02 )
call SaveBuilding( 19, gg_unit_n00X_0245, gg_unit_n00X_0256, true , "Bandit Hideout" , gg_cam_Cave_05 )
call SaveBuilding( 20, gg_unit_n00X_0256, gg_unit_n00X_0245, true , "Tom Watson's House Basement" , gg_cam_Basement_02 )
call SaveBuilding( 21, gg_unit_n00X_0205, gg_unit_n00X_0254, true , "Waterwille Village" , null )
call SaveBuilding( 22, gg_unit_n00X_0254, gg_unit_n00X_0205, true , "Bandit Hideout" , gg_cam_Cave_05 )
call SaveBuilding( 23, gg_unit_n00X_0326, gg_unit_n00X_0332, false, "Waterwille Village" , null )
call SaveBuilding( 24, gg_unit_n00X_0332, gg_unit_n00X_0326, false, "Waterville Inn" , gg_cam_House_06 )
//-----------------------------------------------------------------------------------------------------------------------------|
/* Starting Setup because our hero is already locaded inside of a building */
set APPLY_CAMERA = gg_cam_Camera_Intro_01
set IS_IN_BUILDING = true
set BUILDING_CAMERA_TIMER = CreateTimer()
call TimerStart(BUILDING_CAMERA_TIMER, 0.03, true, function SetBuildingCamera )
endfunction
private function Init takes nothing returns nothing
call RegisterSpellEffectEvent('A02E', function Run)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library BookSystem
struct Book extends array
private static constant trigger T1 = CreateTrigger()
private static constant trigger T2 = CreateTrigger()
private static dialog BOOK
private static string array BOOK_TEXT
private static method run takes nothing returns nothing
local string text
if GetItemLevel(GetManipulatedItem()) > 1000 then
set text = BOOK_TEXT[GetItemLevel(GetManipulatedItem()) - 1000]
call DialogSetMessage(BOOK, text)
call DialogDisplay(Player(0), BOOK, true)
endif
endmethod
private static method setup takes nothing returns nothing
/*
Books
*/
set BOOK_TEXT[1] = " Nchylbar the Old Adventurer
--------------------------------------------------
|c00FFFFFFNchylbar had enjoyed an adventurous youth,
but had grown to be a very wise, very old
adventurer who spent his life searching for
the truth and dispelling superstitions. But
much of the world still puzzled him, and
nothing was a greater enigma to him that the
nature of the Ancient Elves and Magic.
Nothing, however, was a greater question
to Nchylbar than the limits of divine
power. Were the Greater Beings the masters
of the entire world, or did the humbler
creatures have the strength to forge their
own destinies?
No one knows what happened to him, all that
remains is knowledge saved in old books.|r
--------------------------------------------------"
set BOOK_TEXT[2] = " The Darkests Fears
--------------------------------------------------
|c00FFFFFFBrother, I still call you brother for we
share our bonds of blood, tested but
unbroken by hatred. Even if I am
murdered, which seems inevitable now,
know that, brother. You and me are not
innocents, so our benedictions of mutual
enmity is not tragedy, but horror. This
state of silent, shadowed war, of secret
poisons and sleeping men strangled in
their beds, of the sudden arrow and the
artful dagger, has no end that I can see.
No possibility for peace. I see the
shadows in the room move though the
flame of my candle is steady.
I know the signs that I …|r
--------------------------------------------------"
set BOOK_TEXT[3] = " Hunter's Journal - I
--------------------------------------------------
|c00FFFFFFTracked down a small den of bears
today. Their pelts are in fine condition
and should fetch a good price.
Going to set up camp for the night and
kill the beasts in the morning.
Hopefully we can get by on the few
arrows we have left, or I may have to
fall back on my blade.|r
--------------------------------------------------"
set BOOK_TEXT[4] = " Hunter's Journal - II
--------------------------------------------------
|c00FFFFFFAfter trailing the beasts forseveral
days, I think we've finally found their
lair. It seems like theiren is further
in this cave. There maybe more of them
than we first thought, but after seeing
the strange columnsand pipes, there may
be some sort ofruin here.
My Gran always said those places were
full of treasures just waiting for the
first person to find them. We've decided
to make camp and try to clear out the
animals and see if there is anything
worth taking.|r
--------------------------------------------------"
set BOOK_TEXT[5] = " Book of Terror
--------------------------------------------------
|c00FFFFFFBeneath the tides, lay fathoms of
ominous darkness. Inked in death, the blackness
surges eternally, everlasting hunger for flesh,
bone and blood the grasping tide of churning
doom awaits.|r
--------------------------------------------------"
set BOOK_TEXT[6] = " Potion of Non-Motion
--------------------------------------------------
|c00FFFFFFAmong the many ingenious inventions of the
mad forest dwellers, this contagious poison
will hex the blood cells of any victim it’s
magical fluid grips. One small sting, slice
or injection is enough to spread a clay-like
fluid throughout the body, petrifying the
blood in all veins for a small duration of
time. |r
--------------------------------------------------"
set BOOK_TEXT[7] = " Potion of Life
--------------------------------------------------
|c00FFFFFFIn the past, the magical race of elves
once discovered how to absorb their life
essence into fluid substances, while indeed
making the Elves weaker for a set duration
of time, they did indeed stumble upon a
superb means of life giving waters in times
of need.|r
--------------------------------------------------"
set BOOK_TEXT[8] = " Thordundrion
--------------------------------------------------
|c00FFFFFFThis powerful dwarven artefact of a sword
looks to be a practical combination of hammer
and sword. Its runes pulse with thunderous
magic, and its silvery details shine as if
the weapon had never aged. One could nearly
suspect this to be the forerunner to the
venerable Axe.|r
--------------------------------------------------"
set BOOK_TEXT[9] = " Jack the Black
--------------------------------------------------
|c00FFFFFFJack the Black is the notorious albino
bandit-lord of the Five Man Poachers gang
of south-western Wild Lands. He is renowned
for his fast and effective hatchet work in
combat, dual wielding his “Pocket Axes” as
he calls them, and working like a “surgeon”
going by some of his men, when he delivers
his bloody “Royal Strike” move. |r
--------------------------------------------------"
/*
End Books
*/
set BOOK = DialogCreate()
call DialogSetMessage(BOOK, "Text")
call DialogAddButton(BOOK, "Close Book", 0)
endmethod
private static method onInit takes nothing returns nothing
call TriggerRegisterTimerEvent(T1, 1.00, false)
call TriggerRegisterPlayerUnitEvent(T2, Player(0), EVENT_PLAYER_UNIT_USE_ITEM, null)
call TriggerAddAction(T1, function thistype.setup)
call TriggerAddAction(T2, function thistype.run)
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct TeleportSystem extends array
private static constant integer ABIL_CODE1 = 'A03A'
private static constant integer ABIL_CODE2 = 'A00V'
private static constant integer T_SCROLL = 'I03K'
private static constant trigger T1 = CreateTrigger()
private static constant trigger T2 = CreateTrigger()
private static constant trigger T3 = CreateTrigger()
private static dialog T_DIALOG = DialogCreate()
private static button array T_BUTTON
private static string SFX = "Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl"
private static string array color
private static boolean array T_B
private static real array X
private static real array Y
private static unit array CoP
private static method fix takes boolean b returns nothing
if b then
call CreateAdvancedTextTag(TT_CRITICAL, TXTC[2] + "Ah, nevermind.", GetUnitX(HERO), GetUnitY(HERO)+75)
else
call CreateAdvancedTextTag(TT_CRITICAL, TXTC[2] + "Selected Circle of Power isn't activated", GetUnitX(HERO), GetUnitY(HERO)+75)
endif
call UnitAddItem(HERO, CreateItem(T_SCROLL, GetUnitX(HERO), GetUnitY(HERO)))
endmethod
private static method doAction takes real x, real y returns nothing
if x == 0 or y == 0 then
call thistype.fix(true)
endif
call SetUnitX(HERO, x)
call SetUnitY(HERO, y)
call SetUnitX(PET, x)
call SetUnitY(PET, y)
call PanCameraTo(x, y)
call DestroyEffect(AddSpecialEffect(SFX, x, y))
endmethod
private static method click takes nothing returns nothing
local button cb = GetClickedButton()
local integer i = 1
loop
exitwhen i > 6
if cb == T_BUTTON[i] then
if T_B[i] then
call thistype.doAction(X[i], Y[i])
else
call thistype.fix(false)
endif
set cb = null
return
endif
set i = i + 1
endloop
call thistype.fix(true)
set cb = null
endmethod
private static method run takes nothing returns nothing
if not GetUnitCombatState(GetTriggerUnit()) then
call DialogDisplay(Player(0), T_DIALOG, true)
else
call thistype.fix(true)
endif
endmethod
private static method runCoP takes nothing returns nothing
local integer i = 2
loop
exitwhen i>6
if CoP[i] == GetTriggerUnit() and not (T_B[i]) then
set T_B[i] = true
call DisplayTimedTextToPlayer(Player(0), 0, 0 , 5.00, "Circle of Power:" + TXTC[6] + " Activated")
set color[i] = TXTC[6]
call DialogClear(T_DIALOG)
set T_BUTTON[1] = DialogAddButton(T_DIALOG, color[1] + "Camp",0)
set T_BUTTON[2] = DialogAddButton(T_DIALOG, color[2] + "Swamp",0)
set T_BUTTON[3] = DialogAddButton(T_DIALOG, color[3] + "Hills of Arnor",0)
set T_BUTTON[4] = DialogAddButton(T_DIALOG, color[4] + "Ruined Tower",0)
set T_BUTTON[5] = DialogAddButton(T_DIALOG, color[5] + "Graveyard",0)
set T_BUTTON[6] = DialogAddButton(T_DIALOG, color[6] + "Sanctuary",0)
set T_BUTTON[7] = DialogAddButton(T_DIALOG, color[7] + "Cancel",0)
call UnitRemoveAbility(GetTriggerUnit(), ABIL_CODE2)
call DestroyEffect(AddSpecialEffect("war3mapImported\\BlizzardEruption.mdx", GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit())))
endif
set i = i+1
endloop
endmethod
private static method setup takes nothing returns nothing
local integer i = 1
set color[1] = TXTC[6]
set color[2] = TXTC[8]
set color[3] = TXTC[8]
set color[4] = TXTC[8]
set color[5] = TXTC[8]
set color[6] = TXTC[8]
set color[7] = TXTC[0]
set T_BUTTON[1] = DialogAddButton(T_DIALOG, color[1] + "Camp",0)
set T_BUTTON[2] = DialogAddButton(T_DIALOG, color[2] + "Swamp",0)
set T_BUTTON[3] = DialogAddButton(T_DIALOG, color[3] + "Village",0)
set T_BUTTON[4] = DialogAddButton(T_DIALOG, color[4] + "Ruined Tower",0)
set T_BUTTON[5] = DialogAddButton(T_DIALOG, color[5] + "Graveyard",0)
set T_BUTTON[6] = DialogAddButton(T_DIALOG, color[6] + "Sanctuary",0)
set T_BUTTON[7] = DialogAddButton(T_DIALOG, color[7] + "Cancel",0)
call DialogSetMessage(T_DIALOG, "Select your destination")
call TriggerRegisterDialogEvent(T2, T_DIALOG)
call TriggerAddAction( T2, function thistype.click )
set T_B[1] = true
set CoP[1] = gg_unit_ncop_0108
call UnitRemoveAbility(CoP[1], ABIL_CODE2)
set CoP[2] = gg_unit_ncop_0014
set CoP[3] = gg_unit_ncop_0008
set CoP[4] = gg_unit_ncop_0076
set CoP[5] = gg_unit_ncop_0119
set CoP[6] = gg_unit_ncop_0147
loop
exitwhen i>6
set X[i] = GetUnitX(CoP[i])
set Y[i] = GetUnitY(CoP[i])
set i = i+1
endloop
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABIL_CODE1, function thistype.run)
call TriggerRegisterTimerEvent(T1, 0.00, false)
call TriggerAddAction(T1, function thistype.setup)
call RegisterSpellEffectEvent(ABIL_CODE2, function thistype.runCoP)
endmethod
endstruct
//TESH.scrollpos=6
//TESH.alwaysfold=0
library ResourceGenerateSystem uses AdvancedTextTag
globals
/* Real Item Id's */
constant integer GOLD_ID = 'I00C'
/* Dummy Item SFX Id's */
constant integer GOLD_EX_ID = 'e003'
endglobals
function HandleItems takes nothing returns nothing
local item it = GetEnumItem()
local integer gold
if GetWidgetLife(it) < 0.405 then
set it = null
return
endif
if GetItemTypeId(it) == GOLD_ID then
call KillUnit( CreateUnit(Player(15), GOLD_EX_ID , GetItemX(it), GetItemY(it), 0) )
set gold = LoadInteger(CREEP_HASH, GetHandleId(it), 0)
if gold > 0 then
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_GOLD) + gold)
call CreateAdvancedTextTag(TT_WHIRL, TXTC[4] + "+ " + I2S(gold) + " gold", GetItemX(it),GetItemY(it))
endif
call FlushChildHashtable(CREEP_HASH, GetHandleId(it))
call RemoveItem(it)
endif
set it = null
endfunction
function ForceResourcePick takes nothing returns nothing
local item it = GetManipulatedItem()
local integer gold
if GetItemTypeId(it) == GOLD_ID then
call KillUnit( CreateUnit(Player(15), GOLD_EX_ID , GetItemX(it), GetItemY(it), 0) )
set gold = LoadInteger(CREEP_HASH, GetHandleId(it), 0)
if gold > 0 then
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_GOLD) + gold)
call CreateAdvancedTextTag(TT_WHIRL, TXTC[4] + "+ " + I2S(gold) + " gold", GetItemX(it),GetItemY(it))
endif
call FlushChildHashtable(CREEP_HASH, GetHandleId(it))
call RemoveItem(it)
endif
set it = null
endfunction
function CreateResourceItem takes integer id, unit u, integer value returns nothing
local integer i = GetRandomInt(1,5)
local item it
set value = value/i
if value == 0 then
set value = 1
endif
loop
exitwhen i == 0
set it = CreateItem(id , GetUnitX(u) + GetRandomReal(-150,150), GetUnitY(u) + GetRandomReal(-150,150))
call SaveInteger(CREEP_HASH, GetHandleId(it), 0, value)
set i = i-1
endloop
set it = null
endfunction
function CheckItemsInRange takes nothing returns nothing
local rect r = Rect( GetUnitX(HERO) - 150, GetUnitY(HERO) - 150, GetUnitX(HERO) + 150, GetUnitY(HERO) + 150 )
call EnumItemsInRect(r, null, function HandleItems)
call RemoveRect(r)
set r = null
endfunction
function SetupResourceGenerateSystem takes nothing returns nothing
local trigger trig = CreateTrigger()
call TimerStart(CreateTimer(), 0.03, true, function CheckItemsInRange )
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
call TriggerAddAction(trig, function ForceResourcePick)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=105
//TESH.alwaysfold=0
library CreepSystem initializer Init uses DamageSystem, ResourceGenerateSystem, AdvancedTextTag
globals
hashtable CREEP_HASH = InitHashtable()
real RESPAWN_TIMER = 180.00
private real DISTANCE = 300.00
private player CREEP_OWNER = Player(10)
private player BANDIT_OWNER = Player(11)
integer LEVEL = 1
/* Item drop globals */
private constant integer COMMON_ITEM = 11
private constant real COMMON_ITEM_CHANCE = 0.20
private constant integer UNCOMMON_ITEM = 12
private constant real UNCOMMON_ITEM_CHANCE = 0.10
private constant integer RARE_ITEM = 13
private constant real RARE_ITEM_CHANCE = 0.05
private constant integer FOOD_ITEM = 101
private constant real FOOD_ITEM_CHANCE = 0.20
private constant integer COMMON_ABILITY = 200
private constant real COMMON_ABILITY_CHANCE = 0.07
private constant integer UNCOMMON_ABILITY = 201
private constant real UNCOMMON_ABILITY_CHANCE = 0.05
/* End item drop globals */
/* Creep ability globals */
private constant integer ABILITY_TYPE_INSTANT = 1001
private constant integer ABILITY_TYPE_TARGET = 1002
private constant integer ABILITY_TYPE_POINT = 1003
private constant integer ABILITY_TYPE_SELF = 1004
/* End Creep ability globals */
endglobals
private function CreepAddAbility takes integer unit_id, integer a1, string s1, integer a2, string s2, integer a3, string s3, integer a4, string s4 returns nothing
call SaveInteger(CREEP_HASH, unit_id, ABILITY_TYPE_INSTANT, a1)
call SaveStr( CREEP_HASH, unit_id, -ABILITY_TYPE_INSTANT, s1)
call SaveInteger(CREEP_HASH, unit_id, ABILITY_TYPE_TARGET , a2)
call SaveStr( CREEP_HASH, unit_id, -ABILITY_TYPE_TARGET , s2)
call SaveInteger(CREEP_HASH, unit_id, ABILITY_TYPE_POINT , a3)
call SaveStr( CREEP_HASH, unit_id, -ABILITY_TYPE_POINT , s3)
call SaveInteger(CREEP_HASH, unit_id, ABILITY_TYPE_SELF , a4)
call SaveStr( CREEP_HASH, unit_id, -ABILITY_TYPE_SELF , s4)
endfunction
function SaveCreep takes integer id, real r1, real r2, real r3, real r4, real d1, real d2, real d3, real d4, real bc, real bd, real cc, real cm, real scc, real scm, real rc, real rm, real e, real s, real exp, real gold returns nothing
call SaveReal(CREEP_HASH, id, 1, r1)
call SaveReal(CREEP_HASH, id, 2, r2)
call SaveReal(CREEP_HASH, id, 3, r3)
call SaveReal(CREEP_HASH, id, 4, r4)
call SaveReal(CREEP_HASH, id, 5, d1)
call SaveReal(CREEP_HASH, id, 6, d2)
call SaveReal(CREEP_HASH, id, 7, d3)
call SaveReal(CREEP_HASH, id, 8, d4)
call SaveReal(CREEP_HASH, id, 9, bc)
call SaveReal(CREEP_HASH, id,10, bd)
call SaveReal(CREEP_HASH, id,11, cc)
call SaveReal(CREEP_HASH, id,12, cm)
call SaveReal(CREEP_HASH, id,13, scc)
call SaveReal(CREEP_HASH, id,14, scm)
call SaveReal(CREEP_HASH, id,15, rc)
call SaveReal(CREEP_HASH, id,16, rm)
call SaveReal(CREEP_HASH, id,17, e)
call SaveReal(CREEP_HASH, id,18, s)
call SaveReal(CREEP_HASH, id,19, exp)
call SaveReal(CREEP_HASH, id,20, gold)
endfunction
function LoadCreep takes unit u returns nothing
local integer id = GetUnitTypeId(u)
call Unit[u].setResistance(LoadReal(CREEP_HASH, id, 1),LoadReal(CREEP_HASH, id, 2),LoadReal(CREEP_HASH, id, 3),LoadReal(CREEP_HASH, id, 4))
call Unit[u].setDamage(LoadReal(CREEP_HASH, id, 5),LoadReal(CREEP_HASH, id, 6),LoadReal(CREEP_HASH, id, 7),LoadReal(CREEP_HASH, id, 8))
call Unit[u].setBash(LoadReal(CREEP_HASH, id, 9),LoadReal(CREEP_HASH, id,10))
call Unit[u].setCritical(LoadReal(CREEP_HASH, id, 11),LoadReal(CREEP_HASH, id, 12))
call Unit[u].setSpellCritical(LoadReal(CREEP_HASH, id, 13),LoadReal(CREEP_HASH, id, 14))
call Unit[u].setReflect(LoadReal(CREEP_HASH, id, 15),LoadReal(CREEP_HASH, id, 16))
call Unit[u].setEvasion(LoadReal(CREEP_HASH, id, 17))
call Unit[u].setSpellPower(LoadReal(CREEP_HASH, id, 18))
endfunction
function SetupCreepSystem takes nothing returns nothing
local group g = CreateGroup()
local unit u
local integer id
/* Creep Stats */
// id, r1, r2, r3, r4, d1, d2, d3, d4, bc, bd, cc, cm, scc,scm, rc, rm, e, s, exp, gold,shadow
call SaveCreep('n000', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,1.25, 0, 0, 0, 0, 10, 0, 50, 5) //Wolf
call SaveCreep('n00H', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20,1.70, 0, 0, 0, 0, 10, 0, 60, 6) //Dire Wolf
call SaveCreep('n00I', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,2.00, 0, 0, 0, 0, 20, 0, 200, 100) //Alpha Wolf
call SaveCreep('n004', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,1.25, 0, 0, 0, 0, 10, 0, 50, 5) //Boar
call SaveCreep('n012', 0, 0, 0, 0, 0, 0, 0, 0, 5,0.5, 5,1.25, 0, 0, 0, 0, 10, 0, 50, 5) //Crab
call SaveCreep('n008', 0, 0, 0, 0, 0, 0, 0, 0, 5,0.5, 5,1.25, 0, 0, 0, 0, 10, 0, 70, 7) //Dark Crab
call SaveCreep('n009', 0, 0, 0, 0, 0, 0, 0, 0, 10,0.6, 5,1.25, 0, 0, 0, 0, 10, 0, 500, 200) //Giant Crab
call SaveCreep('n00A', 0, 0, 0, 0, 0, 0, 0, 0, 5,0.5, 5,1.25, 0, 0, 20,0.5, 10, 0, 60, 6) //Makrura
call SaveCreep('n00C', 0, 0, 0, 0, 0, 0, 0, 0, 5,0.5, 5,1.25, 0, 0, 20,0.5, 10, 0, 80, 8) //Dark Makrura
call SaveCreep('n00G', 0, 0, 0, 0, 0, 0, 0, 0, 25,0.8, 5,1.25, 0, 0, 20,0.5, 10, 0, 1000, 500) //Tidal Lord
call SaveCreep('n002', 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5,1.25, 0, 0, 0, 0, 66, 0, 50, 5) //Spirit
call SaveCreep('n00N', 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10,1.75, 0, 0, 0, 0, 80, 0, 100, 10) //Wraith
call SaveCreep('n006', 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10,1.25, 0, 0, 0, 0, 10, 0, 75, 7) //Bandit Axeman
call SaveCreep('n007', 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 10,1.25, 0, 0, 0, 0, 10, 0, 75, 7) //Bandit Spearman
call SaveCreep('n005', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,1.25, 0, 0, 10,0.2, 10, 0, 75, 7) //Skeleton Swordsman
call SaveCreep('n00J', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,1.25, 0, 0, 0, 0, 10, 0, 75, 7) //Skeleton Archer
call SaveCreep('n00L',25, 10, 10, 10, 5, 0, 0, 0, 0, 0, 5,1.25, 0, 0, 0, 0, 10, 10, 75, 7) //Skeleton Mage
call SaveCreep('n00M',25, 0, 0, 0, 10, 0, 0, 0, 0, 0, 5,1.25, 0, 0, 0, 0, 10, 0, 110, 7) //Skeleton Burning Archer
call SaveCreep('n00O', 0, 50, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 100, 10) //Water Elemental
call SaveCreep('n00P', 0, 0, 0, 0, 0, 0, 0, 0, 25,1.0, 0, 0, 0, 0, 25,0.8, 10, 0, 900, 100) //Dragon Turtle
call SaveCreep('n00Q',50, 50, 75, 50, 0, 0, 0, 0, 25,1.0, 0, 0, 0, 0, 25,0.8, 10, 0, 120, 15) //Mud Golem
call SaveCreep('n00R',90, 90, 90, 90, 0, 0, 0, 0, 25,1.0, 0, 0, 0, 0, 25,0.8, 10, 0, 2000, 1000) //Rock Golem
//--------------------------------------------------------------------------------------------------------|
/* End Creep Stats */
/* Creep Abilities */
//---------------------id--|-----instant-------|---------target-----------|-------point------|--------self--------|
call CreepAddAbility('n000', 'A01E', "roar", 'A01H', "slow", 0, "", 0, "") //Wolf -> Roar (Level 1), Open Wounds (Level 1)
call CreepAddAbility('n00H', 'A01G', "roar", 'A01H', "slow", 0, "", 0, "") //Dire Wolf -> Roar (Level 2), Open Wounds (Level 1)
call CreepAddAbility('n00I', 0, "", 'A01J', "slow", 0, "", 0, "") //Alpha Wolf -> Roar (Level 3), Open Wounds (Level 3)
call CreepAddAbility('n004', 'A00G', "roar", 'A01H', "slow", 0, "", 0, "") //Boar -> Open Wounds (Level 1)
call CreepAddAbility('n012', 0, "", 0, "", 0, "", 0, "") //Crab
call CreepAddAbility('n008', 0, "", 'A00J',"creepthunderbolt", 0, "", 0, "") //Dark Crab -> Gush (Level 1)
call CreepAddAbility('n009', 0, "", 'A00J',"creepthunderbolt", 0, "", 0, "") //Giant Crab -> Gush (Level 1)
call CreepAddAbility('n00A', 0, "", 'A00U',"creepthunderbolt", 0, "", 'A01K',"frostarmor") //Makrura -> Gush (Level 2), Frost Armor (Level 1)
call CreepAddAbility('n00C', 0, "", 'A00U',"creepthunderbolt", 0, "", 'A01L',"frostarmor") //Dark Makrura -> Gush (Level 2), Frost Armor (Level 2)
call CreepAddAbility('n00G', 0, "", 'A00S',"creepthunderbolt", 0, "", 'A01M',"frostarmor") //Tidal Lord -> Gush (Level 3), Frost Armor (Level 3)
call CreepAddAbility('n002', 0, "", 0, "", 0, "", 0, "") //Spirit
call CreepAddAbility('n00N', 0, "", 'A01Q', "slow", 0, "", 0, "") //Wraith -> Slow (Level 1)
call CreepAddAbility('n006', 0, "", 0, "", 0, "", 0, "") //Bandit Axeman
call CreepAddAbility('n007', 0, "", 0, "", 0, "", 0, "") //Bandit Spearman
call CreepAddAbility('n005', 0, "", 0, "", 0, "", 0, "") //Skeleton Swordsman
call CreepAddAbility('n00J', 0, "", 0, "", 0, "", 0, "") //Skeleton Archer
call CreepAddAbility('n00L', 0, "", 0, "", 'A10O',"firebolt", 0, "") //Skeleton Mage -> Fire Ball (Level 2)
call CreepAddAbility('n00M', 0, "", 0, "", 'A10N',"firebolt", 0, "") //Skeleton Burning Archer -> Fire Ball (Level 1)
call CreepAddAbility('n00O', 0, "", 0, "", 0, "", 0, "") //Water Elemental
call CreepAddAbility('n00P', 0, "", 0, "", 'A10P',"firebolt", 0, "") //Dragon Turtle -> Fire Ball (Level 3)
call CreepAddAbility('n00Q', 0, "", 'A01S', "slow", 0, "", 0, "") //Mud Golem -> Slow (Level 2)
call CreepAddAbility('n00R', 0, "", 'A01R', "slow", 0, "", 0, "") //Rock Golem -> Slow (Level 3)
//----------------------------------------------------------------------------------------------------------------|
/* End Creep Abilities */
/* Pet Stats */
// id, r1, r2, r3, r4, d1, d2, d3, d4, bc, bd, cc, cm, scc,scm, rc, rm, e, s, exp, gold,shadow
call SaveCreep('N017', 5, 5, 5, 5, 0, 1, 0, 0, 10,0.5, 10,2.50, 5, 1.25, 0, 0, 10, 10, 0, 0) //Frost Wolf
call SaveCreep('N019', 5, 5, 5, 5, 0, 1, 0, 0, 0,0.0, 10,2.00, 5, 1.25, 0, 0, 20, 10, 0, 0) //Wisp
call SaveCreep('N016', 5, 5, 5, 5, 1, 0, 0, 0, 10,0.5, 10,2.00, 5, 1.25, 0, 0, 10, 10, 0, 0) //Dragon Turtle
call SaveCreep('N018', 5, 5, 5, 5, 0, 0, 0, 1, 10,0.5, 10,2.00, 5, 1.25, 0, 0, 10, 10, 0, 0) //Wildkin
call SaveCreep('N014', 5, 5, 5, 5, 0, 0, 1, 0, 10,0.5, 10,2.00, 5, 1.25, 0, 0, 10, 10, 0, 0) //Dark Seer
/* End Creep Stats */
call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
set id = GetUnitTypeId(u)
if GetOwningPlayer(u) != Player(0) and GetOwningPlayer(u) != Player(1) then
call SaveReal(CREEP_HASH, GetHandleId(u), -1, GetUnitX(u))
call SaveReal(CREEP_HASH, GetHandleId(u), -2, GetUnitY(u))
call SaveReal(CREEP_HASH, GetHandleId(u), -3, GetUnitFacing(u))
call LoadCreep(u)
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
endfunction
private function Revive takes nothing returns nothing
local integer id = GetHandleId(GetExpiredTimer())
local player p = LoadPlayerHandle(CREEP_HASH, id, 0)
local integer u = LoadInteger(CREEP_HASH, id, 1)
local real x = LoadReal(CREEP_HASH, id, 2)
local real y = LoadReal(CREEP_HASH, id, 3)
local real a = LoadReal(CREEP_HASH, id, 4)
call LoadCreep(CreateUnit(p, u, x, y, a))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl", x, y))
call FlushChildHashtable(CREEP_HASH, id)
call DestroyTimer(GetExpiredTimer())
endfunction
private function CreepRespawn takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer id = GetUnitTypeId(u)
local real x = LoadReal(CREEP_HASH, GetHandleId(u), -1)
local real y = LoadReal(CREEP_HASH, GetHandleId(u), -2)
local real a = LoadReal(CREEP_HASH, GetHandleId(u), -3)
local integer exp = R2I(LoadReal(CREEP_HASH, id, 19) * GetRandomReal(0.80,1.20) * EXP)
local integer gold = R2I(LoadReal(CREEP_HASH, id, 20) * GetRandomReal(0.75,1.25))
local integer lvl = LoadInteger(CREEP_HASH, id, 23)
local player p = GetOwningPlayer(u)
local timer t = CreateTimer()
/* Pet System */
if u == PET then
call MsgDisp("Your pet is now criticaly wounded, you need to visit Pet Trainer to get him back.")
set IS_PET_ALIVE = false
set u = null
set p = null
return
endif
if u == HERO then
set u = null
set p = null
return
endif
/* Item drop system */
if IsUnitType(u, UNIT_TYPE_ANCIENT) then
//We ignore ancient units that are related to map dummy units
set u = null
set p = null
return
endif
if p == BANDIT_OWNER or p == CREEP_OWNER then
if GetRandomReal(0.00,1.00) <= COMMON_ITEM_CHANCE then
call CreateItem(ChooseRandomItem(COMMON_ITEM), GetUnitX(u), GetUnitY(u))
endif
if GetRandomReal(0.00,1.00) <= UNCOMMON_ITEM_CHANCE then
call CreateItem(ChooseRandomItem(UNCOMMON_ITEM), GetUnitX(u), GetUnitY(u))
endif
if GetRandomReal(0.00,1.00) <= RARE_ITEM_CHANCE then
call CreateItem(ChooseRandomItem(RARE_ITEM), GetUnitX(u), GetUnitY(u))
endif
if p == BANDIT_OWNER then
if GetRandomReal(0.00,1.00) <= FOOD_ITEM_CHANCE then
if GetRandomReal(0.00,1.00) > 0.33 then
call CreateItem(ChooseRandomItem(FOOD_ITEM), GetUnitX(u), GetUnitY(u))
else
call CreateItem(ChooseRandomItem(FOOD_ITEM), GetUnitX(u)-10, GetUnitY(u)-10)
call CreateItem(ChooseRandomItem(FOOD_ITEM), GetUnitX(u)+10, GetUnitY(u)+10)
endif
endif
endif
if GetRandomReal(0.00,1.00) < COMMON_ABILITY_CHANCE then
call CreateItem(ChooseRandomItem(COMMON_ABILITY), GetUnitX(u), GetUnitY(u))
endif
endif
/* Resource Generate System */
if GetOwningPlayer(GetKillingUnit()) == Player(0) then
call AddHeroXP(HERO, exp, true)
call AddHeroXP(PET, exp, true)
call CreateAdvancedTextTag(TT_CRITICAL, TXTC[5] + "+ " + I2S(exp) + " exp", GetUnitX(u),GetUnitY(u))
call CreateResourceItem(GOLD_ID, u, gold)
endif
call SavePlayerHandle(CREEP_HASH, GetHandleId(t), 0, p)
call SaveInteger(CREEP_HASH, GetHandleId(t), 1, id)
call SaveReal(CREEP_HASH, GetHandleId(t), 2, x)
call SaveReal(CREEP_HASH, GetHandleId(t), 3, y)
call SaveReal(CREEP_HASH, GetHandleId(t), 4, a)
call TimerStart(t, RESPAWN_TIMER, false, function Revive)
set u = null
set p = null
set t = null
endfunction
private function LevelUp takes nothing returns nothing
local integer level = GetHeroLevel(HERO)
local integer i = 7
if level == 0 then
set level = 1
endif
if GetTriggerUnit() == HERO then
loop
exitwhen i>12
call SetPlayerTechResearched(Player(i) , 'R001', level)
call SetPlayerTechResearched(Player(i) , 'R002', level)
call SetPlayerHandicap(Player(i), (290 + level*10)*0.01)
set i = i+1
endloop
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_LUMBER) + 3)
endif
endfunction
private function CreepTrySpellCast takes nothing returns nothing
local integer i1
local integer i2
local integer i3
local integer i4
local unit u1 = null
local unit u2 = null
if GetOwningPlayer(GetAttacker()) == Player(0) then
set u1 = GetTriggerUnit()
set u2 = GetAttacker()
set i1 = LoadInteger(CREEP_HASH, GetUnitTypeId(u1), ABILITY_TYPE_INSTANT)
set i2 = LoadInteger(CREEP_HASH, GetUnitTypeId(u1), ABILITY_TYPE_TARGET)
set i3 = LoadInteger(CREEP_HASH, GetUnitTypeId(u1), ABILITY_TYPE_POINT)
set i4 = LoadInteger(CREEP_HASH, GetUnitTypeId(u1), ABILITY_TYPE_SELF)
if i1 != 0 then
call IssueImmediateOrder(u1, LoadStr(CREEP_HASH, GetUnitTypeId(u1), -ABILITY_TYPE_INSTANT))
endif
if i2 != 0 then
call IssueTargetOrder(u1, LoadStr(CREEP_HASH, GetUnitTypeId(u1), -ABILITY_TYPE_TARGET), u2)
endif
if i3 != 0 then
call IssuePointOrder(u1, LoadStr(CREEP_HASH, GetUnitTypeId(u1), -ABILITY_TYPE_POINT), GetUnitX(u2), GetUnitY(u2))
endif
if i4 != 0 then
call IssueTargetOrder(u1, LoadStr(CREEP_HASH, GetUnitTypeId(u1), -ABILITY_TYPE_SELF), u1)
endif
set u1 = null
set u2 = null
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent( trig, Player( 0), EVENT_PLAYER_UNIT_DEATH , null )
call TriggerRegisterPlayerUnitEvent( trig, Player( 8), EVENT_PLAYER_UNIT_DEATH , null ) // Shadow Forces
call TriggerRegisterPlayerUnitEvent( trig, Player( 9), EVENT_PLAYER_UNIT_DEATH , null ) // Ancient Ones
call TriggerRegisterPlayerUnitEvent( trig, Player(10), EVENT_PLAYER_UNIT_DEATH , null ) // Animals
call TriggerRegisterPlayerUnitEvent( trig, Player(11), EVENT_PLAYER_UNIT_DEATH , null ) // Outlaws
call TriggerAddAction( trig, function CreepRespawn )
set trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent( trig, Player( 0), EVENT_PLAYER_HERO_LEVEL , null )
call TriggerAddAction( trig, function LevelUp )
set trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player( 8), EVENT_PLAYER_UNIT_ATTACKED, null) // Shadow Forces
call TriggerRegisterPlayerUnitEvent(trig, Player( 9), EVENT_PLAYER_UNIT_ATTACKED, null) // Ancient Ones
call TriggerRegisterPlayerUnitEvent(trig, Player(10), EVENT_PLAYER_UNIT_ATTACKED, null) // Animals
call TriggerRegisterPlayerUnitEvent(trig, Player(11), EVENT_PLAYER_UNIT_ATTACKED, null) // Outlaws
call TriggerAddAction(trig, function CreepTrySpellCast)
set trig = null
call LevelUp()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library PetSystem uses BaseSystems, Math, RegisterPlayerUnitEvent, CreepSystem
globals
private hashtable PET_HASH = InitHashtable()
integer MARKET_ID = 'h00C'
integer HEAL_PET_ID = 'I03V'
endglobals
private function Run takes nothing returns nothing
if MARKET_ID == GetUnitTypeId(GetTriggerUnit()) then
if GetItemTypeId(GetSoldItem()) == HEAL_PET_ID then
if IS_PET_ALIVE then
call SetUnitState(PET, UNIT_STATE_LIFE, 9999999999.00)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Items\\AIlm\\AIlmTarget.mdl", GetUnitX(PET), GetUnitY(PET)))
call RemoveItem(GetSoldItem())
return
else
call ReviveHero(PET, GetUnitX(HERO), GetUnitY(HERO), true)
call SetUnitState(PET, UNIT_STATE_MANA , GetUnitState(PET, UNIT_STATE_MAX_MANA))
set IS_PET_ALIVE = true
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Items\\AIlm\\AIlmTarget.mdl", GetUnitX(PET), GetUnitY(PET)))
call RemoveItem(GetSoldItem())
return
endif
endif
call RemoveItem(GetSoldItem())
endif
endfunction
private function IssueOrder takes nothing returns nothing
if IS_PET_ALIVE and GetDistanceBetween(GetUnitX(PET), GetUnitY(PET), GetUnitX(HERO), GetUnitY(HERO)) > 500 then
call IssuePointOrder(PET, "move", GetUnitX(HERO) + GetRandomReal(-50.,50.), GetUnitY(HERO) + GetRandomReal(-50.,50.))
endif
endfunction
function SetupPetSystem takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SELL_ITEM, function Run)
set PET = CreateUnit(Player(0), PET_ID, GetUnitX(HERO), GetUnitY(HERO), 0)
set PET_UD = GetUnitUserData(PET)
set IS_PET_ALIVE = true
call LoadCreep(PET)
call TimerStart(CreateTimer(), 1.00, true, function IssueOrder)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct HeroRespawn extends array
private static constant timer T = CreateTimer()
private static constant timerdialog TD = CreateTimerDialog(T)
private static unit TOMB
private static method run takes nothing returns nothing
call ReviveHeroLoc( HERO, RevivePos, true )
call SetUnitState( HERO , UNIT_STATE_MANA , GetUnitState( HERO , UNIT_STATE_MAX_MANA ) )
call TimerDialogDisplay(TD, false)
call SelectUnit(HERO, true)
call HeroFormSwap.run(SLOT_USED[101])
call SetUnitX(PET, GetUnitX(HERO))
call SetUnitY(PET, GetUnitY(HERO))
endmethod
public static method respawn takes nothing returns nothing
if GetTriggerUnit() == HERO then
call MsgDisp("Hero will be respawned in nearest safe location.")
set TOMB = CreateUnit(Player(15), 'h007', GetUnitX(HERO), GetUnitY(HERO), 0 )
call UnitApplyTimedLife (TOMB , 'BHwe' , 5 )
call TimerDialogSetRealTimeRemaining( TD , 5 )
call TimerDialogSetTitle( TD , "Respawn in:" )
call TimerDialogDisplay(TD, true)
call TimerStart(T, 5, false, function thistype.run)
call PauseTimer(BUILDING_CAMERA_TIMER)
set APPLY_CAMERA = null
set IS_IN_BUILDING = false
call ExpandMinimap(false)
endif
endmethod
public static method onInit takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.respawn)
endmethod
endstruct
//TESH.scrollpos=123
//TESH.alwaysfold=0
library HeroPickSystem initializer Init uses CreepSystem, CustomInterface, IntroCinematic, PetSystem, HeroStatsMultiboard, DisplaySpellName, HeroVisionSystem, CameraSystem
globals
private trigger TRIG_PET = CreateTrigger()
private trigger CLASS = CreateTrigger()
private trigger OKAY = CreateTrigger()
private timer T
private Table TRACK
private real array TRACKX
private real array TRACKY
private texttag T_HERO_NAME = CreateTextTag()
private texttag T_HERO_DESC = CreateTextTag()
private texttag T_HERO_INFO = CreateTextTag()
private texttag T_PET_NAME = CreateTextTag()
private texttag T_PET_DESC = CreateTextTag()
private string array S_DESC
private string array S_INFO
private string array S_PET_DESC
private destructable array AVATAR
private destructable array AVATAR_PET
private integer PET_PICK_ID = 0
private integer CLASS_ID = 0
private effect SFX1 = null
private effect SFX2 = null
endglobals
private function RegisterTrack takes integer id, real x, real y, trigger trig returns nothing
local trackable t = CreateTrackable("war3mapImported\\64x64Track.mdx", x, y, 270)
set TRACK[GetHandleId(t)] = id
set TRACKX[id] = x
set TRACKY[id] = y
call TriggerRegisterTrackableHitEvent(trig, t)
endfunction
private function LockCam takes nothing returns nothing
call CameraSetupApplyForceDuration(gg_cam___HeroSelect, true, 0)
endfunction
private function ClickClass takes nothing returns nothing
call ShowDestructable(AVATAR[CLASS_ID], false)
set CLASS_ID = TRACK[GetHandleId(GetTriggeringTrackable())]
call ShowDestructable(AVATAR[CLASS_ID], true)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl", TRACKX[CLASS_ID], TRACKY[CLASS_ID]))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl", TRACKX[CLASS_ID], TRACKY[CLASS_ID]))
call DestroyEffect(SFX2)
set SFX2 = AddSpecialEffect("buildings\\other\\CircleOfPower\\CircleOfPower.mdl", TRACKX[CLASS_ID], TRACKY[CLASS_ID])
call SetTextTagText(T_HERO_NAME, TXTC[5] + "Class: |r" + GetDestructableName(AVATAR[CLASS_ID]), 0.03)
call SetTextTagText(T_HERO_DESC, S_DESC[CLASS_ID], 0.022)
call SetTextTagText(T_HERO_INFO, S_INFO[CLASS_ID], 0.022)
endfunction
private function ClickPet takes nothing returns nothing
call ShowDestructable(AVATAR_PET[PET_PICK_ID], false)
set PET_PICK_ID = TRACK[GetHandleId(GetTriggeringTrackable())]
call ShowDestructable(AVATAR_PET[PET_PICK_ID], true)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl", TRACKX[PET_PICK_ID], TRACKY[PET_PICK_ID]))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl", TRACKX[PET_PICK_ID], TRACKY[PET_PICK_ID]))
call DestroyEffect(SFX1)
set SFX1 = AddSpecialEffect("buildings\\other\\CircleOfPower\\CircleOfPower.mdl", TRACKX[PET_PICK_ID], TRACKY[PET_PICK_ID])
call SetTextTagText(T_PET_NAME, TXTC[5] + "Pet: |r" + GetDestructableName(AVATAR_PET[PET_PICK_ID]), 0.03)
call SetTextTagText(T_PET_DESC, S_PET_DESC[PET_PICK_ID], 0.022)
endfunction
private function Confirm takes nothing returns nothing
if PET_PICK_ID == 0 or CLASS_ID == 0 then
call DisplayTimedTextToPlayer(Player(0),0,0,5, "Settings are not correct!")
else
call DisableTrigger(OKAY)
call DisableTrigger(TRIG_PET)
call DisableTrigger(CLASS)
call DestroyTextTag(T_HERO_NAME)
call DestroyTextTag(T_HERO_DESC)
call DestroyTextTag(T_HERO_INFO)
call DestroyTextTag(T_PET_NAME)
call DestroyTextTag(T_PET_DESC)
call DestroyTimer(T)
call DestroyEffect(SFX1)
call DestroyEffect(SFX2)
call ClearTextMessages()
if CLASS_ID == 1 then
set HERO = CreateUnit(Player(0), 'H000', -21100, -2600, -45) //Warrior
set HeroFormSwap.ABIL_CODE = 'A011'
elseif CLASS_ID == 2 then
set HERO = CreateUnit(Player(0), 'H002', -21100, -2600, -45) //Mage
set HeroFormSwap.ABIL_CODE = 'A00B'
elseif CLASS_ID == 3 then
set HERO = CreateUnit(Player(0), 'H006', -21100, -2600, -45) //Pilgrim
set HeroFormSwap.ABIL_CODE = 'A00Z'
elseif CLASS_ID == 4 then
set HERO = CreateUnit(Player(0), 'H00B', -21100, -2600, -45) //Thief
set HeroFormSwap.ABIL_CODE = 'A004'
elseif CLASS_ID == 5 then
set HERO = CreateUnit(Player(0), 'H00D', -21100, -2600, -45) //Assassin
set HeroFormSwap.ABIL_CODE = 'A013'
elseif CLASS_ID == 6 then
set HERO = CreateUnit(Player(0), 'H00L', -21100, -2600, -45) //Knight
set HeroFormSwap.ABIL_CODE = 'A010'
elseif CLASS_ID == 7 then
set HERO = CreateUnit(Player(0), 'H00M', -21100, -2600, -45) //Witchhunter
set HeroFormSwap.ABIL_CODE = 'A014'
elseif CLASS_ID == 8 then
set HERO = CreateUnit(Player(0), 'H016', -21100, -2600, -45) //Battlemage
set HeroFormSwap.ABIL_CODE = 'A00P'
elseif CLASS_ID == 9 then
set HERO = CreateUnit(Player(0), 'H017', -21100, -2600, -45) //Archer
set HeroFormSwap.ABIL_CODE = 'A00A'
elseif CLASS_ID == 10 then
set HERO = CreateUnit(Player(0), 'H018', -21100, -2600, -45) //Agent
set HeroFormSwap.ABIL_CODE = 'A012'
endif
call SelectUnit(HERO, true)
call SetPlayerAbilityAvailable(Player(0), HeroFormSwap.ABIL_CODE, false)
call UnitAddItem(HERO, CreateItem('I048', 0,0)) // Heal Ability
/* core globals */
set HERO_CLASS_ID = GetUnitTypeId(HERO)
set HERO_CLASS = CLASS_ID
set HERO_UD = GetUnitUserData(HERO)
/* end core globals */
if PET_PICK_ID == 11 then
set PET_ID = 'N017' // Frozen Wolf
elseif PET_PICK_ID == 12 then
set PET_ID = 'N019' // Wisp
elseif PET_PICK_ID == 13 then
set PET_ID = 'N016' // Dragon Turtle
elseif PET_PICK_ID == 14 then
set PET_ID = 'N018' // Wildkin
elseif PET_PICK_ID == 15 then
set PET_ID = 'N014' // Dark Seer
endif
set HERO_ID = GetUnitTypeId(HERO)
set HERO_NAME = GetHeroProperName(HERO)
call Rest.registerAbility()
call SetupWeatherSystem()
call SetupCreepSystem()
call SetupItemSystem()
call SetupResourceGenerateSystem()
call SetupBuildingInOutSystem()
call SetupPetSystem()
call SetupHeroStatsMultiboard()
call SetupDisplaySpellNameSystem()
call SetupHeroVisionSystem()
call SetupCameraSystem()
call DisableCinema()
call FadeIn(1)
call RegisterIntroCinematic()
set HERO_F3 = CreateUnit(Player(0), 'H01R', 0,0,0) // Inventory Key
endif
endfunction
function SetupHeroPickSystem takes nothing returns nothing
local integer i = 1
set TRACK = Table.create()
//Warrior
set AVATAR[1] = gg_dest_B022_2391
set S_DESC[1] = "|cffc3dbffHero Description:|r\nFierce and fearless, they charge\ninto combat without a second thought.\nBeing the masters in the use of\nheavy weapons and armor,\nwarriors are always on the\nfront lines, protecting the weak\nand fighting for justice.\n\n\n\n\n"
set S_INFO[1] = "|cffc3dbffHero Attributes:|r\n- (4) Agility\n- (4) Intelligence\n-|cffffcc00 (12) Strength|r\n\n|cffc3dbffSkills:|r\n- Blade \n- Blunt \n- Block \n- Heavy Armor\n\n\n\n\n"
//Mage
set AVATAR[2] = gg_dest_B024_2382
set S_DESC[2] = "|cffc3dbffHero Description:|r\nPrefering to use their extensive\nknowledge of all things magical,\nMages wield a might more powerful\nthan the sharpest blade\nand the rejuvenation abilities\nmore effective than any remedy.\n\n\n\n\n"
set S_INFO[2] = "|cffc3dbffHero Attributes:|r\n- (2) Agility\n-|cffffcc00 (14) Intelligence|r\n- (4) Strength\n\n|cffc3dbffSkills:|r\n- Restoration \n- Scholarship \n- Destruction \n- Mysticism\n\n\n\n\n"
//Pilgrim
set AVATAR[3] = gg_dest_B027_2383
set S_DESC[3] = "|cffc3dbffHero Description:|r\nHearty folk, well-versed\nin the tomes of old,\nPilgrims are no strangers\nwhen it comes to standing\non the front lines,\nas well as providing aid\nto those in need.\n\n\n\n\n"
set S_INFO[3] = "|cffc3dbffHero Attributes:|r\n- (6) Agility\n- (6) Intelligence\n-|cffffcc00 (8) Strength|r\n\n|cffc3dbffSkills:|r\n- Blunt \n- Heavy Armor \n- Restoration \n- Scholarship\n\n\n\n\n"
//Thief
set AVATAR[4] = gg_dest_B01K_2385
set S_DESC[4] = "|cffc3dbffHero Description:|r\nAs the most cunning\nand nimble kind of all,\nThieves specialize in using\nevery opportunity to take down\ntheir foes from a distance\nwith as little head-on\ncombat as possible.\n\n\n\n\n"
set S_INFO[4] = "|cffc3dbffHero Attributes:|r\n-|cffffcc00 (10) Agility|r\n- (5) Intelligence\n- (5) Strength\n\n|cffc3dbffSkills:|r\n- Athletic \n- Acrobatics \n- Marksmanship \n- Light Armor\n\n\n\n\n"
//Assassin
set AVATAR[5] = gg_dest_B025_2381
set S_DESC[5] = "|cffc3dbffHero Description:|r\nThese shadowy people\nutilize their skills in the\nsole purpose of obliterating\ntheir opponent, no matter\nthe means. Whether\nit's weapons or Magic,\nAssassins' target is\ndestined for doom.\n\n\n\n\n"
set S_INFO[5] = "|cffc3dbffHero Attributes:|r\n-|cffffcc00 (11) Agility|r\n- (5) Intelligence\n- (4) Strength\n\n|cffc3dbffSkills:|r\n- Marksmanship \n- Blade \n- Destruction \n- Mysticism\n\n\n\n\n"
//Knight
set AVATAR[6] = gg_dest_B021_2384
set S_DESC[6] = "|cffc3dbffHero Description:|r\nThe most noble and\ncompassionate of all,\nKnights are strong in body\nand in character.\nThey focus on defending\nthe weak, as well as\nspreading the knowledge of\nold throughout the Kingdom.\n\n\n\n\n\n\n"
set S_INFO[6] = "|cffc3dbffHero Attributes:|r\n- (3) Agility\n- (7) Intelligence\n-|cffffcc00 (10) Strength|r\n\n|cffc3dbffSkills:|r\n- Blade \n- Block \n- Heavy Armor \n- Scholarship\n\n\n\n\n"
//Witchhunter
set AVATAR[7] = gg_dest_B01I_2387
set S_DESC[7] = "|cffc3dbffHero Description:|r\nSwift with bows and clever\nwith spells, they use distance\nas their ally. No matter\nwhat kind of foe stands\nin front of them, using\ntheir wits Witchhunters will\nprevail regardless of the cost.\n\n\n\n\n"
set S_INFO[7] = "|cffc3dbffHero Attributes:|r\n- (9) Agility\n-|cffffcc00 (7) Intelligence|r\n- (4) Strength\n\n|cffc3dbffSkills:|r\n- Marksmanship \n- Light Armor \n- Destruction \n- Mysticism\n\n\n\n\n"
//Battlemage
set AVATAR[8] = gg_dest_B01B_2386
set S_DESC[8] = "|cffc3dbffHero Description:|r\nAble to resolve most conflicts\nwith either spell or sword,\nBattlemages are a deadly mix\nof scholars and soldiers.\nStanding in their way is\na mistake regretted by many.\n\n\n\n\n\n"
set S_INFO[8] = "|cffc3dbffHero Attributes:|r\n- (3) Agility\n-|cffffcc00 (9) Intelligence|r\n- (8) Strength\n\n|cffc3dbffSkills:|r\n- Blade \n- Heavy Armor \n- Restoration \n- Destruction\n\n\n\n\n"
//Archer
set AVATAR[9] = gg_dest_B01U_2389
set S_DESC[9] = "|cffc3dbffHero Description:|r\nAlthough adept at long-distance\ncombat, Archers are not afraid\nof drawing their sword and\ncharging the front lines.\nThey are considered as highly\nlethal adversaries with great\ndefensive capabilities.\n\n\n\n\n"
set S_INFO[9] = "|cffc3dbffHero Attributes:|r\n-|cffffcc00 (8) Agility|r\n- (4) Intelligence\n- (8) Strength\n\n|cffc3dbffSkills:|r\n- Athletic \n- Marksmanship \n- Blade \n- Heavy Armor\n\n\n\n\n"
//Agent
set AVATAR[10] = gg_dest_B01J_2388
set S_DESC[10] = "|cffc3dbffHero Description:|r\nIntelligent and agile, Agents\nare excellent scouts due\nto their spectral presence.\nThey are able to shoot\ndown most foes before\nthey even have a chance\nto draw their weapon.\n\n\n\n\n"
set S_INFO[10] = "|cffc3dbffHero Attributes:|r\n-|cffffcc00 (10) Agility|r\n- (6) Intelligence\n- (4) Strength\n\n|cffc3dbffSkills:|r\n- Acrobatics \n- Marksmanship \n- Light Armor \n- Scholarship\n\n\n\n\n"
//Pet: Frost Wolf
set AVATAR_PET[11] = gg_dest_B01V_11940
set S_PET_DESC[11] = "|cffc3dbffPet Description:|r\nAgile creature with good \nattack power. \n\n\n\n\n"
//Pet: Wisp
set AVATAR_PET[12] = gg_dest_B01W_11933
set S_PET_DESC[12] = "|cffc3dbffPet Description:|r\nMagic creature with good \ndefensive magic abilities. \n\n\n\n\n"
//Pet: Dragon Turtle
set AVATAR_PET[13] = gg_dest_B01X_11938
set S_PET_DESC[13] = "|cffc3dbffPet Description:|r\nDurable creature with good \ntanking skills. \n\n\n\n\n"
//Pet: Wildkin
set AVATAR_PET[14] = gg_dest_B01Y_11934
set S_PET_DESC[14] = "|cffc3dbffPet Description:|r\nFrenzy creature with good \nrushing skills. \n\n\n\n\n"
//Pet: Dark Seer
set AVATAR_PET[15] = gg_dest_B01Z_11937
set S_PET_DESC[15] = "|cffc3dbffPet Description:|r\nDark creature with good \noffensive magic abilities. \n\n\n\n\n"
call SetTextTagPos( T_HERO_NAME , -21184 , -4736 , 10 )
call SetTextTagText(T_HERO_NAME , "Choose your class!", 0.03)
call SetTextTagPos( T_HERO_DESC , -20764 , -4804 , 10 )
call SetTextTagText(T_HERO_DESC , " ", 0.022)
call SetTextTagPos( T_HERO_INFO , -20000 , -5088 , 10 )
call SetTextTagText(T_HERO_INFO , " ", 0.022)
call SetTextTagPos( T_PET_NAME , -21184 , -5088 , 10 )
call SetTextTagText(T_PET_NAME , "Choose your class!", 0.03)
call SetTextTagPos( T_PET_DESC , -21184 , -5088 , 10 )
call SetTextTagText(T_PET_DESC , " ", 0.022)
call TriggerRegisterTrackableHitEvent(OKAY, CreateTrackable("war3mapImported\\64x64Track.mdx", -19712, -5312, 270))
call RegisterTrack( 1, -21120, -5312, CLASS)
call RegisterTrack( 2, -20992, -5312, CLASS)
call RegisterTrack( 3, -20864, -5312, CLASS)
call RegisterTrack( 4, -20736, -5312, CLASS)
call RegisterTrack( 5, -20608, -5312, CLASS)
call RegisterTrack( 6, -20480, -5312, CLASS)
call RegisterTrack( 7, -20352, -5312, CLASS)
call RegisterTrack( 8, -20224, -5312, CLASS)
call RegisterTrack( 9, -20096, -5312, CLASS)
call RegisterTrack(10, -19968, -5312, CLASS)
//call RegisterTrack(11, -20672, -5504, TRIG_PET)
call RegisterTrack(12, -20544, -5504, TRIG_PET)
call RegisterTrack(13, -20416, -5504, TRIG_PET)
call RegisterTrack(14, -20288, -5504, TRIG_PET)
//call RegisterTrack(15, -20160, -5504, TRIG_PET)
call TriggerAddAction(CLASS, function ClickClass)
call TriggerAddAction(TRIG_PET, function ClickPet)
call TriggerAddAction(OKAY, function Confirm)
loop
call ShowDestructable( AVATAR[i], false)
call ShowDestructable( AVATAR_PET[i], false)
set i = i + 1
exitwhen i > 15
endloop
set T = CreateTimer()
call TimerStart(T, 0.031250000, true, function LockCam)
endfunction
private function Init takes nothing returns nothing
call SetupHeroPickSystem()
endfunction
endlibrary
//TESH.scrollpos=159
//TESH.alwaysfold=0
library HeroStatsMultiboard
globals
multiboard MB = null
multiboarditem mbitem = null
integer array HERO_ATTRIBUTE
string array HERO_ATTRIBUTE_NAME
string array color
endglobals
function UpdateMBItem takes integer i, integer j, string s returns nothing
set mbitem = MultiboardGetItem(MB, i, j)
call MultiboardSetItemValue(mbitem, s)
call MultiboardReleaseItem(mbitem)
endfunction
function UpdateMB takes nothing returns nothing
call UpdateMBItem( 1, 1, I2S(HERO_ATTRIBUTE[1]))
call UpdateMBItem( 2, 1, I2S(HERO_ATTRIBUTE[2]))
call UpdateMBItem( 3, 1, I2S(HERO_ATTRIBUTE[3]))
call UpdateMBItem( 4, 1, I2S(HERO_ATTRIBUTE[4]))
call UpdateMBItem( 6, 1, I2S(HERO_ATTRIBUTE[6]))
call UpdateMBItem( 7, 1, I2S(HERO_ATTRIBUTE[7]))
call UpdateMBItem( 8, 1, I2S(HERO_ATTRIBUTE[8]))
call UpdateMBItem( 9, 1, I2S(HERO_ATTRIBUTE[9]))
call UpdateMBItem( 11, 1, I2S(HERO_ATTRIBUTE[11]))
call UpdateMBItem( 12, 1, I2S(HERO_ATTRIBUTE[12]))
call UpdateMBItem( 13, 1, I2S(HERO_ATTRIBUTE[13]))
call UpdateMBItem( 14, 1, I2S(HERO_ATTRIBUTE[14]))
call UpdateMBItem( 1, 3, "|c00FEBA0E" + R2SW(Unit[HERO].criticalChance,2,2) + "%")
call UpdateMBItem( 2, 3, "|c00FEBA0E" + R2SW(Unit[HERO].criticalMultiplier,2,2) + "x")
call UpdateMBItem( 3, 3, "|c00FEBA0E" + R2SW(Unit[HERO].bashChance,2,2) + "%")
call UpdateMBItem( 4, 3, "|c00FEBA0E" + R2SW(Unit[HERO].bashDuration,2,2) + "s")
call UpdateMBItem( 5, 3, "|c00FEBA0E" + R2SW(Unit[HERO].reflectChance,2,2) + "%")
call UpdateMBItem( 6, 3, "|c00FEBA0E" + R2SW(Unit[HERO].reflectPercent,2,2) + "%")
call UpdateMBItem( 7, 3, "|c00FEBA0E" + R2SW(Unit[HERO].evasion,2,2) + "%")
call UpdateMBItem( 8, 3, "|c00FEBA0E" + R2SW(Unit[HERO].spellCriticalChance,2,2) + "%")
call UpdateMBItem( 9, 3, "|c00FEBA0E" + R2SW(Unit[HERO].spellCriticalMultiplier,2,2) + "x")
call UpdateMBItem( 10, 3, "|c00FEBA0E" + R2SW(Unit[HERO].spellPower,2,2))
call UpdateMBItem( 1, 4, R2SW(Unit[PET].criticalChance,2,2) + "%")
call UpdateMBItem( 2, 4, R2SW(Unit[PET].criticalMultiplier,2,2) + "x")
call UpdateMBItem( 3, 4, R2SW(Unit[PET].bashChance,2,2) + "%")
call UpdateMBItem( 4, 4, R2SW(Unit[PET].bashDuration,2,2) + "s")
call UpdateMBItem( 5, 4, R2SW(Unit[PET].reflectChance,2,2) + "%")
call UpdateMBItem( 6, 4, R2SW(Unit[PET].reflectPercent,2,2) + "%")
call UpdateMBItem( 7, 4, R2SW(Unit[PET].evasion,2,2) + "%")
call UpdateMBItem( 8, 4, R2SW(Unit[PET].spellCriticalChance,2,2) + "%")
call UpdateMBItem( 9, 4, R2SW(Unit[PET].spellCriticalMultiplier,2,2) + "x")
call UpdateMBItem( 10, 4, R2SW(Unit[PET].spellPower,2,2))
call UpdateMBItem( 1, 6, "|c00FEBA0E" + R2SW(Unit[HERO].fireDamage,2,2))
call UpdateMBItem( 2, 6, "|c00FEBA0E" + R2SW(Unit[HERO].fireResistance * 100,2,2) + "%")
call UpdateMBItem( 3, 6, "|c00FEBA0E" + R2SW(Unit[HERO].coldDamage,2,2))
call UpdateMBItem( 4, 6, "|c00FEBA0E" + R2SW(Unit[HERO].coldResistance * 100,2,2) + "%")
call UpdateMBItem( 5, 6, "|c00FEBA0E" + R2SW(Unit[HERO].lightningDamage,2,2))
call UpdateMBItem( 6, 6, "|c00FEBA0E" + R2SW(Unit[HERO].lightningResistance * 100,2,2) + "%")
call UpdateMBItem( 7, 6, "|c00FEBA0E" + R2SW(Unit[HERO].poisonDamage,2,2))
call UpdateMBItem( 8, 6, "|c00FEBA0E" + R2SW(Unit[HERO].poisonResistance * 100,2,2) + "%")
call UpdateMBItem( 1, 7, R2SW(Unit[PET].fireDamage,2,2))
call UpdateMBItem( 2, 7, R2SW(Unit[PET].fireResistance * 100,2,2) + "%")
call UpdateMBItem( 3, 7, R2SW(Unit[PET].coldDamage,2,2))
call UpdateMBItem( 4, 7, R2SW(Unit[PET].coldResistance * 100,2,2) + "%")
call UpdateMBItem( 5, 7, R2SW(Unit[PET].lightningDamage,2,2))
call UpdateMBItem( 6, 7, R2SW(Unit[PET].lightningResistance * 100,2,2) + "%")
call UpdateMBItem( 7, 7, R2SW(Unit[PET].poisonDamage,2,2))
call UpdateMBItem( 8, 7, R2SW(Unit[PET].poisonResistance * 100,2,2) + "%")
endfunction
private function SetMainAttribute takes integer i1, integer i2, integer i3, integer i4 returns nothing
set color[i1] = "|c00FEBA0E"
set color[i2] = "|c00FEBA0E"
set color[i3] = "|c00FEBA0E"
set color[i4] = "|c00FEBA0E"
set HERO_ATTRIBUTE[i1] = 25
set HERO_ATTRIBUTE[i2] = 25
set HERO_ATTRIBUTE[i3] = 25
set HERO_ATTRIBUTE[i4] = 25
endfunction
function SaveMBItem takes integer i, integer j, string s, boolean b, real size, string icon returns nothing
set mbitem = MultiboardGetItem(MB, i, j)
call MultiboardSetItemValue(mbitem, s)
call MultiboardSetItemStyle(mbitem, true, b)
if b then
call MultiboardSetItemIcon(mbitem, icon)
endif
call MultiboardSetItemWidth(mbitem, size/100.0)
call MultiboardReleaseItem(mbitem)
endfunction
function SetupHeroStatsMultiboard takes nothing returns nothing
local integer i
//
// Core
//
set MB = CreateMultiboard()
call MultiboardSetRowCount(MB, 15)
call MultiboardSetColumnCount(MB, 9)
call MultiboardSetTitleText(MB, "Hero Stats")
call MultiboardDisplay(MB, true)
call MultiboardMinimize(MB, true)
set i = 0
loop
call SaveMBItem( i, 0, "", true , 15, "")
call SaveMBItem( i, 1, "", false , 5 , "")
call SaveMBItem( i, 2, "", true , 15, "")
call SaveMBItem( i, 3, "", false , 5 , "")
call SaveMBItem( i, 4, "", false , 5 , "")
call SaveMBItem( i, 5, "", true , 15, "")
call SaveMBItem( i, 6, "", false , 5 , "")
call SaveMBItem( i, 7, "", false , 5 , "")
call SaveMBItem( i, 8, "", false , 20, "")
set i = i + 1
exitwhen i > 14
endloop
//
// Attributes
//
set HERO_ATTRIBUTE[ 1] = 10
set HERO_ATTRIBUTE[ 2] = 10
set HERO_ATTRIBUTE[ 3] = 10
set HERO_ATTRIBUTE[ 4] = 10
set HERO_ATTRIBUTE[ 6] = 10
set HERO_ATTRIBUTE[ 7] = 10
set HERO_ATTRIBUTE[ 8] = 10
set HERO_ATTRIBUTE[ 9] = 10
set HERO_ATTRIBUTE[11] = 10
set HERO_ATTRIBUTE[12] = 10
set HERO_ATTRIBUTE[13] = 10
set HERO_ATTRIBUTE[14] = 10
if HERO_CLASS == 1 then
call SetMainAttribute( 6, 7, 8, 9)
elseif HERO_CLASS == 2 then
call SetMainAttribute(11,12,13,14)
elseif HERO_CLASS == 3 then
call SetMainAttribute( 7, 8,11,12)
elseif HERO_CLASS == 4 then
call SetMainAttribute( 1, 2, 3, 4)
elseif HERO_CLASS == 5 then
call SetMainAttribute( 3, 6,13,14)
elseif HERO_CLASS == 6 then
call SetMainAttribute( 6, 8, 9,12)
elseif HERO_CLASS == 7 then
call SetMainAttribute( 3, 7,13,14)
elseif HERO_CLASS == 8 then
call SetMainAttribute( 6, 9,11,12)
elseif HERO_CLASS == 9 then
call SetMainAttribute( 1, 3, 6, 9)
elseif HERO_CLASS == 10 then
call SetMainAttribute( 2, 3, 4,12)
endif
call SaveMBItem( 0, 0, TXTC[6] + "Agility Based Attributes:", false, 15, "")
call SaveMBItem( 1, 0, color[1] + "Athletic:" , true, 15, "war3mapImported\\PASBootsOfSpeed.blp")
call SaveMBItem( 2, 0, color[2] + "Acrobatics:", true, 15, "war3mapImported\\PASBanish.blp")
call SaveMBItem( 3, 0, color[3] + "Marksmanship:", true, 15, "war3mapImported\\PASImprovedBows.blp")
call SaveMBItem( 4, 0, color[4] + "Light Armor:", true, 15, "war3mapImported\\PASHoodOfCunning.blp")
call SaveMBItem( 5, 0, TXTC[0] + "Strength Based Attributes:", false, 15, "")
call SaveMBItem( 6, 0, color[6] + "Blade:", true, 15, "war3mapImported\\PASArcaniteMelee.blp")
call SaveMBItem( 7, 0, color[7] + "Blunt:", true, 15, "war3mapImported\\PASOrcMeleeUpThree.blp")
call SaveMBItem( 8, 0, color[8] + "Heavy Armor:", true, 15, "ReplaceableTextures\\PassiveButtons\\PASBTNUnholyAura.blp")
call SaveMBItem( 9, 0, color[9] + "Block:", true, 15, "war3mapImported\\PASHumanArmorUpThree.blp")
call SaveMBItem( 10, 0, TXTC[1] + "Intelligence Based Attributes:", false, 15, "")
call SaveMBItem( 11, 0, color[11] + "Restoration:", true, 15, "war3mapImported\\PASStaffOfNegation.blp")
call SaveMBItem( 12, 0, color[12] + "Scholarship:", true, 15, "ReplaceableTextures\\PassiveButtons\\PASBTNMagicalSentry.blp")
call SaveMBItem( 13, 0, color[13] + "Destruction:", true, 15, "war3mapImported\\PASChainLightning.blp")
call SaveMBItem( 14, 0, color[14] + "Mysticism:", true, 15, "war3mapImported\\PASDarkRitual.blp")
set HERO_ATTRIBUTE_NAME[1] = color[1] +"Athletic"
set HERO_ATTRIBUTE_NAME[2] = color[2] +"Acrobatics"
set HERO_ATTRIBUTE_NAME[3] = color[3] +"Marksmanship"
set HERO_ATTRIBUTE_NAME[4] = color[4] +"Light Armor"
set HERO_ATTRIBUTE_NAME[6] = color[6] +"Blade"
set HERO_ATTRIBUTE_NAME[7] = color[7] +"Blunt"
set HERO_ATTRIBUTE_NAME[8] = color[8] +"Heavy Armor"
set HERO_ATTRIBUTE_NAME[9] = color[9] +"Block"
set HERO_ATTRIBUTE_NAME[11] = color[11] +"Restoration"
set HERO_ATTRIBUTE_NAME[12] = color[12] +"Scholarship"
set HERO_ATTRIBUTE_NAME[13] = color[13] +"Destruction"
set HERO_ATTRIBUTE_NAME[14] = color[14] +"Mysticism"
//
// Stats
//
call SaveMBItem( 0, 2, "", false, 15, "")
call SaveMBItem( 1, 2, "Critical Strike Chance:", true, 15, "war3mapImported\\PASSteelMelee.blp")
call SaveMBItem( 2, 2, "Critical Strike Multiplier:", true, 15, "war3mapImported\\PASThoriumMelee.blp")
call SaveMBItem( 3, 2, "Bash Strike Chance:", true, 15, "war3mapImported\\PASOrcMeleeUpOne.blp")
call SaveMBItem( 4, 2, "Bash Strike Duration:", true, 15, "war3mapImported\\PASOrcMeleeUpTwo.blp")
call SaveMBItem( 5, 2, "Reflection Chance:", true, 15, "war3mapImported\\PASSteelArmor.blp")
call SaveMBItem( 6, 2, "Reflection Value:", true, 15, "war3mapImported\\PASThoriumArmor.blp")
call SaveMBItem( 7, 2, "Dodge Chance:", true, 15, "war3mapImported\\PASQuillSprayOff.blp")
call SaveMBItem( 8, 2, "Spell Critical Strike Chance:", true, 15, "war3mapImported\\PASStrengthOfTheMoon.blp")
call SaveMBItem( 9, 2, "Spell Critical Strike Multiplier:", true, 15, "war3mapImported\\PASAdvancedStrengthOfTheMoon.blp")
call SaveMBItem( 10, 2, "Spellpower:", true, 15, "ReplaceableTextures\\PassiveButtons\\PASBTNBrilliance.blp")
call SaveMBItem( 11, 2, "", false, 15, "")
call SaveMBItem( 12, 2, "", false, 15, "")
call SaveMBItem( 13, 2, "Experience Rate:", true, 15, "ReplaceableTextures\\PassiveButtons\\PASBTNRegenerationAura.blp")
call SaveMBItem( 14, 2, "Luck:", true, 15, "ReplaceableTextures\\PassiveButtons\\PASBTNScatterRockets.blp")
call SaveMBItem( 0, 5, "", false, 15, "")
call SaveMBItem( 1, 5, "Fire Damage Bonus:", true, 15, "war3mapImported\\PASOrbOfFire.blp")
call SaveMBItem( 2, 5, "Fire Resistance:", true, 15, "war3mapImported\\PASSnazzyScrollRed.blp")
call SaveMBItem( 3, 5, "Cold Damage Bonus:", true, 15, "war3mapImported\\PASOrbOfFrost.blp")
call SaveMBItem( 4, 5, "Cold Resistance:", true, 15, "war3mapImported\\PASSnazzyScrollBlue.blp")
call SaveMBItem( 5, 5, "Lightning Damage Bonus:", true, 15, "war3mapImported\\PASOrbOfLightning.blp")
call SaveMBItem( 6, 5, "Lightning Resistance:", true, 15, "war3mapImported\\PASSnazzyScroll.blp")
call SaveMBItem( 7, 5, "Poison Damage Bonus:", true, 15, "war3mapImported\\PASOrbOfVenom.blp")
call SaveMBItem( 8, 5, "Poison Resistance:", true, 15, "war3mapImported\\PASSnazzyScrollGreen.blp")
call SaveMBItem( 9, 5, "", false, 15, "")
call SaveMBItem( 10, 5, "", false, 15, "")
call SaveMBItem( 11, 5, "", false, 15, "")
call SaveMBItem( 12, 5, "", false, 15, "")
call SaveMBItem( 13, 5, "", false, 15, "")
call SaveMBItem( 14, 5, "", false, 15, "")
call UpdateMBItem( 13, 3, "|c00FEBA0E100.00%")
call UpdateMBItem( 14, 3, "|c00FEBA0E100.00%")
call UpdateMBItem( 0, 3, "|c00FEBA0EHero")
call UpdateMBItem( 0, 4, "Pet")
call UpdateMBItem( 0, 6, "|c00FEBA0EHero")
call UpdateMBItem( 0, 7, "Pet")
call Unit[HERO].setResistance(0,0,0,0)
call Unit[HERO].setDamage(0,0,0,0)
call Unit[HERO].setBash(5,0.8)
call Unit[HERO].setCritical(5,1.25)
call Unit[HERO].setSpellCritical(5,1.25)
call Unit[HERO].setReflect(0,0)
call Unit[HERO].setEvasion(5)
call Unit[HERO].setSpellPower(10)
call TimerStart(CreateTimer(), 1.00, true, function UpdateMB)
endfunction
endlibrary
//TESH.scrollpos=487
//TESH.alwaysfold=0
//! textmacro RegisterItems
/***********************************
* Shadows of the Past ItemLib *
* *
* Total Items: 50 *
* Total Item Classes: 9 *
* Total Abilities: 2 *
* *
************************************/
globals
hashtable ITEM_HASH = InitHashtable()
private constant string G = "|cffffcc00" //Gold
private constant string S = "|cffc3dbff" //Silver
private constant string W = "|c00FFFFFF" //White
constant integer ITEM_CLASS_LHAND = 1
constant integer ITEM_CLASS_RHAND = 2
constant integer ITEM_CLASS_RING = 3
constant integer ITEM_CLASS_GLOVE = 4
constant integer ITEM_CLASS_BOOTS = 5
constant integer ITEM_CLASS_TORSO = 6
constant integer ITEM_CLASS_HEAD = 7
constant integer ITEM_CLASS_AMULET = 8
constant integer ITEM_CLASS_BHAND = 9
constant integer ITEM_CLASS_PET_ORB = 10
constant integer ITEM_CLASS_PET_AMULET = 11
constant integer ITEM_CLASS_PET_BELT = 12
constant integer ITEM_CLASS_FOOD = 50
constant integer ITEM_CLASS_ABILITY = 99
constant integer ITEM_ANIM_NONE = 0
constant integer ITEM_ANIM_SWORD = 1
constant integer ITEM_ANIM_BOW = 2
constant integer ITEM_ANIM_AXE = 3
constant integer ITEM_ANIM_STAFF = 4
constant integer ITEM_CATEGORY_COMMON = 0
constant integer ITEM_CATEGORY_UNCOMMON = 1
constant integer ITEM_CATEGORY_RARE = 2
constant integer ITEM_CATEGORY_UNIQUE = 3
constant integer ITEM_CATEGORY_LEGENDARY = 4
string array ITEM_CATEGORY
endglobals
private function SaveItem takes integer item_id, integer dest_id, integer class, integer hand, string msg returns nothing
call SaveInteger(ITEM_HASH, item_id, 0, class )
call SaveInteger(ITEM_HASH, item_id, 1, dest_id)
call SaveInteger(ITEM_HASH, dest_id, 0, class )
call SaveInteger(ITEM_HASH, dest_id, 1, item_id)
call SaveInteger(ITEM_HASH, dest_id, 99, hand )
call SaveStr( ITEM_HASH, dest_id, 2, msg )
endfunction
private function SaveAbility takes integer dest_id, integer Q, integer W, integer E, integer R returns nothing
call SaveInteger(ITEM_HASH, dest_id, 11, Q )
call SaveInteger(ITEM_HASH, dest_id, 12, W )
call SaveInteger(ITEM_HASH, dest_id, 13, E )
call SaveInteger(ITEM_HASH, dest_id, 14, R )
endfunction
private function SaveFood takes integer id, integer Key, real mana, real life, integer food returns nothing
call SaveInteger(ITEM_HASH, id, 0, Key) //Food
call SaveReal( ITEM_HASH, id, 1, mana) //Mana Bonus
call SaveReal( ITEM_HASH, id, 2, life) //Life Bonus
call SaveInteger(ITEM_HASH, id, 3, food) //Food
endfunction
private function Mix takes integer id, string title, string class, string bonus, string speed returns string
if speed == "" then
return W + title + "|r\n(" + ITEM_CATEGORY[id] + ")\n\nClass:\n" + S + class + "|r\n\nDescription:\n" + S + bonus
endif
return W + title + "|r\n(" + ITEM_CATEGORY[id] + ")\n\nClass:\n" + S + class + "|r\n\nDescription:\n" + S + bonus + "|r\n\nSpeed:\n" + S + speed
endfunction
function SetupItemSystem takes nothing returns nothing
set ITEM_CATEGORY[ITEM_CATEGORY_COMMON] = "|c00FFFFFFCommon" // White
set ITEM_CATEGORY[ITEM_CATEGORY_UNCOMMON] = "|c0080FFFFUncommon|r" // Cyan
set ITEM_CATEGORY[ITEM_CATEGORY_RARE] = "|c0020C000Rare|r" // Green
set ITEM_CATEGORY[ITEM_CATEGORY_UNIQUE] = "|c008000FFUnique|r" // Purple
set ITEM_CATEGORY[ITEM_CATEGORY_LEGENDARY] = "|c00FF00FFLegendary|r" // Pink
/*********************
* FOOD ITEMS *
**********************/
// ID Key mana - life - food
call SaveFood('I01P', ITEM_CLASS_FOOD, 19. , 36. , 10 ) //Barbecued Ribs
call SaveFood('I01H', ITEM_CLASS_FOOD, 10. , 10. , 6 ) //Cheese
call SaveFood('I01D', ITEM_CLASS_FOOD, 23. , 24. , 8 ) //Cut Cheese Roll
call SaveFood('I01F', ITEM_CLASS_FOOD, 13. , 16. , 4 ) //Fresh Piece of Cheese
call SaveFood('I01R', ITEM_CLASS_FOOD, 0. , 19. , 6 ) //Fried Chicken Leg
call SaveFood('I01U', ITEM_CLASS_FOOD, 7. , 5. , 2 ) //Green Apple
call SaveFood('I01X', ITEM_CLASS_FOOD, 20. , 20. , 10 ) //Homemade Baked Bread
call SaveFood('I01K', ITEM_CLASS_FOOD, 37. , 37. , 12 ) //Homemade Raspberry Pie
call SaveFood('I01M', ITEM_CLASS_FOOD, 3. , 41. , 10 ) //Meat Loaf
call SaveFood('I01W', ITEM_CLASS_FOOD, 70. , 13. , 12 ) //Pumpkin
call SaveFood('I01S', ITEM_CLASS_FOOD, 9. , 3. , 2 ) //Ripe Red Apple
call SaveFood('I01O', ITEM_CLASS_FOOD, 0. , 135. , 14 ) //Roasted Chicken
call SaveFood('I01T', ITEM_CLASS_FOOD, 8. , 2. , 2 ) //Rotten Wormy Apple
call SaveFood('I01Y', ITEM_CLASS_FOOD, 20. , 27. , 10 ) //Rye-Baked Sliced Bread
call SaveFood('I01Q', ITEM_CLASS_FOOD, 0. , 105. , 12 ) //Sasuage Chain
call SaveFood('I01E', ITEM_CLASS_FOOD, 5. , 5. , 2 ) //Small Cheese Slice
call SaveFood('I01N', ITEM_CLASS_FOOD, 23. , 29. , 8 ) //Smoked Stake
call SaveFood('I01J', ITEM_CLASS_FOOD, 30. , 0. , 4 ) //Stale Bread Slice
call SaveFood('I01G', ITEM_CLASS_FOOD, 16. , 16. , 4 ) //Stale Moldy Cheese
call SaveFood('I01I', ITEM_CLASS_FOOD, 5. , 25. , 6 ) //The "X" Mini-Bread
call SaveFood('I01V', ITEM_CLASS_FOOD, 35. , 10. , 6 ) //Watermelon
/*********************
* ITEM_CLASS_LHAND *
**********************/
/* COMMON ITEM */ /* Damaged Iron Sword */
call SaveItem('I00D', 'B02V', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Damaged Iron Sword", "One Handed Sword", "+12 Attack Power", "Fast"))
call ItemBonus['I00D'].saveStats( 0, 0, 0, 12, 0, 0, 0, 0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I00D'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00D'].saveEffect( 0,"war3mapImported\\SwordShort.mdl", "left hand")
/* COMMON ITEM */ /* Rusty Iron Sword */
call SaveItem('I00E', 'B02A', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Rusty Iron Sword", "One Handed Sword", "+14 Attack Power", "Fast"))
call ItemBonus['I00E'].saveStats( 0, 0, 0, 14, 0, 0, 0, 0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I00E'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00E'].saveEffect( 0,"war3mapImported\\SwordShort.mdl", "left hand")
/* COMMON ITEM */ /* Iron Sword */
call SaveItem('I000', 'B02B', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Iron Sword", "One Handed Sword", "+16 Attack Power", "Fast"))
call ItemBonus['I000'].saveStats( 0, 0, 0, 16, 0, 0, 0, 0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I000'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I000'].saveEffect( 0,"war3mapImported\\SwordShort.mdl", "left hand")
/* COMMON ITEM */ /* Fine Iron Sword */
call SaveItem('I00F', 'B02C', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Fine Iron Sword", "One Handed Sword", "+18 Attack Power", "Fast"))
call ItemBonus['I00F'].saveStats( 0, 0, 0, 18, 0, 0, 0, 0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I00F'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00F'].saveEffect( 0,"war3mapImported\\SwordShort.mdl", "left hand")
/* COMMON ITEM */ /* Perfect Iron Sword */
call SaveItem('I01A', 'B02R', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Perfect Iron Sword", "One Handed Sword", "+20 Attack Power", "Fast"))
call ItemBonus['I01A'].saveStats( 0, 0, 0, 20, 0, 0, 0, 0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I01A'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I01A'].saveEffect( 0,"war3mapImported\\SwordShort.mdl", "left hand")
/* COMMON ITEM */ /* Damaged Iron Dagger */
call SaveItem('I01C', 'B02Y', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Damaged Iron Dagger", "One Handed Sword", "+6 Attack Power", "Fast"))
call ItemBonus['I01C'].saveStats( 0, 0, 0, 6, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I01C'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I01C'].saveEffect( 0,"war3mapImported\\DaggerCombatKnife.mdl", "left hand")
/* COMMON ITEM */ /* Rusty Iron Dagger */
call SaveItem('I01L', 'B03O', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Rusty Iron Dagger", "One Handed Sword", "+7 Attack Power", "Fast"))
call ItemBonus['I01L'].saveStats( 0, 0, 0, 7, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I01L'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I01L'].saveEffect( 0,"war3mapImported\\DaggerCombatKnife.mdl", "left hand")
/* COMMON ITEM */ /* Iron Dagger */
call SaveItem('I01Z', 'B030', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Iron Dagger", "One Handed Sword", "+8 Attack Power", "Fast"))
call ItemBonus['I01Z'].saveStats( 0, 0, 0, 8, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I01Z'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I01Z'].saveEffect( 0,"war3mapImported\\DaggerCombatKnife.mdl", "left hand")
/* COMMON ITEM */ /* Fine Iron Dagger */
call SaveItem('I020', 'B031', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Fine Iron Dagger", "One Handed Sword", "+9 Attack Power", "Fast"))
call ItemBonus['I020'].saveStats( 0, 0, 0, 9, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I020'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I020'].saveEffect( 0,"war3mapImported\\DaggerCombatKnife.mdl", "left hand")
/* COMMON ITEM */ /* Perfect Iron Dagger */
call SaveItem('I028', 'B032', ITEM_CLASS_LHAND, ITEM_ANIM_SWORD, Mix(ITEM_CATEGORY_COMMON, "Perfect Iron Dagger", "One Handed Sword", "+10 Attack Power", "Fast"))
call ItemBonus['I028'].saveStats( 0, 0, 0, 10, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I028'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I028'].saveEffect( 0,"war3mapImported\\DaggerCombatKnife.mdl", "left hand")
/*********************
* ITEM_CLASS_RING *
**********************/
/* Ring of Power */
call SaveItem('I021', 'B03Y', ITEM_CLASS_RING, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Ring of Power", "Ring", "+1 to All Attributes |n+6 Damage |n+2 Defense", ""))
call ItemBonus['I021'].saveStats( 1, 1, 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I021'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I021'].saveEffect( 0,"", "")
/* Ring of Superiority */
call SaveItem('I035', 'B047', ITEM_CLASS_RING, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Ring of Superiority", "Ring", "+3 to All Attributes |n+17 Damage |n+6 Defense", ""))
call ItemBonus['I035'].saveStats( 3, 3, 3, 17, 6, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I035'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I035'].saveEffect( 0,"", "")
/* Dryad Ring */
call SaveItem('I038', 'B048', ITEM_CLASS_RING, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Dryad Ring", "Ring", "+76 Life |n+1% Life Regeneration", ""))
call ItemBonus['I038'].saveStats( 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 1, 0)
//call ItemBonus['I038'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I038'].saveEffect( 0,"", "")
/* Jade Ring */
call SaveItem('I039', 'B049', ITEM_CLASS_RING, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Jade Ring", "Ring", "+1 Cold Damage |n+10 Cold Resistance", ""))
//call ItemBonus['I039'].saveStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I039'].saveDamageStats( 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I039'].saveEffect( 0,"", "")
/* Spider Ring */
call SaveItem('I03A', 'B04A', ITEM_CLASS_RING, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Spider Ring", "Ring", "+6 Poison Damage", ""))
//call ItemBonus['I03A'].saveStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03A'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0)
//call ItemBonus['I03A'].saveEffect( 0,"", "")
/*********************
* ITEM_CLASS_TORSO *
**********************/
/* Damaged Iron Curiass */
call SaveItem('I02D', 'B034', ITEM_CLASS_TORSO, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Damaged Iron Curiass", "Body Armor", "+6 Defense", ""))
call ItemBonus['I02D'].saveStats( 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I02D'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I02D'].saveEffect( 0,"war3mapImported\\Armor10.mdx", "chest")
/* Rusty Iron Curiass */
call SaveItem('I007', 'B033', ITEM_CLASS_TORSO, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Rusty Iron Curiass", "Body Armor", "+7 Defense", ""))
call ItemBonus['I007'].saveStats( 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I007'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I007'].saveEffect( 0,"war3mapImported\\Armor10.mdx", "chest")
/* Iron Curiass */
call SaveItem('I004', 'B036', ITEM_CLASS_TORSO, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Iron Curiass", "Body Armor", "+8 Defense", ""))
call ItemBonus['I004'].saveStats( 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I004'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I004'].saveEffect( 0,"war3mapImported\\Armor10.mdx", "chest")
/* Fine Iron Curiass */
call SaveItem('I003', 'B035', ITEM_CLASS_TORSO, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Fine Iron Curiass", "Body Armor", "+9 Defense", ""))
call ItemBonus['I003'].saveStats( 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I003'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I003'].saveEffect( 0,"war3mapImported\\Armor10.mdx", "chest")
/* Perfect Iron Curiass */
call SaveItem('I02E', 'B02W', ITEM_CLASS_TORSO, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Perfect Iron Curiass", "Body Armor", "+10 Defense", ""))
call ItemBonus['I02E'].saveStats( 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I02E'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I02E'].saveEffect( 0,"war3mapImported\\Armor10.mdx", "chest")
/*********************
* ITEM_CLASS_RHAND *
**********************/
/* Damaged Iron Shield */
call SaveItem('I00A', 'B039', ITEM_CLASS_RHAND, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Damaged Iron Shield", "Shield", "+1 Defense", ""))
call ItemBonus['I00A'].saveStats( 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I00A'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00A'].saveEffect( 0,"war3mapImported\\ShieldBuckler.mdx", "right hand")
/* Rusty Iron Shield */
call SaveItem('I006', 'B03A', ITEM_CLASS_RHAND, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Rusty Iron Shield", "Shield", "+2 Defense", ""))
call ItemBonus['I006'].saveStats( 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I006'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I006'].saveEffect( 0,"war3mapImported\\ShieldBuckler.mdx", "right hand")
/* Iron Shield */
call SaveItem('I009', 'B037', ITEM_CLASS_RHAND, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Iron Shield", "Shield", "+3 Defense", ""))
call ItemBonus['I009'].saveStats( 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I009'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I009'].saveEffect( 0,"war3mapImported\\ShieldBuckler.mdx", "right hand")
/* Fine Iron Shield */
call SaveItem('I008', 'B038', ITEM_CLASS_RHAND, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Fine Iron Shield", "Shield", "+4 Defense", ""))
call ItemBonus['I008'].saveStats( 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I008'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I008'].saveEffect( 0,"war3mapImported\\ShieldBuckler.mdx", "right hand")
/* Superb Iron Shield */
call SaveItem('I00B', 'B02T', ITEM_CLASS_RHAND, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Superb Iron Shield", "Shield", "+5 Defense", ""))
call ItemBonus['I00B'].saveStats( 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I00B'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00B'].saveEffect( 0,"war3mapImported\\ShieldBuckler.mdx", "right hand")
/*********************
* ITEM_CLASS_HEAD *
**********************/
/* Damaged Apprentice Hat */
call SaveItem('I03B', 'B04B', ITEM_CLASS_HEAD, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Damaged Apprentice Hat", "Head", "+1 Defense", ""))
call ItemBonus['I03B'].saveStats( 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03B'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03B'].saveEffect( 0,"war3mapImported\\HelmBlueHat.mdl", "head")
/* Crude Apprentice Hat */
call SaveItem('I03C', 'B04C', ITEM_CLASS_HEAD, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Crude Apprentice Hat", "Head", "+2 Defense", ""))
call ItemBonus['I03C'].saveStats( 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03C'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03C'].saveEffect( 0,"war3mapImported\\HelmBlueHat.mdl", "head")
/* Apprentice Hat */
call SaveItem('I03D', 'B04D', ITEM_CLASS_HEAD, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Apprentice Hat", "Head", "+3 Defense", ""))
call ItemBonus['I03D'].saveStats( 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03D'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03D'].saveEffect( 0,"war3mapImported\\HelmBlueHat.mdl", "head")
/* Fine Apprentice Hat */
call SaveItem('I03E', 'B04E', ITEM_CLASS_HEAD, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Fine Apprentice Hat", "Head", "+4 Defense", ""))
call ItemBonus['I03E'].saveStats( 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03E'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03E'].saveEffect( 0,"war3mapImported\\HelmBlueHat.mdl", "head")
/* Perfect Apprentice Hat */
call SaveItem('I03F', 'B04F', ITEM_CLASS_HEAD, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Perfect Apprentice Hat", "Head", "+5 Defense", ""))
call ItemBonus['I03F'].saveStats( 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03F'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03F'].saveEffect( 0,"war3mapImported\\HelmBlueHat.mdl", "head")
/*********************
* ITEM_CLASS_AMULET *
**********************/
/* Amulet of Valor */
call SaveItem('I03G', 'B04G', ITEM_CLASS_AMULET, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Amulet of Valor", "Amulet", "+8 Attack Power |n+3 Defense |n+25 Hit Points |n+10% Attack Speed", ""))
call ItemBonus['I03G'].saveStats( 0, 0, 0, 8, 3, 25, 0, 0.10, 0, 0, 0, 0, 0)
//call ItemBonus['I03G'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03G'].saveEffect( 0,"", "")
/* Medallion of Courage */
call SaveItem('I03H', 'B04H', ITEM_CLASS_AMULET, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Medallion of Couraget", "Amulet", "+8 Strength |n+4 Agility |n+4 Intelligence |n+10% Evasion", ""))
call ItemBonus['I03H'].saveStats( 8, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03H'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0)
//call ItemBonus['I03H'].saveEffect( 0,"", "")
/* Arcane Talisman */
call SaveItem('I03I', 'B04I', ITEM_CLASS_AMULET, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Arcane Talisman", "Amulet", "+75 Mana Points |n+75% Mana Regeneration", ""))
call ItemBonus['I03I'].saveStats( 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 75)
//call ItemBonus['I03I'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03I'].saveEffect( 0,"", "")
/* Necklace of Storms */
call SaveItem('I03J', 'B04J', ITEM_CLASS_AMULET, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Necklace of Storms", "Amulet", "+15 Lightning Damage", ""))
//call ItemBonus['I03J'].saveStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03J'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03J'].saveEffect( 0,"", "")
/* Jade Amulet */
call SaveItem('I03L', 'B04K', ITEM_CLASS_AMULET, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Jade Amulet", "Amulet", "+2 Cold Damage |n+15 Cold Resistance", ""))
//call ItemBonus['I03L'].saveStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03L'].saveDamageStats( 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03L'].saveEffect( 0,"", "")
/* UNIQUE ITEM */ /* Necklace of the Fallen Star */
call SaveItem('I03X', 'B04M', ITEM_CLASS_AMULET, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_UNIQUE, "Necklace of the Fallen Star", "Amulet", "+22 Strength |n+16 Agility |n+46 Intelligence |n+367 Life Points |n +186 Mana Points |n+3 Life Regeneration |n+2 Mana Regeneration |n+27% Fire Damage Resistance |n+34% Cold Damage Resistance", ""))
call ItemBonus['I03X'].saveStats( 22, 46, 16, 0, 0,367,186, 0, 0, 3, 2, 0, 0)
call ItemBonus['I03X'].saveDamageStats( 0, 0, 0, 0, 0, 27, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03X'].saveEffect( 0,"", "")
/*********************
* ITEM_CLASS_GLOVE *
**********************/
/*********************
* ITEM_CLASS_BOOTS *
**********************/
/*********************
* ITEM_CLASS_BHAND *
**********************/
/* Damaged Iron Claymore */
call SaveItem('I00K', 'B03C', ITEM_CLASS_BHAND, ITEM_ANIM_AXE, Mix(ITEM_CATEGORY_COMMON, "Damaged Iron Claymore", "Claymore", "+30 Attack Power", "Slow"))
call ItemBonus['I00K'].saveStats( 0, 0, 0, 30, 0, 0, 0,-0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I00K'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00K'].saveEffect( 0,"war3mapImported\\SwordMetalBlade.mdx", "right hand")
/* Rusty Iron Claymore */
call SaveItem('I001', 'B03B', ITEM_CLASS_BHAND, ITEM_ANIM_AXE, Mix(ITEM_CATEGORY_COMMON, "Rusty Iron Claymore", "Claymore", "+35 Attack Power", "Slow"))
call ItemBonus['I001'].saveStats( 0, 0, 0, 35, 0, 0, 0,-0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I001'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I001'].saveEffect( 0,"war3mapImported\\SwordMetalBlade.mdx", "right hand")
/* Iron Claymore */
call SaveItem('I00N', 'B02U', ITEM_CLASS_BHAND, ITEM_ANIM_AXE, Mix(ITEM_CATEGORY_COMMON, "Iron Claymore", "Claymore", "+40 Attack Power", "Slow"))
call ItemBonus['I00N'].saveStats( 0, 0, 0, 40, 0, 0, 0,-0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I00N'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00N'].saveEffect( 0,"war3mapImported\\SwordMetalBlade.mdx", "right hand")
/* Fine Iron Claymore */
call SaveItem('I00L', 'B03D', ITEM_CLASS_BHAND, ITEM_ANIM_AXE, Mix(ITEM_CATEGORY_COMMON, "Fine Iron Claymore", "Claymore", "+45 Attack Power", "Slow"))
call ItemBonus['I00L'].saveStats( 0, 0, 0, 45, 0, 0, 0,-0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I00L'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00L'].saveEffect( 0,"war3mapImported\\SwordMetalBlade.mdx", "right hand")
/* Perfect Iron Claymore */
call SaveItem('I00M', 'B03E', ITEM_CLASS_BHAND, ITEM_ANIM_AXE, Mix(ITEM_CATEGORY_COMMON, "Perfect Iron Claymore", "Claymore", "+50 Attack Power", "Slow"))
call ItemBonus['I00M'].saveStats( 0, 0, 0, 50, 0, 0, 0,-0.25, 0, 0, 0, 0, 0)
//call ItemBonus['I00M'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00M'].saveEffect( 0,"war3mapImported\\SwordMetalBlade.mdx", "right hand")
/* UNIQUE ITEM */ /* Dragon Slayer */
call SaveItem('I03W', 'B04L', ITEM_CLASS_BHAND, ITEM_ANIM_AXE, Mix(ITEM_CATEGORY_UNIQUE, "Dragon Slayer", "Claymore", "+275 Attack Power |n+60 Fire Damage |n+10% Critical Strike Chance |n+1.0 Critical Strike Multiplier |n+27 Strength |n+19 Agility |n+3 Intelligence", "Fast"))
call ItemBonus['I03W'].saveStats( 27, 3, 19,275, 0, 0, 0, 0.5, 0, 0, 0, 0, 0)
call ItemBonus['I03W'].saveDamageStats( 10,1.0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I03W'].saveEffect( 0,"war3mapImported\\SwordSearingBlade.mdl", "right hand")
/* Damaged Iron Bow */
call SaveItem('I002', 'B03H', ITEM_CLASS_BHAND, ITEM_ANIM_BOW, Mix(ITEM_CATEGORY_COMMON, "Damaged Iron Bow", "Bow", "+6 Attack Power", "Very Fast"))
call ItemBonus['I002'].saveStats( 0, 0, 0, 6, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I002'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I002'].saveEffect( 0,"war3mapImported\\BowFur.mdx", "left hand")
/* Rusty Iron Bow */
call SaveItem('I00G', 'B03G', ITEM_CLASS_BHAND, ITEM_ANIM_BOW, Mix(ITEM_CATEGORY_COMMON, "Rusty Iron Bow", "Bow", "+7 Attack Power", "Very Fast"))
call ItemBonus['I00G'].saveStats( 0, 0, 0, 7, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I00G'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00G'].saveEffect( 0,"war3mapImported\\BowFur.mdx", "left hand")
/* Iron Bow */
call SaveItem('I00J', 'B029', ITEM_CLASS_BHAND, ITEM_ANIM_BOW, Mix(ITEM_CATEGORY_COMMON, "Iron Bow", "Bow", "+8 Attack Power", "Very Fast"))
call ItemBonus['I00J'].saveStats( 0, 0, 0, 8, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I00J'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00J'].saveEffect( 0,"war3mapImported\\BowFur.mdx", "left hand")
/* Fine Iron Bow */
call SaveItem('I00I', 'B03I', ITEM_CLASS_BHAND, ITEM_ANIM_BOW, Mix(ITEM_CATEGORY_COMMON, "Fine Iron Bow", "Bow", "+9 Attack Power", "Very Fast"))
call ItemBonus['I00I'].saveStats( 0, 0, 0, 9, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I00I'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00I'].saveEffect( 0,"war3mapImported\\BowFur.mdx", "left hand")
/* Perfect Iron Bow */
call SaveItem('I00H', 'B03F', ITEM_CLASS_BHAND, ITEM_ANIM_BOW, Mix(ITEM_CATEGORY_COMMON, "Perfect Iron Bow", "Bow", "+10 Attack Power", "Very Fast"))
call ItemBonus['I00H'].saveStats( 0, 0, 0, 10, 0, 0, 0, 0.50, 0, 0, 0, 0, 0)
//call ItemBonus['I00H'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00H'].saveEffect( 0,"war3mapImported\\BowFur.mdx", "left hand")
/* Damaged Staff of Flames */
call SaveItem('I02C', 'B03L', ITEM_CLASS_BHAND, ITEM_ANIM_STAFF, Mix(ITEM_CATEGORY_COMMON, "Damaged Staff of Flames", "Staff", "+1 Attack Power |n+2 Spellpower |nAbility: Firebolt", "Very Slow"))
call ItemBonus['I02C'].saveStats( 0, 0, 0, 1, 0, 0, 0,-0.50, 0, 0, 0, 0, 0)
call ItemBonus['I02C'].saveDamageStats( 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I02C'].saveEffect('A007',"war3mapImported\\StaffQuarter.mdx", "right hand")
/* Crude Staff of Flames */
call SaveItem('I02B', 'B03K', ITEM_CLASS_BHAND, ITEM_ANIM_STAFF, Mix(ITEM_CATEGORY_COMMON, "Crude Staff of Flames", "Staff", "+2 Attack Power |n+4 Spellpower |nAbility: Firebolt", "Very Slow"))
call ItemBonus['I02B'].saveStats( 0, 0, 0, 2, 0, 0, 0,-0.50, 0, 0, 0, 0, 0)
call ItemBonus['I02B'].saveDamageStats( 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I02B'].saveEffect('A007',"war3mapImported\\StaffQuarter.mdx", "right hand")
/* Staff of Flames */
call SaveItem('I00P', 'B03J', ITEM_CLASS_BHAND, ITEM_ANIM_STAFF, Mix(ITEM_CATEGORY_COMMON, "Staff of Flames", "Staff", "+3 Attack Power |n+6 Spellpower |nAbility: Firebolt", "Very Slow"))
call ItemBonus['I00P'].saveStats( 0, 0, 0, 3, 0, 0, 0,-0.50, 0, 0, 0, 0, 0)
call ItemBonus['I00P'].saveDamageStats( 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I00P'].saveEffect('A007',"war3mapImported\\StaffQuarter.mdx", "right hand")
/* Fine Staff of Flames */
call SaveItem('I029', 'B03M', ITEM_CLASS_BHAND, ITEM_ANIM_STAFF, Mix(ITEM_CATEGORY_COMMON, "Fine Staff of Flames", "Staff", "+4 Attack Power |n+8 Spellpower |nAbility: Firebolt", "Very Slow"))
call ItemBonus['I029'].saveStats( 0, 0, 0, 4, 0, 0, 0,-0.50, 0, 0, 0, 0, 0)
call ItemBonus['I029'].saveDamageStats( 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I029'].saveEffect('A007',"war3mapImported\\StaffQuarter.mdx", "right hand")
/* Perfect Staff of Flames */
call SaveItem('I02A', 'B02X', ITEM_CLASS_BHAND, ITEM_ANIM_STAFF, Mix(ITEM_CATEGORY_COMMON, "Perfect Staff of Flames", "Staff", "+5 Attack Power |n+10 Spellpower |nAbility: Firebolt", "Very Slow"))
call ItemBonus['I02A'].saveStats( 0, 0, 0, 5, 0, 0, 0,-0.50, 0, 0, 0, 0, 0)
call ItemBonus['I02A'].saveDamageStats( 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I02A'].saveEffect('A007',"war3mapImported\\StaffQuarter.mdx", "right hand")
/************************
* ITEM_CLASS_PET_BELT *
*************************/
/* Damaged Fur Belt */
call SaveItem('I042', 'B04R', ITEM_CLASS_PET_BELT, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Damaged Fur Belt", "Pet Belt", "+1 Pet Defense", ""))
call ItemBonus['I042'].saveStatsPet( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I042'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
/* Crude Fur Belt */
call SaveItem('I041', 'B04Q', ITEM_CLASS_PET_BELT, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Crude Fur Belt", "Pet Belt", "+2 Pet Defense", ""))
call ItemBonus['I041'].saveStatsPet( 0, 2, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I041'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
/* Fur Belt */
call SaveItem('I03Y', 'B04N', ITEM_CLASS_PET_BELT, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Fur Belt", "Pet Belt", "+3 Pet Defense", ""))
call ItemBonus['I03Y'].saveStatsPet( 0, 3, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03Y'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
/* Fine Fur Belt */
call SaveItem('I03Z', 'B04O', ITEM_CLASS_PET_BELT, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Fine Fur Belt", "Pet Belt", "+4 Pet Defense", ""))
call ItemBonus['I03Z'].saveStatsPet( 0, 4, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I03Z'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
/* Perfect Fur Belt */
call SaveItem('I040', 'B04P', ITEM_CLASS_PET_BELT, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Perfect Fur Belt", "Pet Belt", "+5 Pet Defense", ""))
call ItemBonus['I040'].saveStatsPet( 0, 5, 0, 0, 0, 0, 0, 0, 0, 0)
//call ItemBonus['I040'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
/************************
* ITEM_CLASS_PET_ORB *
*************************/
/* Orb of Venom */
call SaveItem('I043', 'B04S', ITEM_CLASS_PET_ORB, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Orb of Venom", "Pet Belt", "+1 Pet Poison Damage", ""))
//call ItemBonus['I043'].saveStatsPet( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I043'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0)
/* Orb of Fire */
call SaveItem('I044', 'B04T', ITEM_CLASS_PET_ORB, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Orb of Fire", "Pet Belt", "+1 Pet Fire Damage", ""))
//call ItemBonus['I044'].saveStatsPet( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I044'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
/* Orb of Lightning */
call SaveItem('I045', 'B04U', ITEM_CLASS_PET_ORB, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Orb of Lightning", "Pet Belt", "+1 Pet Lightning Damage", ""))
//call ItemBonus['I045'].saveStatsPet( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I045'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0)
/* Orb of Frost */
call SaveItem('I046', 'B04V', ITEM_CLASS_PET_ORB, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Orb of Frost", "Pet Belt", "+1 Pet Frost Damage", ""))
//call ItemBonus['I046'].saveStatsPet( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I046'].saveDamageStats( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)
/* Orb of Darkness */
call SaveItem('I047', 'B04W', ITEM_CLASS_PET_ORB, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Orb of Darkness", "Pet Belt", "+5 Pet Attack Power |n+10% Pet Critical Strike Chance", ""))
call ItemBonus['I047'].saveStatsPet( 5, 0, 0, 0, 0, 0, 0, 0, 0, 0)
call ItemBonus['I047'].saveDamageStats( 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
/************************
* ITEM_CLASS_ABILITY *
*************************/
/* Heal */
call SaveItem('I048', 'B03T', ITEM_CLASS_ABILITY, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Heal", "- Ability - ", "|cffb4b4b4The most common restoration ability |nin whole Erebos. |nHeal will restore lost hit points |nof target unit instantly.|nUsed mostly by priests and monks, |nthis ability is well known.|nRestoration Battlemage main skill.|n|r|cff99b4d1|n|r|cffdaa520Ability Class:|r |cfff0f0f0Common|r|cff99b4d1|n|nHeal: 7.8 x spellpower.|r|n|cff99b4d1Cooldown: 12.20 seconds.|r", ""))
call SaveAbility('B03T', 'A10Q', 'A10W', 'A10E', 'A10R')
/* Fire Ball */
call SaveItem('I049', 'B03R', ITEM_CLASS_ABILITY, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Fire Ball", "- Ability - ", "|cffb4b4b4Fire Ball is improved version |nof Firebolt.|nFire Ball will damage group |nof enemy units around primary target.|nUsed mostly by wizards, |nthis ability is well known.|nDestruction Battlemage main skill.|n|r|cff99b4d1|n|r|cffdaa520Ability Class: |r|cfff0f0f0Common|r|cff99b4d1|n|nDamage: 2.2 x spellpower (|r|cffff0000Fire|r|cff99b4d1).|r|n|cff99b4d1Cooldown: 7.20 seconds.|r", ""))
call SaveAbility('B03R', 'A11Q', 'A11W', 'A11E', 'A11R')
/* Lightning Strike */
call SaveItem('I04A', 'B03P', ITEM_CLASS_ABILITY, ITEM_ANIM_NONE, Mix(ITEM_CATEGORY_COMMON, "Lightning Strike", "- Ability - ", "|cffb4b4b4Lightning Strike will deal |nsevere damage to single target. |nUsually used by Destruction Battlemages |nto bring havoc and death to enemies. |n|r|cff99b4d1|n|r|cffdaa520Ability Class: |r|cfff0f0f0Common|r|cff99b4d1|n|nHeal: 3.2 x spellpower (|r|cfff5deb3Lightning|r|cff99b4d1).|r|n|cff99b4d1Cooldown: 7.00 seconds.|r", ""))
call SaveAbility('B03P', 'A12Q', 'A12W', 'A12E', 'A12R')
endfunction
//! endtextmacro
//TESH.scrollpos=457
//TESH.alwaysfold=0
library CustomInterface initializer Init uses Table, ItemBonus, BuildingInOutSystem, AdvancedTextTag, HeroStatsMultiboard
globals
private unit LAST_CLICKED_UNIT = null
private unit SELECTOR = null
private destructable SELECTED_OBJECT = null
private integer SELECTED_OBJECT_ID = 0
private destructable DROP_ITEM_DEST = null
private Table BUTTON_ID
private integer array BUTTON_CLASS
private real array BUTTON_X
private real array BUTTON_Y
private real SIZE = 1.9
private constant integer MAX_SLOT = 60
private integer CUR_SLOT = 1
boolean IS_SELECTED = false
private constant trigger DROP_ITEM = CreateTrigger()
private constant trigger CLOSE_UI = CreateTrigger()
private constant trigger CLICK_SLOT = CreateTrigger()
private constant trigger TAKEN_SLOT = CreateTrigger()
private constant trigger TRIG_SHOW = CreateTrigger()
private constant trigger LOAD_ITEM = CreateTrigger()
private constant trigger INCREASE_ATTRIBUTE = CreateTrigger()
boolean array SLOT_USED
destructable array BUTTON_DEST
private integer array ABIL_ID
endglobals
private function Flush takes nothing returns nothing
set LAST_CLICKED_UNIT = null
set SELECTED_OBJECT = null
set IS_SELECTED = false
call RemoveUnit(SELECTOR)
if bj_lastCreatedLeaderboard != null then
call DestroyLeaderboard(bj_lastCreatedLeaderboard)
endif
call RemoveDestructable(DROP_ITEM_DEST)
set DROP_ITEM_DEST = CreateDestructableZ('B00K', BUTTON_X[666],BUTTON_Y[666],10.,0,2,0)
endfunction
private function DisplayInfo takes integer i, string msg returns nothing
if bj_lastCreatedLeaderboard != null then
call DestroyLeaderboard(bj_lastCreatedLeaderboard)
endif
set bj_lastCreatedLeaderboard = CreateLeaderboard()
call LeaderboardSetLabel(bj_lastCreatedLeaderboard, "Info: \n\n" + msg)
call LeaderboardSetSizeByItemCount(bj_lastCreatedLeaderboard, i)
call PlayerSetLeaderboard(Player(0), bj_lastCreatedLeaderboard)
call LeaderboardDisplay(bj_lastCreatedLeaderboard, true)
endfunction
function DoItemPickup takes unit u, item it returns nothing
local integer id = GetItemTypeId(it)
local integer i = 1
if CUR_SLOT == MAX_SLOT or LoadInteger(ITEM_HASH, id, 1) == 0 then
call UnitRemoveItem(u, it)
return
endif
call SetItemUserData(it, LoadInteger(ITEM_HASH, id, 0))
loop
exitwhen i > MAX_SLOT
if not SLOT_USED[i] then
set CUR_SLOT = CUR_SLOT + 1
set BUTTON_DEST[i] = CreateDestructable( LoadInteger(ITEM_HASH, id, 1), BUTTON_X[i], BUTTON_Y[i], 0.00, SIZE, 0 )
set SLOT_USED[i] = true
call UnitRemoveItem(u, it)
call RemoveItem(it)
return
endif
set i = i + 1
endloop
endfunction
private function EatFood takes unit u, item it returns nothing
local integer i = GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED)
local real mana = LoadReal( ITEM_HASH, GetItemTypeId(it), 1)
local real life = LoadReal( ITEM_HASH, GetItemTypeId(it), 2)
local integer food = LoadInteger(ITEM_HASH, GetItemTypeId(it), 3)
if i < 100 then
if life != 0. then
call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) + life)
call CreateAdvancedTextTag(TT_CRITICAL, TXTC[6] + "+" + I2S(R2I(life)), GetUnitX(u) + 15, GetUnitY(u)+25)
endif
if mana != 0. then
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + mana)
call CreateAdvancedTextTag(TT_CRITICAL, TXTC[1] + "+" + I2S(R2I(mana)), GetUnitX(u) - 15, GetUnitY(u)+25)
endif
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED, i + food)
else
call CreateAdvancedTextTag(TT_CRITICAL, TXTC[0] + "I can't eat anymore.", GetUnitX(u), GetUnitY(u)+75)
call CreateItem(GetItemTypeId(it), GetUnitX(u), GetUnitY(u))
endif
endfunction
private function Looper takes nothing returns nothing
local integer i = GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED)
if i > 0 then
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED, i - 1)
else
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_FOOD_USED, 0)
endif
endfunction
private function ItemPickup takes nothing returns nothing
if LoadInteger(ITEM_HASH, GetItemTypeId(GetManipulatedItem()), 0) == ITEM_CLASS_FOOD then
//Food Item
call EatFood(GetTriggerUnit(), GetManipulatedItem())
else
//Normal Item
call DoItemPickup(GetTriggerUnit(), GetManipulatedItem())
endif
endfunction
private function OnTrack takes nothing returns nothing
local integer id = BUTTON_ID[GetHandleId(GetTriggeringTrackable())]
if id > 500 and id < 550 then
call DisplayInfo(3, "|c00FFFFFFIncrease Attribute: |n" + HERO_ATTRIBUTE_NAME[id-500])
return
endif
if SLOT_USED[id] then
call DisplayInfo(30, LoadStr(ITEM_HASH, GetDestructableTypeId(BUTTON_DEST[id]), 2))
else
if bj_lastCreatedLeaderboard != null then
call DestroyLeaderboard(bj_lastCreatedLeaderboard)
endif
endif
endfunction
private function OnClick takes nothing returns nothing
local integer id = BUTTON_ID[GetHandleId(GetTriggeringTrackable())]
local integer item1
local integer item2
local integer id1
local integer id2
local integer class1
local integer class2
local boolean add_stats = false
local boolean add_stats_pet = false
local boolean remove_stats = false
local boolean remove_stats_pet = false
local item it1
local item it2
local integer ability_id = 0
local integer a = 0
if IS_SELECTED then
if SLOT_USED[id] then
set item1 = SELECTED_OBJECT_ID
set item2 = id
set id1 = GetDestructableTypeId(BUTTON_DEST[item1])
set id2 = GetDestructableTypeId(BUTTON_DEST[item2])
set class1 = LoadInteger(ITEM_HASH, id1, 0)
set class2 = LoadInteger(ITEM_HASH, id2, 0)
if (item1 > 100 and item2 > 100) then
call StartSound(gg_snd_Error)
call Flush()
return
endif
if id1 == id2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
if (item1 < 100 and item2 > 100) or (item1 > 100 and item2 < 100) then
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
if item1 < 100 then
set it1 = CreateItem(LoadInteger(ITEM_HASH, id1, 1),0,0)
call SaveItemHandle(ITEM_HASH, id1, 3, it1)
set it2 = LoadItemHandle(ITEM_HASH, id2, 3)
else
set it1 = CreateItem(LoadInteger(ITEM_HASH, id2, 1),0,0)
call SaveItemHandle(ITEM_HASH, id2, 3, it1)
set it2 = LoadItemHandle(ITEM_HASH, id1, 3)
endif
if item1 <100 and item2 > 100 then
if item2 <= 109 then
call ItemBonus.load(GetItemTypeId(it1))
call ItemBonus.remove(GetItemTypeId(it2))
else
if item2 < 200 then
call ItemBonus.loadPet(GetItemTypeId(it1))
call ItemBonus.removePet(GetItemTypeId(it2))
else
if item2 == 201 then
set a = 1
elseif item2 == 202 then
set a = 2
elseif item2 == 203 then
set a = 3
elseif item2 == 204 then
set a = 4
endif
if a > 0 then
//remove old one
set ability_id = LoadInteger(ITEM_HASH, id2, 10 + a)
call UnitRemoveAbility(HERO, ability_id)
//add new one
set ability_id = LoadInteger(ITEM_HASH, id1, 10 + a)
call UnitAddAbility(HERO, ability_id)
call UnitMakeAbilityPermanent(HERO, true, ability_id)
endif
endif
endif
elseif item1 >100 and item2 < 100 then
if item1 <= 109 then
call ItemBonus.load(GetItemTypeId(it1))
call ItemBonus.remove(GetItemTypeId(it2))
else
if item1 < 200 then
call ItemBonus.loadPet(GetItemTypeId(it1))
call ItemBonus.removePet(GetItemTypeId(it2))
else
if item1 == 201 then
set a = 1
elseif item1 == 202 then
set a = 2
elseif item1 == 203 then
set a = 3
elseif item1 == 204 then
set a = 4
endif
if a > 0 then
//remove old one
set ability_id = LoadInteger(ITEM_HASH, id1, 10 + a)
call UnitRemoveAbility(HERO, ability_id)
//add new one
set ability_id = LoadInteger(ITEM_HASH, id2, 10 + a)
call UnitAddAbility(HERO, ability_id)
call UnitMakeAbilityPermanent(HERO, true, ability_id)
endif
endif
endif
endif
set it1 = null
set it2 = null
endif
call RemoveDestructable(BUTTON_DEST[item1])
call RemoveDestructable(BUTTON_DEST[item2])
set BUTTON_DEST[item1] = CreateDestructable( id2, BUTTON_X[item1], BUTTON_Y[item1], 0.00, SIZE, 0 )
set BUTTON_DEST[item2] = CreateDestructable( id1, BUTTON_X[item2], BUTTON_Y[item2], 0.00, SIZE, 0 )
call HeroFormSwap.run(SLOT_USED[101])
call Flush()
else
set item1 = SELECTED_OBJECT_ID
set item2 = id
set id1 = GetDestructableTypeId(BUTTON_DEST[item1])
set class1 = LoadInteger(ITEM_HASH, id1, 0)
set class2 = BUTTON_CLASS[id]
if (item1 > 100 and item2 > 100) then
call StartSound(gg_snd_Error)
call Flush()
return
endif
if item2 == 101 then /* ITEM_CLASS_LHAND */
if class1 != class2 then
if class1 == ITEM_CLASS_BHAND then
if SLOT_USED[102] then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif class1 != ITEM_CLASS_LHAND then
call StartSound(gg_snd_Error)
call Flush()
return
endif
endif
elseif item2 == 102 then /* ITEM_CLASS_RHAND */
if class1 == class2 then
if LoadInteger(ITEM_HASH, GetDestructableTypeId(BUTTON_DEST[101]), 0) == ITEM_CLASS_BHAND then
call StartSound(gg_snd_Error)
call Flush()
return
endif
else
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 103 or item2 == 104 then /* ITEM_CLASS_RING */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 105 then /* ITEM_CLASS_GLOVE */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 106 then /* ITEM_CLASS_BOOTS */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 107 then /* ITEM_CLASS_TORSO */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 108 then /* ITEM_CLASS_HEAD */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 109 then /* ITEM_CLASS_AMULET */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 110 or item2 == 111 then /* ITEM_CLASS_PET_ORB */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 112 then /* ITEM_CLASS_PET_AMULET */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 113 then /* ITEM_CLASS_PET_BELT */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
elseif item2 == 201 or item2 == 202 or item2 == 203 or item2 == 204 then /* ITEM_CLASS_ABILITY -> Q W E R */
if class1 != class2 then
call StartSound(gg_snd_Error)
call Flush()
return
endif
endif
if item1 <100 and item2 > 100 then
if item2 <= 109 then
set add_stats = true
else
if item2 < 200 then
set add_stats_pet = true
endif
if item2 == 201 then
set a = 1
elseif item2 == 202 then
set a = 2
elseif item2 == 203 then
set a = 3
elseif item2 == 204 then
set a = 4
endif
if a > 0 then
set ability_id = LoadInteger(ITEM_HASH, id1, 10 + a)
call UnitAddAbility(HERO, ability_id)
call UnitMakeAbilityPermanent(HERO, true, ability_id)
endif
endif
elseif item1 >100 and item2 < 100 then
if item1 <= 109 then
set remove_stats = true
else
if item1 < 200 then
set remove_stats_pet = true
endif
if item1 == 201 then
set a = 1
elseif item1 == 202 then
set a = 2
elseif item1 == 203 then
set a = 3
elseif item1 == 204 then
set a = 4
endif
if a > 0 then
set ability_id = LoadInteger(ITEM_HASH, id1, 10 + a)
call UnitRemoveAbility(HERO, ability_id)
endif
endif
endif
call RemoveDestructable(BUTTON_DEST[item1])
set BUTTON_DEST[item2] = CreateDestructable( id1, BUTTON_X[item2], BUTTON_Y[item2], 0.00, SIZE, 0 )
set SLOT_USED[item1] = false
set SLOT_USED[item2] = true
if add_stats then
set it1 = CreateItem(LoadInteger(ITEM_HASH, id1, 1),0,0)
call SaveItemHandle(ITEM_HASH, id1, 3, it1)
call ItemBonus.load(GetItemTypeId(it1))
set it1 = null
endif
if add_stats_pet then
set it1 = CreateItem(LoadInteger(ITEM_HASH, id1, 1),0,0)
call SaveItemHandle(ITEM_HASH, id1, 3, it1)
call ItemBonus.loadPet(GetItemTypeId(it1))
set it1 = null
endif
if remove_stats then
call ItemBonus.remove(GetItemTypeId(LoadItemHandle(ITEM_HASH, id1, 3)))
endif
if remove_stats_pet then
call ItemBonus.removePet(GetItemTypeId(LoadItemHandle(ITEM_HASH, id1, 3)))
endif
if add_stats or remove_stats then
call HeroFormSwap.run(SLOT_USED[101])
endif
call Flush()
endif
else
if SLOT_USED[id] then
set SELECTED_OBJECT = BUTTON_DEST[id]
set SELECTED_OBJECT_ID = id
set IS_SELECTED = true
call RemoveUnit(SELECTOR)
set SELECTOR = CreateUnit(Player(15), 'h00A', BUTTON_X[id], BUTTON_Y[id], 0)
call RemoveDestructable(DROP_ITEM_DEST)
set DROP_ITEM_DEST = CreateDestructableZ('B03N', BUTTON_X[666],BUTTON_Y[666],270.,0,SIZE,0)
else
call Flush()
endif
endif
endfunction
private function OnDrop takes nothing returns nothing
local integer item_id = LoadInteger(ITEM_HASH, GetDestructableTypeId(SELECTED_OBJECT), 1)
if SELECTED_OBJECT_ID > 100 then
if SELECTED_OBJECT_ID > 100 then
if SELECTED_OBJECT_ID <= 109 then
call ItemBonus.remove(GetItemTypeId(LoadItemHandle(ITEM_HASH, GetDestructableTypeId(SELECTED_OBJECT), 3)))
else
call ItemBonus.removePet(GetItemTypeId(LoadItemHandle(ITEM_HASH, GetDestructableTypeId(SELECTED_OBJECT), 3)))
endif
endif
if SELECTED_OBJECT_ID == 101 then
call HeroFormSwap.run(false)
endif
endif
call CreateItem( item_id, GetUnitX(HERO), GetUnitY(HERO) )
call RemoveDestructable(SELECTED_OBJECT)
set CUR_SLOT = CUR_SLOT - 1
set SLOT_USED[SELECTED_OBJECT_ID] = false
set BUTTON_DEST[SELECTED_OBJECT_ID] = null
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\DispelMagic\\DispelMagicTarget.mdl",BUTTON_X[SELECTED_OBJECT_ID], BUTTON_Y[SELECTED_OBJECT_ID]))
call Flush()
endfunction
private function OnClose takes nothing returns nothing
call Flush()
set IS_IN_CI = false
if IS_IN_BUILDING then
call TimerStart(BUILDING_CAMERA_TIMER, 0.03, true, function SetBuildingCamera )
else
call ExpandMinimap(false)
endif
endfunction
private function registerTrack takes integer id, integer class, real x, real y, trigger trig returns nothing
local trackable t = CreateTrackable("war3mapImported\\128x128Track.mdx", x, y, 270)
set BUTTON_ID[GetHandleId(t)] = id
set BUTTON_CLASS[id] = class
set SLOT_USED[id] = false
set BUTTON_X[id] = x
set BUTTON_Y[id] = y
call TriggerRegisterTrackableHitEvent(trig, t)
call TriggerRegisterTrackableTrackEvent(TRIG_SHOW, t)
set t = null
endfunction
function GetInventoryItemType takes integer index returns integer
return LoadInteger(ITEM_HASH, GetDestructableTypeId(BUTTON_DEST[index]), 1)
endfunction
private function OnAttri takes nothing returns nothing
local integer id = BUTTON_ID[GetHandleId(GetTriggeringTrackable())]
local integer lumber = GetPlayerState(Player(0), PLAYER_STATE_RESOURCE_LUMBER)
if lumber > 0 then
set lumber = lumber - 1
else
return
endif
if HERO_ATTRIBUTE[id - 500] < 100 then
set HERO_ATTRIBUTE[id - 500] = HERO_ATTRIBUTE[id - 500] + 1
call UpdateMBItem( id - 500, 1, I2S(HERO_ATTRIBUTE[id - 500]))
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl",BUTTON_X[id], BUTTON_Y[id]))
else
set lumber = lumber + 1
call ClearTextMessages()
call DisplayTimedTextToPlayer(Player(0), 0.8, 0.1, 3,"|cffccccffAttribute is already fully upgraded!")
endif
call SetPlayerState(Player(0), PLAYER_STATE_RESOURCE_LUMBER, lumber)
endfunction
//! runtextmacro RegisterItems()
private function Init takes nothing returns nothing
set BUTTON_ID = Table.create()
/* Special Buttons */
call registerTrack(666, 666, -7616, -5440, DROP_ITEM)
call registerTrack(999, 999, -7488, -5440, CLOSE_UI )
/* Empty Buttons */
call registerTrack( 1, 0, -8640, -4416, CLICK_SLOT)
call registerTrack( 2, 0, -8512, -4416, CLICK_SLOT)
call registerTrack( 3, 0, -8384, -4416, CLICK_SLOT)
call registerTrack( 4, 0, -8256, -4416, CLICK_SLOT)
call registerTrack( 5, 0, -8128, -4416, CLICK_SLOT)
call registerTrack( 6, 0, -8000, -4416, CLICK_SLOT)
call registerTrack( 7, 0, -8640, -4544, CLICK_SLOT)
call registerTrack( 8, 0, -8512, -4544, CLICK_SLOT)
call registerTrack( 9, 0, -8384, -4544, CLICK_SLOT)
call registerTrack( 10, 0, -8256, -4544, CLICK_SLOT)
call registerTrack( 11, 0, -8128, -4544, CLICK_SLOT)
call registerTrack( 12, 0, -8000, -4544, CLICK_SLOT)
call registerTrack( 13, 0, -8640, -4672, CLICK_SLOT)
call registerTrack( 14, 0, -8512, -4672, CLICK_SLOT)
call registerTrack( 15, 0, -8384, -4672, CLICK_SLOT)
call registerTrack( 16, 0, -8256, -4672, CLICK_SLOT)
call registerTrack( 17, 0, -8128, -4672, CLICK_SLOT)
call registerTrack( 18, 0, -8000, -4672, CLICK_SLOT)
call registerTrack( 19, 0, -8640, -4800, CLICK_SLOT)
call registerTrack( 20, 0, -8512, -4800, CLICK_SLOT)
call registerTrack( 21, 0, -8384, -4800, CLICK_SLOT)
call registerTrack( 22, 0, -8256, -4800, CLICK_SLOT)
call registerTrack( 23, 0, -8128, -4800, CLICK_SLOT)
call registerTrack( 24, 0, -8000, -4800, CLICK_SLOT)
call registerTrack( 25, 0, -8640, -4928, CLICK_SLOT)
call registerTrack( 26, 0, -8512, -4928, CLICK_SLOT)
call registerTrack( 27, 0, -8384, -4928, CLICK_SLOT)
call registerTrack( 28, 0, -8256, -4928, CLICK_SLOT)
call registerTrack( 29, 0, -8128, -4928, CLICK_SLOT)
call registerTrack( 30, 0, -8000, -4928, CLICK_SLOT)
call registerTrack( 31, 0, -8640, -5056, CLICK_SLOT)
call registerTrack( 32, 0, -8512, -5056, CLICK_SLOT)
call registerTrack( 33, 0, -8384, -5056, CLICK_SLOT)
call registerTrack( 34, 0, -8256, -5056, CLICK_SLOT)
call registerTrack( 35, 0, -8128, -5056, CLICK_SLOT)
call registerTrack( 36, 0, -8000, -5056, CLICK_SLOT)
call registerTrack( 37, 0, -8640, -5184, CLICK_SLOT)
call registerTrack( 38, 0, -8512, -5184, CLICK_SLOT)
call registerTrack( 39, 0, -8384, -5184, CLICK_SLOT)
call registerTrack( 40, 0, -8256, -5184, CLICK_SLOT)
call registerTrack( 41, 0, -8128, -5184, CLICK_SLOT)
call registerTrack( 42, 0, -8000, -5184, CLICK_SLOT)
call registerTrack( 43, 0, -8640, -5312, CLICK_SLOT)
call registerTrack( 44, 0, -8512, -5312, CLICK_SLOT)
call registerTrack( 45, 0, -8384, -5312, CLICK_SLOT)
call registerTrack( 46, 0, -8256, -5312, CLICK_SLOT)
call registerTrack( 47, 0, -8128, -5312, CLICK_SLOT)
call registerTrack( 48, 0, -8000, -5312, CLICK_SLOT)
call registerTrack( 49, 0, -8640, -5440, CLICK_SLOT)
call registerTrack( 50, 0, -8512, -5440, CLICK_SLOT)
call registerTrack( 51, 0, -8384, -5440, CLICK_SLOT)
call registerTrack( 52, 0, -8256, -5440, CLICK_SLOT)
call registerTrack( 53, 0, -8128, -5440, CLICK_SLOT)
call registerTrack( 54, 0, -8000, -5440, CLICK_SLOT)
call registerTrack(101, ITEM_CLASS_LHAND , -7744, -4864, CLICK_SLOT) //Left Hand
call registerTrack(102, ITEM_CLASS_RHAND , -7360, -4864, CLICK_SLOT) //Right Hand
call registerTrack(103, ITEM_CLASS_RING , -7744, -4992, CLICK_SLOT) //Ring1
call registerTrack(104, ITEM_CLASS_RING , -7360, -4992, CLICK_SLOT) //Ring2
call registerTrack(105, ITEM_CLASS_GLOVE , -7680, -5120, CLICK_SLOT) //Glove
call registerTrack(106, ITEM_CLASS_BOOTS , -7424, -5120, CLICK_SLOT) //Boots
call registerTrack(107, ITEM_CLASS_TORSO , -7552, -5184, CLICK_SLOT) //Torso
call registerTrack(108, ITEM_CLASS_HEAD , -7616, -4736, CLICK_SLOT) //Head
call registerTrack(109, ITEM_CLASS_AMULET , -7488, -4736, CLICK_SLOT) //Amulet
call registerTrack(110, ITEM_CLASS_PET_ORB , -7744, -4480, CLICK_SLOT) //Pet Orb1
call registerTrack(111, ITEM_CLASS_PET_ORB , -7616, -4480, CLICK_SLOT) //Pet Orb2
call registerTrack(112, ITEM_CLASS_PET_AMULET, -7488, -4480, CLICK_SLOT) //Pet Amulet
call registerTrack(112, ITEM_CLASS_PET_BELT , -7360, -4480, CLICK_SLOT) //Pet Belt
call registerTrack(201, ITEM_CLASS_ABILITY , -7104, -4672, CLICK_SLOT) //Ability Q
call registerTrack(202, ITEM_CLASS_ABILITY , -7104, -4800, CLICK_SLOT) //Ability W
call registerTrack(203, ITEM_CLASS_ABILITY , -7104, -4928, CLICK_SLOT) //Ability E
call registerTrack(204, ITEM_CLASS_ABILITY , -7104, -5056, CLICK_SLOT) //Ability R
call registerTrack(501, 0, -8832.00, -4992.00, INCREASE_ATTRIBUTE)
call registerTrack(502, 0, -8832.00, -5120.00, INCREASE_ATTRIBUTE)
call registerTrack(503, 0, -8832.00, -5248.00, INCREASE_ATTRIBUTE)
call registerTrack(504, 0, -8832.00, -5376.00, INCREASE_ATTRIBUTE)
call registerTrack(506, 0, -8064.00, -5696.00, INCREASE_ATTRIBUTE)
call registerTrack(507, 0, -7936.00, -5696.00, INCREASE_ATTRIBUTE)
call registerTrack(508, 0, -7808.00, -5696.00, INCREASE_ATTRIBUTE)
call registerTrack(509, 0, -7680.00, -5696.00, INCREASE_ATTRIBUTE)
call registerTrack(511, 0, -7552.00, -5696.00, INCREASE_ATTRIBUTE)
call registerTrack(512, 0, -7424.00, -5696.00, INCREASE_ATTRIBUTE)
call registerTrack(513, 0, -7296.00, -5696.00, INCREASE_ATTRIBUTE)
call registerTrack(514, 0, -7168.00, -5696.00, INCREASE_ATTRIBUTE)
call SetupItemSystem()
call TriggerRegisterPlayerUnitEvent(LOAD_ITEM, Player(0), EVENT_PLAYER_UNIT_USE_ITEM,null)
call TriggerAddAction(LOAD_ITEM, function ItemPickup)
call TriggerAddAction(CLICK_SLOT , function OnClick)
call TriggerAddAction(DROP_ITEM , function OnDrop )
call TriggerAddAction(CLOSE_UI , function OnClose)
call TriggerAddAction(TRIG_SHOW , function OnTrack)
call TriggerAddAction(INCREASE_ATTRIBUTE , function OnAttri)
call TimerStart(CreateTimer(), 1.00, true, function Looper)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct HeroFormSwap extends array
static integer ABIL_CODE
static integer ANIMATION_STATE
static string ORDER = "metamorphosis"
//Lumber = Archer Animations
//None = Vilager Animations
//Flesh = Priest Animations
//Channel = Blademaster Animations
//Alternate = Footman Animations
static method changeTo takes string s returns nothing
call AddUnitAnimationProperties(HERO, "Lumber" , false)
call AddUnitAnimationProperties(HERO, "None" , false)
call AddUnitAnimationProperties(HERO, "Flesh" , false)
call AddUnitAnimationProperties(HERO, "Channel" , false)
call AddUnitAnimationProperties(HERO, "Alternate", false)
call AddUnitAnimationProperties(HERO, s , true )
endmethod
//Ranged
static method toggleRanged takes nothing returns nothing
if GetUnitPointValue(HERO) < 100 then
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, true)
call IssueImmediateOrder(HERO, ORDER)
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, false)
call thistype.changeTo("Lumber")
endif
endmethod
//Normal
static method toggleMelee takes nothing returns nothing
if GetUnitPointValue(HERO) > 100 then
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, true)
call IssueImmediateOrder(HERO, ORDER)
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, false)
call thistype.changeTo("Alternate")
endif
endmethod
//Two Hand Melee Weapon
static method twoHanded takes nothing returns nothing
if GetUnitPointValue(HERO) > 100 then
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, true)
call IssueImmediateOrder(HERO, ORDER)
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, false)
endif
call thistype.changeTo("Channel")
endmethod
//Staff
static method staff takes nothing returns nothing
if GetUnitPointValue(HERO) > 100 then
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, true)
call IssueImmediateOrder(HERO, ORDER)
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, false)
endif
call thistype.changeTo("Flesh")
endmethod
//No Weapon
static method emptyHanded takes nothing returns nothing
if GetUnitPointValue(HERO) > 100 then
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, true)
call IssueImmediateOrder(HERO, ORDER)
call SetPlayerAbilityAvailable(Player(0), ABIL_CODE, false)
endif
call thistype.changeTo("None")
endmethod
static method run takes boolean b returns nothing
local integer id = LoadInteger(ITEM_HASH, GetDestructableTypeId(BUTTON_DEST[101]),99) //Left Hand
if b then //Slot is used
if id == 1 then // SWORD
call thistype.toggleMelee()
set ANIMATION_STATE = 1
elseif id == 2 then // BOW
call thistype.toggleRanged()
set ANIMATION_STATE = 2
elseif id == 3 then // AXE
call thistype.twoHanded()
set ANIMATION_STATE = 3
elseif id == 4 then // STAFF
call thistype.staff()
set ANIMATION_STATE = 4
endif
else
call thistype.emptyHanded()
set ANIMATION_STATE = 0
endif
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
library HeroVisionSystem
globals
private constant integer ABIL_ID = 'A00F' // Far Sight
private unit dummy = null
endglobals
function CreateVision takes nothing returns nothing
if GetWidgetLife(HERO) > 0.405 then
call IssuePointOrder(dummy, "farsight", GetUnitX(HERO), GetUnitY(HERO))
endif
endfunction
function SetupHeroVisionSystem takes nothing returns nothing
set dummy = CreateUnit(Player(0), DUMMY_ID, 0,0,0)
call UnitAddAbility(dummy, ABIL_ID)
call TimerStart(CreateTimer(), 2.00, true, function CreateVision)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CinemaSystems uses BuildingInOutSystem
globals
dialog D
private button B_SKIP
private button B_WATCH
boolean PLAY_CINEMA = false
boolean D_CLICKED = false
boolean SKIP = false
playercolor PC0 = PLAYER_COLOR_RED
playercolor PC1 = PLAYER_COLOR_BLUE
private trigger TRIG = CreateTrigger()
endglobals
function MsgDispCinema takes string text returns nothing
call ClearTextMessages()
call DisplayTimedTextToPlayer(Player(0), 0, 0, 8,"|cffccccff" + text)
endfunction
function SkipCinema takes nothing returns nothing
if IS_CINEMA_ON then
set SKIP = true
endif
endfunction
/**************************************************/
/* Enable Cinema Mode */
/**************************************************/
function EnableCinema takes nothing returns nothing
set IS_CINEMA_ON = true
if IS_IN_BUILDING then
call PauseTimer(BUILDING_CAMERA_TIMER)
endif
if (not bj_cineModeAlreadyIn) then
set bj_cineModeAlreadyIn = true
set bj_cineModePriorSpeed = GetGameSpeed()
set bj_cineModePriorFogSetting = IsFogEnabled()
set bj_cineModePriorMaskSetting = IsFogMaskEnabled()
set bj_cineModePriorDawnDusk = bj_useDawnDuskSounds
set bj_cineModeSavedSeed = GetRandomInt(0, 1000000)
endif
call ClearTextMessages()
call ShowInterface(false, 0.5)
call EnableUserControl(false)
call EnableOcclusion(false)
call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITMOVEMENT, bj_CINEMODE_VOLUME_UNITMOVEMENT)
call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITSOUNDS, bj_CINEMODE_VOLUME_UNITSOUNDS)
call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_COMBAT, bj_CINEMODE_VOLUME_COMBAT)
call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_SPELLS, bj_CINEMODE_VOLUME_SPELLS)
call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UI, bj_CINEMODE_VOLUME_UI)
call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_MUSIC, bj_CINEMODE_VOLUME_MUSIC)
call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_AMBIENTSOUNDS, bj_CINEMODE_VOLUME_AMBIENTSOUNDS)
call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_FIRE, bj_CINEMODE_VOLUME_FIRE)
call SetGameSpeed(MAP_SPEED_NORMAL)
call SetMapFlag(MAP_LOCK_SPEED, true)
call FogMaskEnable(false)
call FogEnable(false)
call EnableWorldFogBoundary(false)
set bj_useDawnDuskSounds = false
call SetRandomSeed(0)
endfunction
function DisableCinema takes nothing returns nothing
set IS_CINEMA_ON = false
set SKIP = false
set bj_cineModeAlreadyIn = false
call ShowInterface(true, 0.5)
call EnableUserControl(true)
call EnableOcclusion(true)
call VolumeGroupReset()
call EndThematicMusic()
call CameraSetSmoothingFactor(0)
call SetMapFlag(MAP_LOCK_SPEED, false)
call SetGameSpeed(bj_cineModePriorSpeed)
call FogMaskEnable(bj_cineModePriorMaskSetting)
call FogEnable(bj_cineModePriorFogSetting)
call EnableWorldFogBoundary(true)
set bj_useDawnDuskSounds = bj_cineModePriorDawnDusk
call SetRandomSeed(bj_cineModeSavedSeed)
if IS_IN_BUILDING then
call TimerStart(BUILDING_CAMERA_TIMER, 0.03, true, function SetBuildingCamera )
else
call PauseTimer(BUILDING_CAMERA_TIMER)
set APPLY_CAMERA = null
set IS_IN_BUILDING = false
call ResetToGameCamera(0.00)
call SetCameraPosition(GetUnitX(HERO), GetUnitY(HERO))
endif
endfunction
/**************************************************/
/* Mask Textures */
/**************************************************/
function FadeOut takes real time returns nothing
call SetCineFilterTexture("ReplaceableTextures\\CameraMasks\\White_mask.blp")
call SetCineFilterBlendMode(BLEND_MODE_BLEND)
call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
call SetCineFilterStartUV(0, 0, 1, 1)
call SetCineFilterEndUV(0, 0, 1, 1)
call SetCineFilterStartColor(0, 0, 0, 255)
call SetCineFilterEndColor(0, 0, 0, 0)
call SetCineFilterDuration(time)
call DisplayCineFilter(true)
endfunction
function FadeIn takes real time returns nothing
call DisplayCineFilter(false)
call SetCineFilterTexture("ReplaceableTextures\\CameraMasks\\White_mask.blp")
call SetCineFilterBlendMode(BLEND_MODE_BLEND)
call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
call SetCineFilterStartUV(0, 0, 1, 1)
call SetCineFilterEndUV(0, 0, 1, 1)
call SetCineFilterStartColor(0, 0, 0, 0)
call SetCineFilterEndColor(0, 0, 0, 255)
call SetCineFilterDuration(time)
call DisplayCineFilter(true)
endfunction
function FadeOutEx takes real time, integer r, integer g, integer b returns nothing
call SetCineFilterTexture("ReplaceableTextures\\CameraMasks\\White_mask.blp")
call SetCineFilterBlendMode(BLEND_MODE_BLEND)
call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
call SetCineFilterStartUV(0, 0, 1, 1)
call SetCineFilterEndUV(0, 0, 1, 1)
call SetCineFilterStartColor(r, g, b, 255)
call SetCineFilterEndColor(0, 0, 0, 0)
call SetCineFilterDuration(time)
call DisplayCineFilter(true)
endfunction
function FadeInEx takes real time, integer r, integer g, integer b returns nothing
call DisplayCineFilter(false)
call SetCineFilterTexture("ReplaceableTextures\\CameraMasks\\White_mask.blp")
call SetCineFilterBlendMode(BLEND_MODE_BLEND)
call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
call SetCineFilterStartUV(0, 0, 1, 1)
call SetCineFilterEndUV(0, 0, 1, 1)
call SetCineFilterStartColor(0, 0, 0, 0)
call SetCineFilterEndColor(r, g, b, 255)
call SetCineFilterDuration(time)
call DisplayCineFilter(true)
endfunction
/**************************************************/
/* Play Cinema Dialog */
/**************************************************/
private function OnClick takes nothing returns nothing
set D_CLICKED = true
if GetClickedButton() == B_WATCH then
set PLAY_CINEMA = true
endif
endfunction
function PlayCinema takes nothing returns nothing
set D_CLICKED = false
set PLAY_CINEMA = false
call DialogDisplay(Player(0), D, true)
endfunction
function RegisterCinemaSystems takes nothing returns nothing
local trigger trig = CreateTrigger()
set D = DialogCreate()
call DialogSetMessage(D, " Shadows of the Past
---------------------------------------
|c00FFFFFFYou can skip cinematic now if you want.|r")
set B_WATCH = DialogAddButton(D, "Watch Cinematic",0)
set B_SKIP = DialogAddButton(D, "Skip Cinematic" ,0)
call TriggerRegisterDialogEvent(trig, D)
call TriggerAddAction(trig, function OnClick)
set trig = null
call DestroyTimer(GetExpiredTimer())
endfunction
/***************************************************/
struct RegisterSystem extends array
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0.00, false, function RegisterCinemaSystems )
call TriggerRegisterPlayerEvent(TRIG, Player(0), EVENT_PLAYER_END_CINEMATIC)
call TriggerAddAction(TRIG, function SkipCinema)
call FadeOut(0)
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library IntroCinematic uses CinemaSystems, Quest1
globals
private unit MARTIN = null
private unit U = null
private trigger T
endglobals
private function Run takes nothing returns nothing
if PLAY_CINEMA then
call EnableCinema()
call StartLoopingSound(MUSIC_INTRO)
call FadeIn(0)
call TriggerSleepAction(5)
call MsgDispCinema(" --- S H A D O W S O F T H E P A S T --- ")
call TriggerSleepAction(5)
call FadeOut(2)
call SetCinematicScene('n00W',PC1,"Old Man","Ah, you're finally awake.",5,0)
call TriggerSleepAction(4)
call SetCinematicScene('n00W',PC1,"Old Man","I hope you like mushrooms.",5,0)
call TriggerSleepAction(4)
call SetCinematicScene('n00W',PC1,"Old Man","Tell me, how can such a strong and young man almost bleed to death?",6,0)
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Where am I? Who are you old man?",5,0)
call SetUnitFacingTimed(HERO, 45, 1)
call TriggerSleepAction(4)
call SetCinematicScene('n00W',PC1,"Old Man","Who I am doesn't really matter, and you are in my house of course.",6,0)
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Where is my weapon... Where are my tools, I must leave immediately!",5,0)
call TriggerSleepAction(4)
call SetCinematicScene('n00W',PC1,"Old Man","I don't know, you were alone, almost naked when I found you, but rest now young one, you can travel tomorrow.",7,0)
call TriggerSleepAction(6)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"I guess you are right, thank you for saving me old man, please tell me how I should call you.",6,0)
call TriggerSleepAction(5)
call SetUnitFacingTimed(MARTIN, 45, 1)
call SetCinematicScene('n00W',PC1,"Old Man","You can call me Martin. The pleasure is mine, now please sit down and let us eat.",6,0)
call TriggerSleepAction(6)
call IssuePointOrder(MARTIN, "move", -20815, -2565)
call IssuePointOrder(HERO, "move", -20970, -2750)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Can you tell me more about this place, Martin? Where exactly am I?",6,0)
call TriggerSleepAction(5)
call SetCinematicScene('n00W',PC1,"Martin","As I've already said, you are in my house, located near a small fishing village called Waterville.",7,0)
call TriggerSleepAction(6)
call SetCinematicScene('n00W',PC1,"Martin","I will give you a list of important people in the village so that you can go ask for, more details if you wish to do so.",7,0)
call TriggerSleepAction(6)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"I'd appreciate that Martin, thank you once again.",6,0)
call TriggerSleepAction(5)
call Quest1Start()//Quest 1
call SetCinematicScene('n00W',PC1,"Martin","Eat now young one, eat, it's getting cold.",5,0)
call TriggerSleepAction(4)
call FadeIn(3)
call TriggerSleepAction(3)
call FadeOut(1)
call StartLoopingSound(MUSIC_WORLD1)
call DisableCinema()
call MsgDispCinema("Hint: Use the Interact ability to open the door and go outside.")
call MsgDispCinema("Hint: Once outside you can control camera with arrow keys.")
else
call IssuePointOrder(MARTIN, "move", -20815, -2565)
call IssuePointOrder(HERO, "move", -21000, -2750)
call StartLoopingSound(MUSIC_WORLD1)
call FadeOut(2)
call Quest1Start()//Quest 1
call DisableCinema()
call MsgDispCinema("Hint: Hint: Use the Interact ability to open the door and go outside.")
call MsgDispCinema("Hint: Once outside you can control camera with arrow keys.")
endif
call DestroyTrigger(GetTriggeringTrigger())
endfunction
private function CheckClick takes nothing returns nothing
if D_CLICKED then
set D_CLICKED = false
call DestroyTrigger(T)
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
set T = CreateTrigger()
set U = CreateUnit(Player(0), DUMMY_ID, 0,0,0)
call UnitApplyTimedLife(U, 0, 0.5)
call TriggerRegisterPlayerUnitEvent(T, Player(0), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddAction(T, function Run)
endif
endfunction
function RegisterIntroCinematic takes nothing returns nothing
set T = CreateTrigger()
set U = CreateUnit(Player(0), DUMMY_ID, 0,0,0)
call UnitApplyTimedLife(U, 0, 0.5)
call TriggerRegisterPlayerUnitEvent(T, Player(0), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddAction(T, function PlayCinema)
call TimerStart(CreateTimer(), 1.00, true, function CheckClick )
call FadeIn(0)
set MARTIN = gg_unit_n00W_0019
endfunction
endlibrary
//TESH.scrollpos=204
//TESH.alwaysfold=0
/*struct Interact extends array
//struct globals
static constant integer ABIL_CODE = 'A02E'
static constant hashtable INTERACT_HASH = InitHashtable()
//endglobals
static method SaveInteract takes integer id, integer n, string msg1, string msg2, string msg3, string msg4, string msg5, string msg6, string msg7, string msg8 returns nothing
call SaveInteger(INTERACT_HASH, id, 0, n)
call SaveStr(INTERACT_HASH, id, 1, msg1)
call SaveStr(INTERACT_HASH, id, 2, msg2)
call SaveStr(INTERACT_HASH, id, 3, msg3)
call SaveStr(INTERACT_HASH, id, 4, msg4)
call SaveStr(INTERACT_HASH, id, 5, msg5)
call SaveStr(INTERACT_HASH, id, 6, msg6)
call SaveStr(INTERACT_HASH, id, 7, msg7)
call SaveStr(INTERACT_HASH, id, 8, msg8)
endmethod
static method RegisterInteractAbility takes nothing returns nothing
//Squire UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(1, 8, "
Where the fuck am I?", "
I need a bigger weapon to look more tough.", "
Maybe I’m the Dragonborn, and I just don’t know it yet! Wait… Where have I heard that one before…?", "
Walking, eating, bashing sculls in… Just another normal day.", "
I feel the power overflowing in me… RAAAAAAAARRRGH!!!! … Hmm, nothing. Oh well, didn’t hurt to try.", "
I hope I know what I’m doing.", "
My blade is hungry for blood!! Or ectoplasm, whatever.", "
Damn forests! I’ll be happy if I don’t see another tree for the rest of my life!")
//Ranger UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(2, 8, "I need a new bow.", "
People ask me ‘why do you keep shooting everyone in the head?’, I say ‘because there are no apples on top of their heads.’", "
My arrows are deadly, without having to envenom them", "
Wandering adventurers, protect your kneecaps!", "
Someone told me I’m too ‘bow-string happy’, they never found his body…", "
An arrow flying towards you is the last thing you see before another one pierces your other eye.", "
If I shoot a random arrow in the air, will it kill somebody?", "Legolas? Pffft. Poser!")
//Monk UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(3, 8, "We Monks are peaceful people.", "
What a beautiful and peaceful day.", "Aaah, the peace… Peaceful, peacy peace-peace!", "
I shall bring peace upon the land.", "
More people should consider adding this new green pointy plant into their meals.", "
The ‘Peace Plant’ is the answer for all our problems.", "
I kill only in self-defense, because I’m peaceful like that.", "
I’m all about peace, honestly! Just take a look at my spells.")
//Sorcerer UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(4, 8, " HmmmmmHmmmHmm… Yes, but of course! That’s it! Wait… What was I pondering about, again?", "
What sorcery is this?!", "I'm hungry for magic! Or maybe I’m just plain hungry…", "
3.1415926535897932384626433832795028841971693993751… I’m positive that this number would change the world, but I forgot what it was used for…", "
Magic is my drug. I mean fuel! FUEL!", "
Hmm, if I combine fire and this greasy colorful fluid, the results should be very *KABOOOOOOOOOOOOOM* … *cough* Never mind… *cough*", "
As a student of the Arcane, it is my obligation to preach peace, and discourage violen- EEEK! A SPIDER! DIE! DIEEEE!!!", "
This rough terrain is bad for my robe.")
//Thief UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(5, 8, "I move unseen.", "
The night is my ally.", "
Swiftly.", "
I am one with the shadows.", "
Those coin purses seem awfully heavy…", "
Hold on to your valuables, if you wish to keep them.", "
The only visible part of me is my unsheathed blade, flashing at your throat.", "
‘Backstabbing is dishonorable’ is a phrase used by fat people who can’t hide from the enemy.")
//BACKPACK UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(6, 8, "Backpacks – can’t live with them, can’t carry junk without them.", "
BACKPACK, Y U NO HOLD MORE ITEMS??!!", "
Is it me, or is this thing getting heavier by the minute…", "
Food, I need food, oh wrong bag.", "
Nobody knows what kind of deep, dark evil lurks in the depths of it…", "
Blast, that little… Where did it hide now?", "
So anyways, the innkeeper said… Wait, why am I talking to a backpack", "
Where did it go…")
//BAG UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(7, 8, "There you are.", "
Wait what.", "
Bag started to smell...", "
I need some more food.", "
Ha diamond, nope, it's not.", "
Gosh it's so dark here.", "
Almost big as Santa's bag", "
I should call you somehow.")
//Soliders Archers UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(8, 5, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
", "
", "
")
//Soliders Axe UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(9, 5, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
", "
", "
")
//Soliders Knight UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(10, 5, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
", "
", "
")
//Soliders Sword UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(11, 5, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
", "
", "
")
//Battlemages UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(12, 5, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
", "
", "
")
//Master Wizard UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(13, 8, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
Nice cape.", "
Say, how about some free magic lessons, eh? No? Pfft, cheapskate!", "
How do you keep your hair shiny like that in this crude weather?")
//Captain UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(14, 8, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
Killed any bandits lately?", "
Every day is like watermelon cracking day for you, with that giant hammer of yours.", "
I bet you used to be an adventurer like me...")
//Merchants UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(15, 8, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
A bit pricey, don't you think?", "
Prices that big on economy this bad?! You must be out of your mind!", "
So... Who's your supplier? I wont tell, I promise.")
//Pet Master UPV (must be different for each class of units) - number of strings - messages from 1 to 8
call SaveInteract(666, 5, "Good day.", "
Hello.", "
Hi.", "
How do you do?", "
Greetings.", "
", "
", "
")
//Forces of Darkness PLAYER NUMBER *100 - number of strings - messages from 1 to 8
call SaveInteract( 800, 1, "For the Light", "
", "
", "
", "
", "
", "
", "
")
//Ancient Ones PLAYER NUMBER *100 - number of strings - messages from 1 to 8
call SaveInteract( 900, 1, "You think that you are special, eh?", "
", "
", "
", "
", "
", "
", "
")
//Creatures PLAYER NUMBER *100 - number of strings - messages from 1 to 8
call SaveInteract(1000, 5, "Die Beast!", "
Run, run away!", "
ROARARRRRARRRARR!!!", "
Just die already!", "Taste my wrath!", "
", "
", "
")
//Bandits PLAYER NUMBER *100 - number of strings - messages from 1 to 8
call SaveInteract(1100, 5, "Die enemy of the empire!", "
Surender!", "
Force wrath of justice!", "
You will pay for your sins!", "
Leave this land, and never come back!", "
", "
", "
")
endmethod
static method run takes nothing returns nothing
local unit u = GetSpellTargetUnit()
local integer pv = GetUnitPointValue(u)
local integer i = GetRandomInt(1, LoadInteger(INTERACT_HASH, pv, 0))
local string s = LoadStr(INTERACT_HASH, pv, i)
local integer j = 5
if IsUnitType(u, UNIT_TYPE_HERO) then
call IssueImmediateOrder(GetTriggerUnit(), "stop")
return
endif
if s == null then
set i = GetRandomInt(1, LoadInteger(INTERACT_HASH, GetPlayerId(GetOwningPlayer(u)) * 100, 0))
set s = LoadStr(INTERACT_HASH, GetPlayerId(GetOwningPlayer(u)) * 100, i)
set j = 0
if s == null then
set s = "Well, nevermind"
set j = 5
endif
endif
call FloatingText.AddEx(TXTC[j] + s, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 128, 65., 90.00, 0.023, 3.5)
if IsUnitAlly(u, Player(0)) then
set i = GetRandomInt(1, 5)
if i == 1 then
set s = "Hi"
elseif i == 2 then
set s = "Hello Sir"
elseif i == 3 then
set s = "Greetings"
elseif i == 4 then
set s = "Good Day"
else
return
endif
call FloatingText.AddEx(TXTC[1] + s, GetUnitX(u), GetUnitY(u), 128, 65., 90.00, 0.025, 2.)
endif
set u = null
endmethod
static method onInit takes nothing returns nothing
call thistype.RegisterInteractAbility()
call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
endmethod
endstruct*/
//TESH.scrollpos=0
//TESH.alwaysfold=0
library ItemGenerateLib initializer Init
globals
private hashtable ITEM_LIB_HASH = InitHashtable()
private item bj_lastGeneratedItem = null
/* Type */
private constant integer ITEM_TYPE_WEAPON = 'I000'
private constant integer ITEM_TYPE_SCROLL = 'IA00'
/* Class */
private constant integer ITEM_CLASS_SWORD = 0
private constant integer ITEM_CLASS_AXE = 1
private constant integer ITEM_CLASS_AXE = 1
endglobals
private function GenerateItem takes integer id, integer class, integer sub_class, string name returns nothing
local item it = CreateItem(sub_class, 0.00, 0.00)
local integer parentKey = GetHandleId(it)
call SaveItemHandle(ITEM_LIB_HASH, parentKey, 0, it)
call SaveInteger( ITEM_LIB_HASH, parentKey, 1, id)
call SaveInteger( ITEM_LIB_HASH, parentKey, 2, class)
call SaveInteger( ITEM_LIB_HASH, parentKey, 3, sub_class)
call SaveStr( ITEM_LIB_HASH, parentKey, 4, name)
endfunction
function Check takes nothing returns nothing
call BJDebugMsg(LoadStr(ITEM_LIB_HASH, GetHandleId(GetManipulatedItem()), 4))
endfunction
function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 0
loop
exitwhen i > 25
call GenerateItem(1000, ITEM_TYPE_WEAPON, ITEM_CLASS_SWORD, "Iron Sword - " + I2S(i))
call GenerateItem(1000, ITEM_TYPE_WEAPON, ITEM_CLASS_AXE , "Axe - " + I2S(i))
set i = i + 1
endloop
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
call TriggerAddAction( trig, function Check )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Transition_Camp_1_Actions takes nothing returns nothing
if GetUnitTypeId(GetTriggerUnit()) == GetUnitTypeId(HERO) then
call ClearTextMessages()
if GetUnitX(GetTriggerUnit()) < -14900 then
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.8, 0.1, 3, "|cffccccffEntering Hostile Area Level 1: The Ancient Forest|r")
set RevivePos = GetUnitLoc(gg_unit_ncop_0108)
else
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.8, 0.1, 3, "|cffccccffEntering Neutral Area: The Camp|r")
endif
endif
endfunction
//===========================================================================
function InitTrig_Transition_Camp_1 takes nothing returns nothing
set gg_trg_Transition_Camp_1 = CreateTrigger( )
call TriggerRegisterLeaveRectSimple( gg_trg_Transition_Camp_1, gg_rct_Transition_Camp_and_Ancient_Forest )
call TriggerAddAction( gg_trg_Transition_Camp_1, function Transition_Camp_1_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Transition_Camp_2_Actions takes nothing returns nothing
if GetUnitTypeId(GetTriggerUnit()) == GetUnitTypeId(HERO) then
call ClearTextMessages()
if GetUnitX(GetTriggerUnit()) < -13250 then
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.8, 0.1, 3, "|cffccccffEntering Neutral Area: The Camp|r")
set RevivePos = GetUnitLoc(gg_unit_ncop_0108)
else
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.8, 0.1, 3, "|cffccccffEntering Hostile Area Level 2: Hills of Arnor|r")
endif
endif
endfunction
//===========================================================================
function InitTrig_Transition_Camp_2 takes nothing returns nothing
set gg_trg_Transition_Camp_2 = CreateTrigger( )
call TriggerRegisterLeaveRectSimple( gg_trg_Transition_Camp_2, gg_rct_Transition_Camp_and_Ancient_Forest )
call TriggerAddAction( gg_trg_Transition_Camp_2, function Transition_Camp_2_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Transition_Swamps_Actions takes nothing returns nothing
if GetUnitTypeId(GetTriggerUnit()) == GetUnitTypeId(HERO) then
call ClearTextMessages()
if GetUnitY(GetTriggerUnit()) > 20300 then
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.8, 0.1, 3, "|cffccccffEntering Hostile Area Level 1: The Ancient Forest|r")
else
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.8, 0.1, 3, "|cffccccffEntering Hostile Area Level 1: Swamps|r")
endif
endif
endfunction
//===========================================================================
function InitTrig_Transition_Swamps takes nothing returns nothing
set gg_trg_Transition_Swamps = CreateTrigger( )
call TriggerRegisterLeaveRectSimple( gg_trg_Transition_Swamps, gg_rct_Transition_Ancient_Forest_and_Swamps )
call TriggerAddAction( gg_trg_Transition_Swamps, function Transition_Swamps_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Transition_Hills_of_Arnor_Actions takes nothing returns nothing
if GetUnitTypeId(GetTriggerUnit()) == GetUnitTypeId(HERO) then
call ClearTextMessages()
if GetUnitY(GetTriggerUnit()) > 24450 then
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.8, 0.1, 3, "|cffccccffEntering Hostile Area Level 1: The Ancient Forest|r")
else
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.8, 0.1, 3, "|cffccccffEntering Hostile Area Level 2: Hills of Arnor|r")
endif
endif
endfunction
//===========================================================================
function InitTrig_Transition_Hills_of_Arnor takes nothing returns nothing
set gg_trg_Transition_Hills_of_Arnor = CreateTrigger( )
call TriggerRegisterLeaveRectSimple( gg_trg_Transition_Hills_of_Arnor, gg_rct_Transition_Ancient_Forest_and_Hills_of_Arnor )
call TriggerAddAction( gg_trg_Transition_Hills_of_Arnor, function Transition_Hills_of_Arnor_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct Rest extends array
private static constant integer ABIL_CODE = 'A00C'
private static constant trigger T = CreateTrigger()
private static constant timer TIMER = CreateTimer()
private static boolean B = false
private static effect SFX = null
private static method doHeal takes nothing returns nothing
call SetUnitState(HERO, UNIT_STATE_LIFE, GetUnitState(HERO, UNIT_STATE_LIFE) + GetUnitState(HERO, UNIT_STATE_MAX_LIFE)*0.05)
call SetUnitState(HERO, UNIT_STATE_MANA, GetUnitState(HERO, UNIT_STATE_MANA) + GetUnitState(HERO, UNIT_STATE_MAX_MANA)*0.05)
call DestroyEffect(SFX)
set SFX = AddSpecialEffectTarget("Abilities\\Spells\\Other\\CreepSleep\\CreepSleepTarget.mdl", HERO, "overhead")
endmethod
private static method stopHeal takes nothing returns nothing
call DisableTrigger(T)
call PauseTimer(TIMER)
call DestroyEffect(SFX)
call IssueImmediateOrder(HERO, "stop")
set B = false
endmethod
private static method run takes nothing returns nothing
if not B then
call EnableTrigger(T)
call TimerStart(TIMER, 1, true, function thistype.doHeal)
endif
endmethod
static method registerAbility takes nothing returns nothing
call TriggerRegisterUnitEvent(T, HERO, EVENT_UNIT_ATTACKED)
call TriggerRegisterUnitEvent(T, HERO, EVENT_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterUnitEvent(T, HERO, EVENT_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddAction(T, function thistype.stopHeal)
call DisableTrigger(T)
call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=7
//TESH.alwaysfold=0
struct ItemStaffSpells extends array
private static constant integer ABIL_CODE1 = 'A007' /*Firebolt*/
private static constant integer ABIL_CODE3 = 'A009' /*Poison Ball*/
static method run takes nothing returns nothing
local unit caster = GetTriggerUnit()
local location l = GetUnitLoc(caster)
local real damage
local real heigh
local real speed
local real angle = LA2R(l, GetSpellTargetLoc())
local real radius
local string sfx
local boolean doFirst
local damagetype dmgType
call SetUnitAnimation(caster, "attack")
/*Firebolt*/
if GetSpellAbilityId() == ABIL_CODE1 then
set damage = Unit[caster].spellPower * 1.4
set speed = 900
set dmgType = DAMAGE_TYPE_FIRE
set heigh = 50
set radius = 60
set sfx = "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl"
set doFirst = true
/*Poison Ball*/
elseif GetSpellAbilityId() == ABIL_CODE3 then
set damage = Unit[caster].spellPower * 2.2
set dmgType = DAMAGE_TYPE_POISON
set speed = 900
set heigh = 50
set radius = 100
set sfx = "Abilities\\Weapons\\GreenDragonMissile\\GreenDragonMissile.mdl"
set doFirst = true
endif
call FireMissile(caster, damage, dmgType, heigh, speed, angle, radius, sfx, doFirst, 800.00)
call RemoveLocation(l)
set l = null
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABIL_CODE1, function thistype.run)
call RegisterSpellEffectEvent(ABIL_CODE3, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct MortalBlow extends array
private static constant integer ABIL_CODE = 'A00S'
static method run takes nothing returns nothing
call Unit[GetTriggerUnit()].damageTarget(GetSpellTargetUnit(), GetHeroStr(HERO, true) * 2.5, 1 /*Normal*/)
call Stun.apply(GetSpellTargetUnit(), 2.00, false)
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct Defend extends array
private static constant integer ABIL_CODE = 'A00U'
static method fix takes nothing returns nothing
call DestroyTimer(GetExpiredTimer())
call Bonus(GetUnitUserData(HERO)).addBonus(BONUS_TYPE_ARMOR, -5)
endmethod
static method run takes nothing returns nothing
call Bonus(GetUnitUserData(HERO)).addBonus(BONUS_TYPE_ARMOR, 5)
call TimerStart(CreateTimer(), 5.00, false, function thistype.fix)
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct FireBall extends array
static method run takes nothing returns nothing
local unit caster = GetTriggerUnit()
local location l = GetUnitLoc(caster)
local real damage = Unit[caster].spellPower * 2.2
local real heigh = 50
local real speed = 900
local real angle = LA2R(l, GetSpellTargetLoc())
local real radius = 100
local string sfx = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
local boolean doFirst = true
local damagetype dmgType = DAMAGE_TYPE_FIRE
if GetSpellAbilityId() == 'A01N' then
//Skeleton Burning Archer
set damage = damage * 2
set sfx = "Abilities\\Weapons\\SearingArrow\\SearingArrowMissile.mdl"
elseif GetSpellAbilityId() == 'A01O' then
//Skeleton Mage
set damage = damage * 3
elseif GetSpellAbilityId() == 'A01P' then
//Dragon Turtle
set damage = damage * 4
endif
call FireMissile(caster, damage, dmgType, heigh, speed, angle, radius, sfx, doFirst, 800.00)
set caster = null
call RemoveLocation(l)
set l = null
endmethod
static method onInit takes nothing returns nothing
//Hero Q W E R spells
call RegisterSpellEffectEvent('A11Q', function thistype.run)
call RegisterSpellEffectEvent('A11W', function thistype.run)
call RegisterSpellEffectEvent('A11E', function thistype.run)
call RegisterSpellEffectEvent('A11R', function thistype.run)
//Creep Spells
call RegisterSpellEffectEvent('A01N', function thistype.run)
call RegisterSpellEffectEvent('A01O', function thistype.run)
call RegisterSpellEffectEvent('A01P', function thistype.run)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct LightningStrike extends array
static method run takes nothing returns nothing
local unit caster = GetTriggerUnit()
local unit target = GetSpellTargetUnit()
local unit dummy = CreateUnit(GetOwningPlayer(caster), DUMMY_ID, GetUnitX(caster), GetUnitY(caster), 0.00)
call UnitApplyTimedLife(dummy, 'BTLF', 5.00)
call UnitAddAbility(dummy, 'A005')
call IssueTargetOrder(dummy, "fingerofdeath", target)
call Unit[caster].damageTarget(target,Unit[caster].spellPower * 3.2, 5 /*Lightning*/)
set caster = null
set target = null
set dummy = null
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent('A12Q', function thistype.run)
call RegisterSpellEffectEvent('A12W', function thistype.run)
call RegisterSpellEffectEvent('A12E', function thistype.run)
call RegisterSpellEffectEvent('A12R', function thistype.run)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct Heal extends array
static method run takes nothing returns nothing
call Unit[GetTriggerUnit()].damageTarget(GetSpellTargetUnit(),-Unit[GetTriggerUnit() ].spellPower * 7.8, 0/*Heal*/)
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent('A10Q', function thistype.run)
call RegisterSpellEffectEvent('A10W', function thistype.run)
call RegisterSpellEffectEvent('A10E', function thistype.run)
call RegisterSpellEffectEvent('A10R', function thistype.run)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
library FireBrathSpell initializer Init uses CustomMissileSystem, DamageSystem
globals
private constant integer ABIL_ID = 'A00W'
endglobals
private function Run takes nothing returns nothing
local unit caster = null
local real damage
local string sfx
local location loc = GetSpellTargetLoc()
if GetSpellAbilityId() == ABIL_ID then
set caster = GetTriggerUnit()
set damage = Unit[caster].spellPower * GetUnitAbilityLevel(caster, ABIL_ID) * 0.2
set sfx = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
//function FireMissile takes caster, damage, dmgType, heigh, speed, angle, radius, sfx, onlyOne, distance
call FireMissile(caster, damage, DAMAGE_TYPE_FIRE, 5.00, 1000.00, A2R(GetUnitX(caster), GetLocationX(loc), GetUnitY(caster), GetLocationY(loc))+0.25, 60.00, sfx, false, 300.00)
call FireMissile(caster, damage, DAMAGE_TYPE_FIRE, 5.00, 1000.00, A2R(GetUnitX(caster), GetLocationX(loc), GetUnitY(caster), GetLocationY(loc))-0.25, 60.00, sfx, false, 300.00)
call FireMissile(caster, damage, DAMAGE_TYPE_FIRE, 5.00, 1000.00, A2R(GetUnitX(caster), GetLocationX(loc), GetUnitY(caster), GetLocationY(loc)) , 60.00, sfx, false, 300.00)
set caster = null
endif
call RemoveLocation(loc)
set loc = null
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library RavageSpell initializer Init uses DamageSystem
globals
private constant integer ABIL_ID = 'A00T'
private constant integer DUMMY_ABIL_ID = 'A00N'
private hashtable hash = InitHashtable()
endglobals
private function DoDmg takes nothing returns nothing
local integer parentKey = GetHandleId(GetExpiredTimer())
local group g = CreateGroup()
local unit u
local unit caster = LoadUnitHandle(hash, parentKey, 0)
call GroupEnumUnitsInRange(g, GetUnitX(caster), GetUnitY(caster), 400, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
if IsUnitEnemy(u, Player(0)) then
call Unit[caster].damageTarget(u, LoadReal(hash, parentKey, 1), 1 /*normal*/)
endif
endloop
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
call FlushChildHashtable(hash, parentKey)
set caster = null
call DestroyGroup(g)
set g = null
endfunction
private function DoImpale takes unit caster, real x, real y returns nothing
local unit u
local real a = 0
local real fake_x
local real fake_y
loop
set u = CreateUnit(GetOwningPlayer(caster), DUMMY_ID, x, y, 0.00)
call UnitApplyTimedLife(u, 'BTLF', 3.00)
call UnitAddAbility(u, DUMMY_ABIL_ID)
set fake_x = x + 250 * Cos(a * bj_DEGTORAD)
set fake_y = y + 250 * Sin(a * bj_DEGTORAD)
call IssuePointOrder(u, "impale", fake_x, fake_y)
set u = null
set a = a + 30
exitwhen a >= 360
endloop
endfunction
private function Run takes nothing returns nothing
local timer t = null
local integer parentKey
local unit caster = null
if GetSpellAbilityId() == ABIL_ID then
set t = CreateTimer()
set parentKey = GetHandleId(t)
set caster = GetTriggerUnit()
call SaveUnitHandle(hash, parentKey, 0, caster)
call SaveReal(hash, parentKey, 1, ((2.2 + 0.2*GetUnitAbilityLevel(caster, ABIL_ID)) * Unit[caster].spellPower))
call TimerStart(t, 1, false, function DoDmg)
set t = null
call DoImpale(caster, GetUnitX(caster), GetUnitY(caster))
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
library BlazingCarapaceSpell initializer Init uses CreepSystem, CustomMissileSystem, DamageSystem
globals
private constant integer ABIL_ID = 'A00L'
endglobals
private function Run1 takes nothing returns nothing
local unit caster = null
local unit target = null
local real damage
local string sfx
if GetUnitAbilityLevel(GetTriggerUnit(), ABIL_ID) > 0 then
if GetRandomReal(0.00,1.00) <= (0.16 + (0.1 * GetUnitAbilityLevel(GetTriggerUnit(), ABIL_ID))) then
set caster = GetTriggerUnit()
set target = GetAttacker()
set damage = (1.0 + 0.2 * GetUnitAbilityLevel(caster, ABIL_ID)) * Unit[caster].spellPower
set sfx = "Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl"
//function FireMissile takes caster, damage, dmgType, heigh, speed, angle, radius, sfx, onlyOne
call FireMissile(caster, damage, DAMAGE_TYPE_FIRE, 75.00, 700.00, UA2R(caster, target), 60.00, sfx, true, 800.00)
set caster = null
set target = null
endif
endif
endfunction
private function Run2 takes nothing returns nothing
local integer id
if GetLearnedSkill() == ABIL_ID then
set id = GetUnitTypeId(PET)
call SaveReal(CREEP_HASH, id, 1, LoadReal(CREEP_HASH, id, 1) + 5.00)
call Unit[PET].setResistance(LoadReal(CREEP_HASH, id, 1), LoadReal(CREEP_HASH, id, 2), LoadReal(CREEP_HASH, id, 3), LoadReal(CREEP_HASH, id, 4))
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerAddAction(trig, function Run1)
set trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_HERO_SKILL, null)
call TriggerAddAction(trig, function Run2)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=1
//TESH.alwaysfold=0
library FlammingLasoSpell initializer Init uses DamageSystem
globals
private constant integer ABIL_ID = 'A00K'
private constant integer BUFF_ID = 'B002'
private hashtable hash = InitHashtable()
endglobals
private function DoLoop takes nothing returns nothing
local integer parentKey = GetHandleId(GetExpiredTimer())
local integer counter = LoadInteger(hash, parentKey, 100)
set counter = counter + 1
if counter > 5 then
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
call FlushChildHashtable(hash, parentKey)
else
if GetUnitAbilityLevel(LoadUnitHandle(hash, parentKey, 1), BUFF_ID) > 0 then
call Unit[LoadUnitHandle(hash, parentKey, 0)].damageTarget(LoadUnitHandle(hash, parentKey, 1), LoadReal(hash, parentKey, 2), 2 /*Fire*/)
endif
call SaveInteger(hash, parentKey, 100, counter)
endif
endfunction
private function Run takes nothing returns nothing
local timer t = null
local integer parentKey
if GetSpellAbilityId() == ABIL_ID then
set t = CreateTimer()
set parentKey = GetHandleId(t)
call SaveUnitHandle(hash, parentKey, 0, GetTriggerUnit())
call SaveUnitHandle(hash, parentKey, 1, GetSpellTargetUnit())
call SaveReal(hash, parentKey, 2, ((5 + 5*GetUnitAbilityLevel(GetTriggerUnit(), ABIL_ID)) * Unit[GetTriggerUnit()].spellPower))
call SaveInteger(hash, parentKey, 100, 1)
call TimerStart(t, 1, true, function DoLoop)
set t = null
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library BrillianceAuraSpell initializer Init uses DamageSystem, CreepSystem
globals
private constant integer ABIL_ID = 'A00Y'
endglobals
private function Run takes nothing returns nothing
local integer id
if GetLearnedSkill() == ABIL_ID then
set id = GetUnitTypeId(PET)
call SaveReal(CREEP_HASH, id, 18, LoadReal(CREEP_HASH, id, 18) + 3.00)
call Unit[PET].setSpellPower(LoadReal(CREEP_HASH, id, 18))
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_HERO_SKILL, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library PowerAuraSpell initializer Init uses DamageSystem, CreepSystem
globals
private constant integer ABIL_ID = 'A015'
endglobals
private function Run takes nothing returns nothing
local integer id
if GetLearnedSkill() == ABIL_ID then
set id = GetUnitTypeId(PET)
call SaveReal(CREEP_HASH, id, 6, LoadReal(CREEP_HASH, id, 6) + 3.00)
call Unit[PET].setDamage(LoadReal(CREEP_HASH, id, 5), LoadReal(CREEP_HASH, id, 6), LoadReal(CREEP_HASH, id, 7), LoadReal(CREEP_HASH, id, 8))
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_HERO_SKILL, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library DevotionAuraSpell initializer Init uses DamageSystem, CreepSystem
globals
private constant integer ABIL_ID = 'A00X'
endglobals
private function Run takes nothing returns nothing
local integer id
if GetLearnedSkill() == ABIL_ID then
set id = GetUnitTypeId(PET)
call SaveReal(CREEP_HASH, id, 17, LoadReal(CREEP_HASH, id, 17) + 3.00)
call Unit[PET].setEvasion(LoadReal(CREEP_HASH, id, 17))
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_HERO_SKILL, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=72
//TESH.alwaysfold=0
library SpiritualBondSpell initializer Init uses Math, DamageSystem, TimedLightnings, UnitRegeneration, DisplaySpellName
globals
private constant integer ABIL_ID = 'A016'
private constant integer DUMMY_ABIL_ID = 'A019'
private constant integer DURATION = 10
private hashtable hash = InitHashtable()
boolean ARE_HEROES_LINKED = false
endglobals
private function DoLoop takes nothing returns nothing
local integer parentKey = GetHandleId(GetExpiredTimer())
local integer counter = LoadInteger(hash, parentKey, 100)
local real regBonus
local real resistanceBonus
set counter = counter + 1
if counter > DURATION or GetWidgetLife(PET) < 1.00 or GetWidgetLife(HERO) < 1.00 or GetDistanceBetween(GetUnitX(PET), GetUnitY(PET), GetUnitX(HERO), GetUnitY(HERO)) > 1000 then
set regBonus = LoadReal(hash, parentKey, 2)
set resistanceBonus = LoadReal(hash, parentKey, 3)
set UnitRegeneration(PET_UD).life = UnitRegeneration(PET_UD).life - regBonus
set Unit(PET_UD).fireResistance = Unit(PET_UD).fireResistance - resistanceBonus
set Unit(PET_UD).coldResistance = Unit(PET_UD).coldResistance - resistanceBonus
set Unit(PET_UD).poisonResistance = Unit(PET_UD).poisonResistance - resistanceBonus
set Unit(PET_UD).lightningResistance = Unit(PET_UD).lightningResistance - resistanceBonus
set UnitRegeneration(HERO_UD).life = UnitRegeneration(HERO_UD).life - regBonus
set Unit(HERO_UD).fireResistance = Unit(HERO_UD).fireResistance - resistanceBonus
set Unit(HERO_UD).coldResistance = Unit(HERO_UD).coldResistance - resistanceBonus
set Unit(HERO_UD).poisonResistance = Unit(HERO_UD).poisonResistance - resistanceBonus
set Unit(HERO_UD).lightningResistance = Unit(HERO_UD).lightningResistance - resistanceBonus
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
call DestroyLightning(LoadLightningHandle(hash, parentKey, 1))
call FlushChildHashtable(hash, parentKey)
set ARE_HEROES_LINKED = false
else
/* Aura duration bug */
if counter > DURATION-4 then
call UnitRemoveAbility(PET, DUMMY_ABIL_ID)
call UnitRemoveAbility(HERO, DUMMY_ABIL_ID)
endif
/*********************/
call SaveInteger(hash, parentKey, 100, counter)
endif
endfunction
private function Run takes nothing returns nothing
local timer t = null
local integer parentKey
local real regBonus
local real resistanceBonus
if GetSpellAbilityId() == ABIL_ID and GetSpellTargetUnit() == HERO then
set t = CreateTimer()
set parentKey = GetHandleId(t)
set bj_lastCreatedLightning = AddLightningEx("MFPB", true, GetUnitX(PET), GetUnitY(PET), 10.00, GetUnitX(HERO), GetUnitY(HERO), 10.00)
call TimedL.U2U(bj_lastCreatedLightning, PET, HERO, DURATION, 50.00, 50.00, 1.00, 1.00)
call SaveLightningHandle(hash, parentKey, 1, bj_lastCreatedLightning)
set regBonus = 5 + GetUnitAbilityLevel(PET, ABIL_ID) * 2
set resistanceBonus = 0.10 + GetUnitAbilityLevel(PET, ABIL_ID) * 0.04
set UnitRegeneration(PET_UD).life = UnitRegeneration(PET_UD).life + regBonus
set Unit(PET_UD).fireResistance = Unit(PET_UD).fireResistance + resistanceBonus
set Unit(PET_UD).coldResistance = Unit(PET_UD).coldResistance + resistanceBonus
set Unit(PET_UD).poisonResistance = Unit(PET_UD).poisonResistance + resistanceBonus
set Unit(PET_UD).lightningResistance = Unit(PET_UD).lightningResistance + resistanceBonus
set UnitRegeneration(HERO_UD).life = UnitRegeneration(HERO_UD).life + regBonus
set Unit(HERO_UD).fireResistance = Unit(HERO_UD).fireResistance + resistanceBonus
set Unit(HERO_UD).coldResistance = Unit(HERO_UD).coldResistance + resistanceBonus
set Unit(HERO_UD).poisonResistance = Unit(HERO_UD).poisonResistance + resistanceBonus
set Unit(HERO_UD).lightningResistance = Unit(HERO_UD).lightningResistance + resistanceBonus
call SetPlayerAbilityAvailable(GetOwningPlayer(PET), DUMMY_ABIL_ID, true)
call UnitAddAbility(PET, DUMMY_ABIL_ID)
call UnitMakeAbilityPermanent(PET, true, DUMMY_ABIL_ID)
call SetPlayerAbilityAvailable(GetOwningPlayer(PET), DUMMY_ABIL_ID, false)
call SetPlayerAbilityAvailable(GetOwningPlayer(HERO), DUMMY_ABIL_ID, true)
call UnitAddAbility(HERO, DUMMY_ABIL_ID)
call UnitMakeAbilityPermanent(HERO, true, DUMMY_ABIL_ID)
call SetPlayerAbilityAvailable(GetOwningPlayer(HERO), DUMMY_ABIL_ID, false)
call SaveReal(hash, parentKey, 2, regBonus)
call SaveReal(hash, parentKey, 3, resistanceBonus)
call TimerStart(t, 1.00, true, function DoLoop)
set t = null
set ARE_HEROES_LINKED = true
call CreateAdvancedTextTag(TT_SPELL, "|c0000FF00" + GetObjectName(ABIL_ID), GetUnitX(PET), GetUnitY(PET))
elseif GetSpellAbilityId() == ABIL_ID and GetSpellTargetUnit() != HERO then
call IssueImmediateOrder(PET, "stop")
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=33
//TESH.alwaysfold=0
library SpiritualEnlightenmentSpell initializer Init uses DamageSystem, SpiritualBondSpell
globals
private constant integer ABIL_ID = 'A01A'
private constant integer DURATION = 10
private hashtable hash = InitHashtable()
private boolean IS_HERO_BUSTED = false
endglobals
private function DoLoop takes nothing returns nothing
local integer parentKey = GetHandleId(GetExpiredTimer())
local real counter = LoadReal(hash, parentKey, 100)
local real value = LoadReal(hash, parentKey, 1)
set counter = counter + 0.1
if counter > DURATION then
call DestroyEffect(LoadEffectHandle(hash, parentKey, 1))
call Bonus(PET_UD).addBonus(BONUS_TYPE_ARMOR, -1000)
set Unit(PET_UD).reflectChance = Unit(PET_UD).reflectChance - 50
set Unit(PET_UD).reflectPercent = Unit(PET_UD).reflectPercent - value
if IS_HERO_BUSTED then
call DestroyEffect(LoadEffectHandle(hash, parentKey, 2))
call Bonus(HERO_UD).addBonus(BONUS_TYPE_ARMOR, -1000)
set Unit(HERO_UD).reflectChance = Unit(HERO_UD).reflectChance - 50
set Unit(HERO_UD).reflectPercent = Unit(HERO_UD).reflectPercent - value
endif
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
call FlushChildHashtable(hash, parentKey)
set IS_HERO_BUSTED = false
else
if ARE_HEROES_LINKED and not IS_HERO_BUSTED then
call SaveEffectHandle(hash, parentKey, 2, AddSpecialEffectTarget("Abilities\\Spells\\Orc\\SpiritLink\\SpiritLinkZapTarget.mdl", HERO, "origin"))
call Bonus(HERO_UD).addBonus(BONUS_TYPE_ARMOR, 1000)
set Unit(HERO_UD).reflectChance = Unit(HERO_UD).reflectChance + 50
set Unit(HERO_UD).reflectPercent = Unit(HERO_UD).reflectPercent + value
set IS_HERO_BUSTED = true
elseif not ARE_HEROES_LINKED and IS_HERO_BUSTED then
call DestroyEffect(LoadEffectHandle(hash, parentKey, 2))
call Bonus(HERO_UD).addBonus(BONUS_TYPE_ARMOR, -1000)
set Unit(HERO_UD).reflectChance = Unit(HERO_UD).reflectChance - 50
set Unit(HERO_UD).reflectPercent = Unit(HERO_UD).reflectPercent - value
set IS_HERO_BUSTED = false
endif
call SaveReal(hash, parentKey, 100, counter)
endif
endfunction
private function Run takes nothing returns nothing
local timer t = null
local integer parentKey
local real value
if GetSpellAbilityId() == ABIL_ID then
set t = CreateTimer()
set parentKey = GetHandleId(t)
set value = Unit[PET].spellPower * GetUnitAbilityLevel(PET, ABIL_ID)
call SaveReal(hash, parentKey, 1, value)
call SaveEffectHandle(hash, parentKey, 1, AddSpecialEffectTarget("Abilities\\Spells\\Orc\\SpiritLink\\SpiritLinkZapTarget.mdl", PET, "origin"))
call Bonus(PET_UD).addBonus(BONUS_TYPE_ARMOR, 1000)
set Unit(PET_UD).reflectChance = Unit(PET_UD).reflectChance + 50
set Unit(PET_UD).reflectPercent = Unit(PET_UD).reflectPercent + value
if ARE_HEROES_LINKED then
call SaveEffectHandle(hash, parentKey, 2, AddSpecialEffectTarget("Abilities\\Spells\\Orc\\SpiritLink\\SpiritLinkZapTarget.mdl", HERO, "origin"))
call Bonus(HERO_UD).addBonus(BONUS_TYPE_ARMOR, 1000)
set Unit(HERO_UD).reflectChance = Unit(HERO_UD).reflectChance + 50
set Unit(HERO_UD).reflectPercent = Unit(HERO_UD).reflectPercent + value
set IS_HERO_BUSTED = true
endif
call TimerStart(t, 0.10, true, function DoLoop)
set t = null
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library LightningMasterySpell initializer Init uses DamageSystem, CreepSystem
globals
private constant integer ABIL_ID = 'A01F'
endglobals
private function Run takes nothing returns nothing
local integer id
if GetLearnedSkill() == ABIL_ID then
set id = GetUnitTypeId(PET)
call SaveReal(CREEP_HASH, id, 8, LoadReal(CREEP_HASH, id, 8) + 25.00)
call Unit[PET].setDamage(LoadReal(CREEP_HASH, id, 5), LoadReal(CREEP_HASH, id, 6), LoadReal(CREEP_HASH, id, 7), LoadReal(CREEP_HASH, id, 8))
call SaveReal(CREEP_HASH, id, 4, LoadReal(CREEP_HASH, id, 4) + 15.00)
call Unit[PET].setResistance(LoadReal(CREEP_HASH, id, 1), LoadReal(CREEP_HASH, id, 2), LoadReal(CREEP_HASH, id, 3), LoadReal(CREEP_HASH, id, 4))
endif
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_HERO_SKILL, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library LightningStrikeSpell initializer Init uses CreepSystem, CustomMissileSystem, DamageSystem
globals
private constant integer ABIL_ID = 'A00D'
private trigger trig = CreateTrigger()
endglobals
private function EnableTrig takes nothing returns nothing
call PauseTimer(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
call EnableTrigger(trig)
endfunction
private function Run takes nothing returns nothing
local unit caster = null
local unit target = null
local real damage
local string sfx
if GetUnitAbilityLevel(GetAttacker(), ABIL_ID) > 0 and GetRandomReal(0.00,1.00) <= 0.20 then
set caster = GetAttacker()
set target = GetTriggerUnit()
set damage = (2.5 + 0.5 * GetUnitAbilityLevel(caster, ABIL_ID)) * Unit[caster].spellPower
set sfx = "Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl"
//function FireMissile takes caster, damage, dmgType, heigh, speed, angle, radius, sfx, onlyOne, distance
call FireMissile(caster, damage, DAMAGE_TYPE_LIGHTNING, 75.00, 1500.00, UA2R(caster, target), 60.00, sfx, false, 500.00)
set caster = null
set target = null
call DisableTrigger(trig)
call TimerStart(CreateTimer(), 0.7, false, function EnableTrig)
endif
endfunction
private function Init takes nothing returns nothing
call TriggerRegisterPlayerUnitEvent(trig, Player( 8), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerRegisterPlayerUnitEvent(trig, Player( 9), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerRegisterPlayerUnitEvent(trig, Player(10), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerRegisterPlayerUnitEvent(trig, Player(11), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerAddAction(trig, function Run)
endfunction
endlibrary
//TESH.scrollpos=47
//TESH.alwaysfold=0
library Ping
struct Ping extends array
private static thistype array rn
private static integer ic = 0
private static timer t = CreateTimer()
private static thistype array next
private static thistype array prev
private static integer count = 0
private static integer array color_type
private static real array x_p
private static real array y_p
private static method periodic takes nothing returns nothing
local thistype this = next[0]
loop
exitwhen this == 0
if color_type[this] == 1 then
call PingMinimapEx(x_p[this], y_p[this], 5.00, 0xff, 0xcc, 0x00, false)
else
call PingMinimapEx(x_p[this], y_p[this], 5.00, 0xc3, 0xdb, 0xff, false)
endif
set this = next[this]
endloop
endmethod
static method create takes real x, real y, integer c_t returns thistype
local thistype this = rn[0]
if this == 0 then
set ic = ic + 1
set this = ic
else
set rn[0] = rn[this]
endif
set color_type[this] = c_t
set x_p[this] = x
set y_p[this] = y
set next[this] = 0
set prev[this] = prev[0]
set next[prev[0]] = this
set prev[0] = this
if color_type[this] == 1 then
call PingMinimapEx(x, y, 5.00, 0xff, 0xcc, 0x00, false)
else
call PingMinimapEx(x, y, 5.00, 0xc3, 0xdb, 0xff, false)
endif
set count = count + 1
if count == 1 then
call TimerStart(t, 60, true, function thistype.periodic)
endif
return this
endmethod
method destroy takes nothing returns nothing
set rn[this] = rn[0]
set rn[0] = this
set next[prev[this]] = next[this]
set prev[next[this]] = prev[this]
set count = count - 1
if count == 0 then
call PauseTimer(t)
endif
endmethod
endstruct
function CreatePing takes real x, real y, integer c_t returns Ping
return Ping.create(x, y, c_t)
endfunction
function RemovePing takes Ping ping returns nothing
call ping.destroy()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library QuestMessageSystem initializer Init
globals
private dialog DIALOG
private hashtable HASH = InitHashtable()
private integer array PAGE_NUMBER
private integer array MAX_PAGE_NUMBER
private integer LAST_CREATED_DIALOG
private button B_LEFT
private button B_RIGHT
private button B_CLOSE
private integer array COUNTER
endglobals
function EditMessage takes nothing returns nothing
call DialogClear(DIALOG)
call DialogSetMessage(DIALOG, LoadStr(HASH, LAST_CREATED_DIALOG, PAGE_NUMBER[LAST_CREATED_DIALOG]))
if MAX_PAGE_NUMBER[LAST_CREATED_DIALOG] > 1 then
set B_LEFT = DialogAddButton(DIALOG, "Previous Message",0)
set B_RIGHT = DialogAddButton(DIALOG, "Next Message",0)
endif
set B_CLOSE = DialogAddButton(DIALOG, "|c00FF0303Close|r",0)
call DialogDisplay(Player(0), DIALOG, true)
endfunction
private function OnClick takes nothing returns nothing
local integer id = LoadInteger(HASH, LAST_CREATED_DIALOG, 100)
if GetClickedButton() == B_LEFT then
if PAGE_NUMBER[id] > 1 then
set PAGE_NUMBER[id] = PAGE_NUMBER[id] - 1
endif
call EditMessage()
elseif GetClickedButton() == B_RIGHT then
if PAGE_NUMBER[id] < MAX_PAGE_NUMBER[id] then
set PAGE_NUMBER[id] = PAGE_NUMBER[id] + 1
endif
call EditMessage()
elseif GetClickedButton() == B_CLOSE then
endif
endfunction
function AddQuestMessage takes integer id, string text returns nothing
set PAGE_NUMBER[id] = PAGE_NUMBER[id] + 1
call SaveStr(HASH, id, PAGE_NUMBER[id], I2S(PAGE_NUMBER[id]) + "/" + I2S(MAX_PAGE_NUMBER[id]) + " " + text)
if PAGE_NUMBER[id] == MAX_PAGE_NUMBER[id] then
set PAGE_NUMBER[id] = 1
endif
endfunction
function CreateMessage takes integer id, integer max returns nothing
set PAGE_NUMBER[id] = 0
set MAX_PAGE_NUMBER[id] = max
call SaveInteger(HASH, id, 100, id)
set LAST_CREATED_DIALOG = id
endfunction
private function Setup takes nothing returns nothing
local trigger t = CreateTrigger()
set DIALOG = DialogCreate()
call TriggerRegisterDialogEvent(t, DIALOG)
call TriggerAddAction( t, function OnClick )
set t = null
endfunction
private function Init takes nothing returns nothing
call TimerStart(CreateTimer(), 0, false, function Setup)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library SotPQuests initializer Init uses QuestMessageSystem
globals
quest array QUEST
string array QUEST_NAME
string array QUEST_DESC
string array QUEST_ITEM_DESC
integer array GOLD_AWARD
integer array LUMBER_AWARD
integer array EXP_AWARD
integer array QUEST_UNIT
unit array NPC
effect array SFX
constant string MARK_SFX1 = "Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl"
constant string MARK_SFX2 = "war3mapImported\\TalkToMeQuestionMarkWhite2.mdx"
constant string MARK_SFX3 = "war3mapImported\\TalkToMe2.mdl"
constant sound SOUND_QUEST_COMPLETED = CreateSound("Sound\\Interface\\QuestCompleted.wav",false,false,false,10,10,"")
constant sound SOUND_QUEST_NEW = CreateSound("Sound\\Interface\\QuestNew.wav",false,false,false,10,10,"")
constant sound SOUND_QUEST_FAILED = CreateSound("Sound\\Interface\\QuestFailed.wav",false,false,false,10,10,"")
constant sound SOUND_ITEM_COMPLETED = CreateSound("Sound\\Interface\\GoodJob.wav",false,false,false,10,10,"")
private constant string GOLD = "|cffffcc00"
private constant string SILV = "|cffc3dbff"
private constant real D = 5.
private constant player p0 = Player(0)
endglobals
function QuestAdd takes integer questid, string name, string desc, string icon, boolean required returns nothing
set QUEST[questid] = CreateQuest()
call QuestSetTitle(QUEST[questid], name)
call QuestSetDescription(QUEST[questid], desc)
call QuestSetIconPath(QUEST[questid], icon)
call QuestSetDiscovered(QUEST[questid], true)
call QuestSetEnabled(QUEST[questid], true)
call QuestSetRequired(QUEST[questid], required)
call DestroyEffect(SFX[questid])
endfunction
function QuestFinish takes integer questid returns nothing
call QuestSetDescription(QUEST[questid], SILV + QUEST_DESC[questid])
call QuestSetCompleted(QUEST[questid], true)
call DestroyEffect(SFX[questid])
endfunction
function QuestAward takes integer questid returns nothing
local boolean b1 = GOLD_AWARD[questid] > 0
local boolean b2 = LUMBER_AWARD[questid] > 0
local boolean b3 = EXP_AWARD[questid] > 0
if b1 or b2 or b3 then
call DisplayTimedTextToPlayer(p0, 0, 0, D, GOLD + "Awards")
endif
if b1 then
call DisplayTimedTextToPlayer(p0, 0, 0, D, " + " + I2S(GOLD_AWARD[questid]) + " Gold Coins")
call SetPlayerState(p0, PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(p0, PLAYER_STATE_RESOURCE_GOLD) + GOLD_AWARD[questid])
endif
if b2 then
call DisplayTimedTextToPlayer(p0, 0, 0, D, " + " + I2S(LUMBER_AWARD[questid]) + " Skill Points")
call SetPlayerState(p0, PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(p0, PLAYER_STATE_RESOURCE_LUMBER) + LUMBER_AWARD[questid])
endif
if b3 then
call DisplayTimedTextToPlayer(p0, 0, 0, D, " + " + I2S(EXP_AWARD[questid]) + " Experience")
call SetHeroXP(HERO, GetHeroXP(HERO) + EXP_AWARD[questid], true)
endif
call DisplayTextToPlayer(p0, 0, 0, " ")
endfunction
function QuestAwardEx takes integer questid returns nothing
if questid == 1 then
call DisplayTimedTextToPlayer(p0, 0, 0, D, GOLD + "Special Award:|r +5% chance for Critical Strike")
//call ADS.SetUnitStats(HERO, false, ABc, ACc + 5, ADc, ARc, ACm, ABd, ARv)
endif
endfunction
function QuestMsg takes integer questid, sound snd, integer msgtype, integer loopint, integer i1, integer i2, integer i3, integer i4, integer i5, integer i6, integer i7, integer i8 returns nothing
local string s1 = " - "
local string s2 = GOLD + " (New)|r"
local string s3 = " (Completed)"
local string array S
local integer i = 1
local integer array I
call StartSound(snd)
if msgtype == 1 then
call DisplayTimedTextToPlayer(p0, 0, 0, D, GOLD + "Quest Discovered|r\n" + QUEST_NAME[questid])
elseif msgtype == 2 then
call DisplayTimedTextToPlayer(p0, 0, 0, D, GOLD + "Quest Updated|r\n" + QUEST_NAME[questid])
else
call DisplayTimedTextToPlayer(p0, 0, 0, D, GOLD + "Quest Completed|r\n" + QUEST_NAME[questid])
endif
set I[1] = i1
set I[2] = i2
set I[3] = i3
set I[4] = i4
set I[5] = i5
set I[6] = i6
set I[7] = i7
set I[8] = i8
loop
exitwhen i == loopint + 1
if I[i] == 1 then
set S[i] = s1 + QUEST_ITEM_DESC[i] + s2
elseif I[i] == 2 then
set S[i] = s1 + QUEST_ITEM_DESC[i]
elseif I[i] == 3 then
set S[i] = s1 + SILV + QUEST_ITEM_DESC[i] + s3
else
set S[i] = ""
endif
call DisplayTimedTextToPlayer(p0, 0, 0, D, S[i])
set i = i + 1
endloop
if msgtype != 3 then
call DisplayTextToPlayer(p0, 0, 0, " ")
endif
call FlashQuestDialogButton()
endfunction
function QuestAddItem takes integer questid, string desc returns questitem
local questitem qi = QuestCreateItem(QUEST[questid])
call QuestItemSetDescription(qi, desc)
return qi
endfunction
function Fire takes nothing returns nothing
local integer id = GetUnitTypeId(GetSoldUnit())
if id == QUEST_UNIT[501] then
call quest501.start()
elseif id == QUEST_UNIT[502] then
call quest502.start()
elseif id == QUEST_UNIT[503] then
call quest503.start()
elseif id == QUEST_UNIT[504] then
call quest504.start()
elseif id == QUEST_UNIT[505] then
call quest505.start()
elseif id == QUEST_UNIT[506] then
call quest506.start()
endif
if id == QUEST_UNIT[1000+501] then
call quest501.finish()
elseif id == QUEST_UNIT[1000+502] then
call quest502.finish()
elseif id == QUEST_UNIT[1000+503] then
call quest503.finish()
/*elseif id == QUEST_UNIT[1000+504] then
call quest504.finish() THERE IS NO NEED */
/*elseif id == QUEST_UNIT[1000+505] then
call quest505.finish() THERE IS NO NEED */
elseif id == QUEST_UNIT[1000+506] then
call quest506.finish()
endif
call RemoveUnitFromStock(GetSellingUnit(), id)
endfunction
private function Init takes nothing returns nothing
/*set NPC[id] =
set QUEST_UNIT[id] = 'n200'
set QUEST_UNIT[1000+id] = 'n400'
set SFX[id] = AddSpecialEffectTarget(MARK_SFX3, NPC[id], "overhead")
call AddUnitToStock(NPC[id], QUEST_UNIT[id], 0, 0)*/
set NPC[501] = gg_unit_h001_0120
set QUEST_UNIT[501] = 'n200'
set QUEST_UNIT[1000+501] = 'n400'
set SFX[501] = AddSpecialEffectTarget(MARK_SFX3, NPC[501], "overhead")
call AddUnitToStock(NPC[501], QUEST_UNIT[501], 0, 0)
set NPC[502] = gg_unit_h004_0101
set QUEST_UNIT[502] = 'n201'
set QUEST_UNIT[1000+502] = 'n401'
set SFX[502] = AddSpecialEffectTarget(MARK_SFX3, NPC[502], "overhead")
call AddUnitToStock(NPC[502], QUEST_UNIT[502], 0, 0)
set NPC[503] = gg_unit_h008_0123
set QUEST_UNIT[503] = 'n202'
set QUEST_UNIT[1000+503] = 'n402'
set SFX[503] = AddSpecialEffectTarget(MARK_SFX3, NPC[503], "overhead")
call AddUnitToStock(NPC[503], QUEST_UNIT[503], 0, 0)
set NPC[504] = gg_unit_h012_0012
set QUEST_UNIT[504] = 'n203'
/*set QUEST_UNIT[1000+504] = 'n403' */
set SFX[504] = AddSpecialEffectTarget(MARK_SFX3, NPC[504], "overhead")
call AddUnitToStock(NPC[504], QUEST_UNIT[504], 0, 0)
set NPC[505] = gg_unit_h010_0136
set QUEST_UNIT[505] = 'n204'
/*set QUEST_UNIT[1000+505] = 'n404' */
set SFX[505] = AddSpecialEffectTarget(MARK_SFX3, NPC[505], "overhead")
call AddUnitToStock(NPC[505], QUEST_UNIT[505], 0, 0)
set NPC[506] = gg_unit_n010_0279
set QUEST_UNIT[506] = 'n205'
set QUEST_UNIT[1000+506] = 'n405'
set SFX[506] = AddSpecialEffectTarget(MARK_SFX3, NPC[506], "overhead")
call AddUnitToStock(NPC[506], QUEST_UNIT[506], 0, 0)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SELL, function Fire)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Quest1 uses SotPQuests, QuestMessageSystem, Ping, CinemaSystems, Quest2
globals
//Core
private constant integer QUEST_ID = 1
private questitem array QUEST_ITEM
//ThisQuestRelated
private constant integer ABIL_CODE = 'A02E'
private integer COUNTER = 0
private integer array MSG_I
private boolean array NPC_BOOLEAN
private unit array UNIT
private Ping array PING
private effect array NOTE
endglobals
function Finish takes nothing returns nothing
call QuestFinish(QUEST_ID)
call PanCameraTo(GetUnitX(HERO), GetUnitY(HERO))
set QUEST_ITEM_DESC[1] = "Speak with Captain Edi"
set QUEST_ITEM_DESC[2] = "Speak with Merchant Abel"
set QUEST_ITEM_DESC[3] = "Speak with Merchant Ida"
set QUEST_ITEM_DESC[4] = "Speak with Lia the Huntress"
set QUEST_ITEM_DESC[5] = "Speak with Eva"
call QuestMsg(QUEST_ID, SOUND_QUEST_COMPLETED, 3, 5, 3, 3, 3, 3, 3, 0, 0, 0)
call QuestAward(QUEST_ID)
call Quest2Start()
endfunction
private function SkipRun takes integer i returns nothing
call DisableCinema()
set SKIP = false
set COUNTER = COUNTER + 1
if COUNTER == 5 then
call QuestItemSetCompleted(QUEST_ITEM[i], true)
call Finish()
return
endif
call QuestItemSetCompleted(QUEST_ITEM[i], true)
set QUEST_ITEM_DESC[1] = "Speak with Captain Edi"
set QUEST_ITEM_DESC[2] = "Speak with Merchant Abel"
set QUEST_ITEM_DESC[3] = "Speak with Merchant Ida"
set QUEST_ITEM_DESC[4] = "Speak with Lia the Huntress"
set QUEST_ITEM_DESC[5] = "Speak with Eva"
set MSG_I[i] = 3
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 5, MSG_I[1], MSG_I[2], MSG_I[3], MSG_I[4], MSG_I[5], 0, 0, 0)
call SetUnitFacingTimed(UNIT[1], 210., 1.)
call SetUnitFacingTimed(UNIT[2], 0., 1.)
call SetUnitFacingTimed(UNIT[3], 270., 1.)
call SetUnitFacingTimed(UNIT[4], 0., 1.)
call SetUnitFacingTimed(UNIT[5], 110., 1.)
call DestroyEffect(NOTE[1])
call DestroyEffect(NOTE[2])
call DestroyEffect(NOTE[3])
call DestroyEffect(NOTE[4])
call DestroyEffect(NOTE[5])
endfunction
private function Run1 takes nothing returns nothing
local integer id = GetUnitTypeId(UNIT[1])
local string name = GetUnitName(UNIT[1])
set NPC_BOOLEAN[1] = true
call RemovePing(PING[1])
call DestroyEffect(NOTE[1])
call EnableCinema()
call FadeIn(2)
call TriggerSleepAction(2)
call SetUnitX(HERO, -18500.)
call SetUnitY(HERO, -2500.)
call SetUnitFacing(HERO, 0.)
call CameraSetupApplyForceDuration(gg_cam_House_01, true, 0)
call TriggerSleepAction(2)
call FadeOut(2)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Greetings Captain. I'm new here and I would like to ask you a few questions if you don't mind.",6,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(5)
call SetUnitFacingTimed(UNIT[1], 180., 1.)
call SetCinematicScene(id,PC1,name,"Hello traveler. I have heard about you from the villagers. What do you want to know?",6,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"I would like to know more about this place.",5,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(id,PC1,name,"Our company came here a few weeks ago to protect this area, on Master Wizard's request.",6,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id,PC1,name,"That is all we were told, but if you ask me, those mages from the Council are always overreacting.",6,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"How so?",3,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(2)
call SetCinematicScene(id,PC1,name,"Well, they seem to think that increased wild life and the supposed 'eerie presence' around here are caused by something. Something big, hiding in the background.",9,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(8)
call SetCinematicScene(id,PC1,name,"But don't let the mages' old wives' tales scare you. The West Imperial Gate is just a few hours away so feel at ease, everything is perfectly safe.",9,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(8)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Thank you for the information, Captain.",4,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(3)
call SetCinematicScene(id,PC1,name,"No problem, traveler. Oh, and if you're interested in earning some coins, drop by again later and maybe I'll have something for you to do.",8,0)
if SKIP then
call SkipRun(1)
return
endif
call TriggerSleepAction(7)
call SkipRun(1)
endfunction
private function Run2 takes nothing returns nothing
local integer id = GetUnitTypeId(UNIT[2])
local string name = GetUnitName(UNIT[2])
set NPC_BOOLEAN[2] = true
call RemovePing(PING[2])
call DestroyEffect(NOTE[2])
call EnableCinema()
call FadeIn(2)
call TriggerSleepAction(2)
call SetUnitX(HERO,-14784.)
call SetUnitY(HERO, 27808.)
call SetUnitFacing(HERO, 90.)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_01, true, 0)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_02, true, 60)
call TriggerSleepAction(2)
call FadeOut(2)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Hello there. I'm new around here and I would like to ask you a few questions if you don't mind.",7,0)
call TriggerSleepAction(6)
call SetUnitFacingTimed(UNIT[2], 270., 1.)
if SKIP then
call SkipRun(2)
return
endif
call SetCinematicScene(id,PC1,name,"Sorry. I'm really busy at the moment.",5,0)
call TriggerSleepAction(4)
if SKIP then
call SkipRun(2)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Okay... I will come back later, then.",5,0)
call TriggerSleepAction(4)
call SkipRun(2)
endfunction
private function Run3 takes nothing returns nothing
local integer id = GetUnitTypeId(UNIT[3])
local string name = GetUnitName(UNIT[3])
set NPC_BOOLEAN[3] = true
call RemovePing(PING[3])
call DestroyEffect(NOTE[3])
call EnableCinema()
call FadeIn(2)
call TriggerSleepAction(2)
call SetUnitX(HERO,-14752.)
call SetUnitY(HERO, 28448.)
call SetUnitFacing(HERO, 0.)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_03, true, 0)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_04, true, 60)
call TriggerSleepAction(2)
call FadeOut(2)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Greetings. I'm new around here and I would like to know more about this place. Do you have some time?",100,0)
call TriggerSleepAction(6)
call SetUnitFacingTimed(UNIT[3], 180., 1.)
if SKIP then
call SkipRun(3)
return
endif
call SetCinematicScene(id,PC1,name,"Greetings to you too, stranger. There are no customers right now so tell me, what do you want to know?",100,0)
call TriggerSleepAction(5)
if SKIP then
call SkipRun(3)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Could you tell me if anyone, including yourself, needs something done in exchange for a reward?",100,0)
call TriggerSleepAction(5)
if SKIP then
call SkipRun(3)
return
endif
call SetCinematicScene(id,PC1,name,"Well, you seem useful enough, but I have nothing to offer you right now. Come back later and maybe something will come up.",100,0)
call TriggerSleepAction(6)
if SKIP then
call SkipRun(3)
return
endif
call SetCinematicScene(id,PC1,name,"You can try asking people all around Waterwille if they have something for you to do.",100,0)
call TriggerSleepAction(5)
if SKIP then
call SkipRun(3)
return
endif
call SetCinematicScene(id,PC1,name,"Oh, if you will excuse me. I have a new customer.",100,0)
call TriggerSleepAction(4)
if SKIP then
call SkipRun(3)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"No problem. Thank you for your time.",100,0)
call TriggerSleepAction(4)
call SkipRun(3)
endfunction
private function Run4 takes nothing returns nothing
local integer id = GetUnitTypeId(UNIT[4])
local string name = GetUnitName(UNIT[4])
set NPC_BOOLEAN[4] = true
call RemovePing(PING[4])
call DestroyEffect(NOTE[4])
call EnableCinema()
call FadeIn(2)
call TriggerSleepAction(2)
call SetUnitX(HERO,-14784.)
call SetUnitY(HERO, 29632.)
call SetUnitFacing(HERO, 0.)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_05, true, 0)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_06, true, 60)
call TriggerSleepAction(2)
call FadeOut(2)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Excuse me, I'm looking for Lia the Huntress.",100,0)
call TriggerSleepAction(4)
call SetUnitFacingTimed(UNIT[4], 180., 1.)
if SKIP then
call SkipRun(4)
return
endif
call SetCinematicScene(id,PC1,name,"You found her. How can I help you?",100,0)
call TriggerSleepAction(4)
if SKIP then
call SkipRun(4)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"I'd like to know more about this place, like hunting grounds and such.",100,0)
call TriggerSleepAction(5)
if SKIP then
call SkipRun(4)
return
endif
call SetCinematicScene(id,PC1,name,"Something strange is happening in forests around here. Usually all you would see are some wild boars and wolf or two here and there.",100,0)
call TriggerSleepAction(7)
if SKIP then
call SkipRun(4)
return
endif
call SetCinematicScene(id,PC1,name,"But lately, I've started to see things... Strange things, on really unusual places...",100,0)
call TriggerSleepAction(5)
if SKIP then
call SkipRun(4)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"What kind of things?",100,0)
call TriggerSleepAction(2)
if SKIP then
call SkipRun(4)
return
endif
call SetCinematicScene(id,PC1,name,"Evil things. Ghosts, walking skeletons and all kinds of fiends. I thought such things exist only in tales, but to actually see them made me question my sanity!",100,0)
call TriggerSleepAction(8)
if SKIP then
call SkipRun(4)
return
endif
call FadeInEx(0,100,0,0)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_07, true, 0)
call TriggerSleepAction(2)
call FadeOut(1)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_05, true, 0)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_06, true, 60)
if SKIP then
call SkipRun(4)
return
endif
call SetCinematicScene(id,PC1,name,"Heed my advice - stay away from dark places and don't walk alone at night. Soldiers came here for a reason.",100,0)
call TriggerSleepAction(6)
if SKIP then
call SkipRun(4)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"I'll be sure to remember it. Have a nice day.",100,0)
call TriggerSleepAction(4)
if SKIP then
call SkipRun(4)
return
endif
call SetUnitFacingTimed(UNIT[4], 0., 1.)
call SetUnitFacingTimed(HERO, 180., 1.)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"I remember now. It was him who attacked me that night!",100,0)
call TriggerSleepAction(4)
call SkipRun(4)
endfunction
private function Run5 takes nothing returns nothing
local integer id = GetUnitTypeId(UNIT[5])
local string name = GetUnitName(UNIT[5])
set NPC_BOOLEAN[5] = true
call RemovePing(PING[5])
call DestroyEffect(NOTE[5])
call EnableCinema()
call FadeIn(2)
call TriggerSleepAction(2)
call SetUnitX(HERO,-17536.)
call SetUnitY(HERO, 26784.)
call SetUnitFacing(HERO, 35.)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_08, true, 0)
call CameraSetupApplyForceDuration(gg_cam_Quest_1_09, true, 60)
call TriggerSleepAction(2)
call FadeOut(2)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Hello ma'am, may I ask you something?",100,0)
call TriggerSleepAction(4)
call SetUnitFacingTimed(UNIT[5], 2010., 1.)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(id,PC1,name,"Oh look at you. Martin really knows how to fix a person.",100,0)
call TriggerSleepAction(4)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"I'm sorry, have we met?",100,0)
call TriggerSleepAction(2)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(id,PC1,name,"My name is Eva. I was with Martin that night when we found you. How are you feeling? Does it hurt anywhere?",100,0)
call TriggerSleepAction(6)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"To tell you the truth, from the moment I woke up, I keep feeling a slight burning pain in the chest. But other that that, I'm fine.",100,0)
call TriggerSleepAction(8)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(id,PC1,name,"It will heal in time, don't worry. Now, you wanted to ask me something?",100,0)
call TriggerSleepAction(5)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Yes. I've never been here before, so if you could just give me some directions.",100,0)
call TriggerSleepAction(6)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(id,PC1,name,"I see. Well, you know where Martin lives, that old house on the edge of the village. If you go right from there you'll find the dock, and if you keep going you will find the Smith, the Town Hall and many other buildings.",100,0)
call TriggerSleepAction(10)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Thank you, Eva. I best get going now.",100,0)
call TriggerSleepAction(3)
if SKIP then
call SkipRun(5)
return
endif
call SetCinematicScene(id,PC1,name,"Take care!",100,0)
call TriggerSleepAction(2)
call SkipRun(5)
endfunction
function Run takes nothing returns nothing
if GetSpellAbilityId() == ABIL_CODE then
if GetSpellTargetUnit() == UNIT[1] and not NPC_BOOLEAN[1] then
call Run1()
elseif GetSpellTargetUnit() == UNIT[2] and not NPC_BOOLEAN[2] then
call Run2()
elseif GetSpellTargetUnit() == UNIT[3] and not NPC_BOOLEAN[3] then
call Run3()
elseif GetSpellTargetUnit() == UNIT[4] and not NPC_BOOLEAN[4] then
call Run4()
elseif GetSpellTargetUnit() == UNIT[5] and not NPC_BOOLEAN[5] then
call Run5()
endif
endif
endfunction
function Quest1Start takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 1
set QUEST_NAME[QUEST_ID] = "Introduction"
set QUEST_DESC[QUEST_ID] = "Hmm... I woke up in Martin's house, near Waterwille village. I should learn more about this place."
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNTownHall.blp", true)
set GOLD_AWARD[QUEST_ID] = 0
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 0
set QUEST_ITEM_DESC[1] = "Speak with Captain Edi"
set QUEST_ITEM_DESC[2] = "Speak with Merchant Abel"
set QUEST_ITEM_DESC[3] = "Speak with Merchant Ida"
set QUEST_ITEM_DESC[4] = "Speak with Lia the Huntress"
set QUEST_ITEM_DESC[5] = "Speak with Eva"
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 5, 1, 1, 1, 1, 1, 0, 0, 0)
set UNIT[1] = gg_unit_h005_0034
set UNIT[2] = gg_unit_h004_0101
set UNIT[3] = gg_unit_h00E_0138
set UNIT[4] = gg_unit_h001_0120
set UNIT[5] = gg_unit_n013_0327
loop
exitwhen i>5
if i == 1 then
set PING[i] = CreatePing(-13920., 28288., 1)
else
set PING[i] = CreatePing(GetUnitX(UNIT[i]), GetUnitY(UNIT[i]), 1)
endif
set NOTE[i] = AddSpecialEffectTarget(MARK_SFX1, UNIT[i], "overhead")
set QUEST_ITEM[i] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[i])
set MSG_I[i] = 2
set i = i+1
endloop
call TriggerRegisterPlayerUnitEvent(trig, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(trig, function Run)
set trig = null
endfunction
endlibrary
//TESH.scrollpos=586
//TESH.alwaysfold=0
library Quest2 uses SotPQuests, QuestMessageSystem, Ping, CinemaSystems, BuildingInOutSystem, Quest3
globals
//Core
private constant integer QUEST_ID = 2
private questitem array QUEST_ITEM
//ThisQuestRelated
private constant integer ABIL_CODE = 'A02E'
private integer COUNTER = 0
private boolean NPC_BOOLEAN
private unit array UNIT
private Ping PING
private effect NOTE
private trigger TRIG = CreateTrigger()
endglobals
private function Finish takes nothing returns nothing
call QuestFinish(QUEST_ID)
call PanCameraTo(GetUnitX(HERO), GetUnitY(HERO))
set QUEST_DESC[QUEST_ID] = "I finished this important quest for Master Wizard, I should now seek and find answers to new ridle Master Wizard got for me."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
call QuestItemSetCompleted(QUEST_ITEM[3], true)
set QUEST_ITEM_DESC[1] = "Speak with Master Wizard"
set QUEST_ITEM_DESC[2] = "Find Imperial Battlemages"
set QUEST_ITEM_DESC[3] = "Bring intel Master Wizard"
call QuestMsg(QUEST_ID, SOUND_QUEST_COMPLETED, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0)
call QuestAward(QUEST_ID)
call Quest3Start()
endfunction
private function SkipRunPart3 takes nothing returns nothing
call DisableCinema()
set SKIP = false
call DestroyTrigger(TRIG)
call SetUnitFacingTimed(UNIT[2], 230., 1.)
call SetUnitFacingTimed(UNIT[3], 250., 1.)
call SetUnitFacingTimed(UNIT[4], 75., 1.)
call Finish()
endfunction
private function RunPart3 takes nothing returns nothing
local integer id = GetUnitTypeId(UNIT[1])
local string name = GetUnitName(UNIT[1])
if GetSpellTargetUnit() != UNIT[1] then
return
endif
call RemovePing(PING)
call DestroyEffect(NOTE)
call EnableCinema()
call FadeIn(2)
call TriggerSleepAction(2)
call SetUnitX(HERO, -14464.)
call SetUnitY(HERO, 27200.)
call SetUnitFacing(HERO, 0.)
call CameraSetupApplyForceDuration(gg_cam_Quest_2_01, true, 0)
call CameraSetupApplyForceDuration(gg_cam_Quest_2_02, true, 80)
call TriggerSleepAction(2)
call FadeOut(2)
call SetUnitFacingTimed(UNIT[1], 180., 1.)
call SetCinematicScene(id,PC1,name,"And so we meet again and I can see you have found something.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Greetings Master Wizard, I bring you intel, that battlemages gathered for you.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id,PC1,name,"Ah you did well, now let me see...",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(id,PC1,name,"Young one, it seams that our the most feared nightmares come true.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id,PC1,name,"Shadow Lord is walking among us once again, he has new host, weak one, but still good enough to handle it's wast power.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(6)
call SetCinematicScene(id,PC1,name,"Now it make sense, Necromancer wasn't tryig to become Lich, he was feeding and summoning Shadow Lord itself.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id,PC1,name,"Listen me now carefuly boy, I will flee to my master and summon imperial council at once, you must find out what that buring mark on your chest means.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(8)
call SetCinematicScene(id,PC1,name,"I was doing some research and there are 2 possiblities, you are choosen to be Shadow Lord new host or you are have elvish blood in your veins.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(7)
call SetCinematicScene(id,PC1,name,"In both cases, that is why you can apsorb shadow essence.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"But what should I do, where to search answers for.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(id,PC1,name,"Not so far from here, you will find my old friend, Trioh, seek him in hidden and dark place.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Thank you, we will be waiting your next orders.",100,0)
if SKIP then
call SkipRunPart3()
return
endif
call TriggerSleepAction(4)
call SkipRunPart3()
endfunction
private function SkipRunPart2 takes nothing returns nothing
call DisableCinema()
set SKIP = false
call SetUnitFacingTimed(UNIT[2], 230., 1.)
call SetUnitFacingTimed(UNIT[3], 250., 1.)
call SetUnitFacingTimed(UNIT[4], 75., 1.)
set PING = CreatePing(GetUnitX(UNIT[1]), GetUnitY(UNIT[1]), 1)
set NOTE = AddSpecialEffectTarget(MARK_SFX1, UNIT[1], "overhead")
call DestroyTrigger(TRIG)
set TRIG = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(TRIG, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(TRIG, function RunPart3)
call QuestItemSetCompleted(QUEST_ITEM[2], true)
set QUEST_DESC[QUEST_ID] = "I should report back to Master Wizard intel I just got. He will know what to do for sure."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
set QUEST_ITEM_DESC[1] = "Speak with Master Wizard"
set QUEST_ITEM_DESC[2] = "Find Imperial Battlemages"
set QUEST_ITEM_DESC[3] = "Bring intel Master Wizard"
set QUEST_ITEM[3] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[3])
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0)
endfunction
private function RunPart2 takes nothing returns nothing
local integer id1 = GetUnitTypeId(UNIT[2])
local integer id2 = GetUnitTypeId(UNIT[3])
local integer id3 = GetUnitTypeId(UNIT[4])
local string name1 = GetUnitName(UNIT[2])
local string name2 = GetUnitName(UNIT[3])
local string name3 = GetUnitName(UNIT[4])
local effect sfx1
local effect sfx2
if GetSpellTargetUnit() != UNIT[2] then
return
endif
call RemovePing(PING)
call DestroyEffect(NOTE)
call EnableCinema()
call FadeIn(2)
call TriggerSleepAction(2)
call SetUnitX(HERO, -9568.)
call SetUnitY(HERO, -3264.)
call SetUnitFacing(HERO, 30.)
call TriggerSleepAction(2)
call FadeOut(2)
call TriggerSleepAction(2)
if SKIP then
call SkipRunPart2()
return
endif
call SetUnitFacingTimed(UNIT[2], 190., 1.)
call SetUnitFacingTimed(UNIT[3], 245., 1.)
call SetUnitFacingTimed(UNIT[4], 150., 1.)
call SetUnitAnimation(UNIT[2], "spell attack")
call SetUnitAnimation(UNIT[3], "spell attack")
set sfx1 = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\AntiMagicShell\\AntiMagicShell.mdl", HERO, "chest")
set sfx2 = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\AntiMagicShell\\AntiMagicShell.mdl", PET, "chest")
call PauseUnit(HERO, true)
call PauseUnit(PET, true)
call SetCinematicScene(id1,PC1,name1,"Hold right there citizen, you are not aloved to be here, please leave this place at once!",100,0)
if SKIP then
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
set sfx1 = null
set sfx2 = null
call PauseUnit(HERO, false)
call PauseUnit(PET, false)
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Excuse me mages, Master Wizard send me, I would like to help.",100,0)
if SKIP then
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
set sfx1 = null
set sfx2 = null
call PauseUnit(HERO, false)
call PauseUnit(PET, false)
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetUnitAnimation(UNIT[3], "spell attack")
call DestroyEffect(sfx1)
call DestroyEffect(sfx2)
set sfx1 = null
set sfx2 = null
call PauseUnit(HERO, false)
call PauseUnit(PET, false)
call SetCinematicScene(id2,PC1,name2,"He must be desperate when he send random weakling.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(id2,PC1,name2,"Leave citizen, you don't want to get hurt or die.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(id3,PC1,name3,"That's enough, stop judging people, instead tell him what we find.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id1,PC1,name1,"As you can see, there are blood, bones and bodies all over this faul place.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id1,PC1,name1,"It was too late, we discovered this hiden place just recently.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id1,PC1,name1,"We found no one alive, and dark magic sence is already too much weak to fallow.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"You must found something, I mean is there any clue who did this, and why.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id2,PC1,name2,"Yes, we was able to to extract some intel, memories to be precise of few dead people.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id1,PC1,name1,"But they are all messed up, look strange and unbeliavable.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"How is so? Please tell me what you saw...",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(3)
call SetCinematicScene(id3,PC1,name3,"We saw small girl, with red, blood like, eyes, killing and tearing apart poor men body.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"What does it mean?",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(3)
call SetCinematicScene(id1,PC1,name1,"We have no idea, but it looked like girls face was changing, constanty geting new shape, like showing someone or something inside it.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(7)
call SetCinematicScene(id3,PC1,name3,"We still have work to do, please send those words to Master Wizard.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Sure, I'm on my way.",100,0)
if SKIP then
call SkipRunPart2()
return
endif
call TriggerSleepAction(5)
set sfx1 = null
call SkipRunPart2()
endfunction
private function SkipRunPart1 takes nothing returns nothing
call DisableCinema()
set SKIP = false
set PING = CreatePing(-18112., 22688., 1)
set NOTE = AddSpecialEffectTarget(MARK_SFX1, UNIT[2], "overhead")
call UnlockBuilding(7)
call UnlockBuilding(8)
call SaveBoolean(BIO_HASH, GetHandleId(gg_unit_n00X_0140), 0, false)
call SaveBoolean(BIO_HASH, GetHandleId(gg_unit_n00X_0114), 0, false)
call SetUnitFacingTimed(UNIT[1], 90., 1.)
call DestroyTrigger(TRIG)
set TRIG = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(TRIG, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(TRIG, function RunPart2)
call QuestItemSetCompleted(QUEST_ITEM[1], true)
set QUEST_DESC[QUEST_ID] = "Master Wizard told me to find his men in a nearby cave and help them in their search for clues about the Necromancer."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
set QUEST_ITEM_DESC[1] = "Speak with Master Wizard"
set QUEST_ITEM_DESC[2] = "Find Imperial Battlemages"
set QUEST_ITEM[2] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[2])
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 3, 2, 3, 1, 0, 0, 0, 0, 0, 0)
endfunction
private function RunPart1 takes nothing returns nothing
local integer id = GetUnitTypeId(UNIT[1])
local string name = GetUnitName(UNIT[1])
if GetSpellTargetUnit() != UNIT[1] then
return
endif
call RemovePing(PING)
call DestroyEffect(NOTE)
call EnableCinema()
call FadeIn(2)
call TriggerSleepAction(2)
call SetUnitX(HERO, -14464.)
call SetUnitY(HERO, 27200.)
call SetUnitFacing(HERO, 0.)
call CameraSetupApplyForceDuration(gg_cam_Quest_2_01, true, 0)
call CameraSetupApplyForceDuration(gg_cam_Quest_2_02, true, 80)
call TriggerSleepAction(2)
call FadeOut(2)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Excuse me Master Wizard, may I have a moment of your time.",100,0)
call SetUnitFacingTimed(UNIT[1], 180., 1.)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id,PC1,name,"Ah! Greetings " + HERO_NAME + ", and welcome to Waterville.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"How you know my name?",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(3)
call SetCinematicScene(id,PC1,name,"I'm the 2nd most powerful mage in the land. I know many things, young one.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Well then, can you first tell me what is this increasing pain in my chest? It's not healing at all!",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(6)
call SetCinematicScene(id,PC1,name,"The pain you feel is most likely a side-effect due to the damage left by the Dark magic cast upon you.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(6)
call SetCinematicScene(id,PC1,name,"I must say, in all my long years of studying magic, I have never came across anything similar to your case. ",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(6)
call SetCinematicScene(id,PC1,name,"According to what we know, you should either be dead or a walking undead with no mind of his own. This is very peculiar indeed...",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(7)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Dark magic? Is that what happened to me? And why can't I remember anything except the figure of an old man wearing strange clothing?",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(8)
call SetCinematicScene(id,PC1,name,"The man you saw is responsible for your condition. He is a Necromancer, perhaps the most powerful one there is. You shouldn't be asking yourself why are your memories gone, but rather why are you even alive!",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(10)
call SetCinematicScene(id,PC1,name,"We've been tracking him, or more precisely, his 'work' for some time now, and usually when he is through with someone, there is nothing left of that person.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(8)
call CameraSetupApplyForceDuration(gg_cam_Quest_2_03, true, 80)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"A Necromancer... I never saw one, or at least, I don't think so...",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Wait, is he responsible for all this madness? Why can't you just hunt him down?",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(6)
call SetCinematicScene(id,PC1,name,"I'm afraid it is not so simple. Even my master can't track his presence.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(5)
call SetCinematicScene(id,PC1,name,"He gained possession over a rare relic, created by the Ancient Elves themselves, which erases the wielder's very presence.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(7)
call SetCinematicScene(id,PC1,name,"Our magic is not strong enough to dispel the relic's magic.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(id,PC1,name,"As for what is happening here, we are still investigating. We believe it is a type of plague, which he caused not to simply pollute mankind, but rather to make his own personal army.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(9)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"He's building an army? What for? Regardless of numbers, he will never be able to win against the whole empire!",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(7)
call SetCinematicScene(id,PC1,name,"Exactly. We have the strongest army of high-class Imperial Knights and the most well trained Battlemages.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(6)
call SetCinematicScene(id,PC1,name,"Knowing that, the Council thinks he is trying to find a way to transform himself into a Lich - a pure entity of Dark magic, with far more greater capacity for evil.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(8)
call CameraSetupApplyForceDuration(gg_cam_Quest_2_01, true, 80)
call SetCinematicScene(id,PC1,name,"If we don't stop him, there is no telling what devastation will he be able to unleash upon the land!",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(6)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"That's terrible! We must stop him at all costs!",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(id,PC1,name,"I commend your enthusiasm, young one. As such, would you be willing to help our cause and stop that vile necromancer?",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(6)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Of course! Anything you say!",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(3)
call SetCinematicScene(id,PC1,name,"Good. Some of my finest men went into a nearby cave, looking for clues about his current whereabouts. Maybe you can help them as well.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(7)
call SetCinematicScene(id,PC1,name,"Here, let me mark it on your map.",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(4)
call SetCinematicScene(HERO_ID,PC0,HERO_NAME,"Thank you, sir. I will do my best!",100,0)
if SKIP then
call SkipRunPart1()
return
endif
call TriggerSleepAction(4)
call SkipRunPart1()
endfunction
function Quest2Start takes nothing returns nothing
local integer i = 1
set QUEST_NAME[QUEST_ID] = "Burning Mark"
set QUEST_DESC[QUEST_ID] = "I should speak with Master Wizard about this pain in my chest. It feels like it's not healing, but rather steadily growing even more painful..."
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNImmolationOn.blp", true)
set GOLD_AWARD[QUEST_ID] = 0
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 0
set QUEST_ITEM_DESC[1] = "Speak with Master Wizard"
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[1] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[1])
set UNIT[1] = gg_unit_h013_0274 //Master Wizard
set UNIT[2] = gg_unit_h00I_0122 //Imperial Battlemage: Conjuration
set UNIT[3] = gg_unit_h00J_0117 //Imperial Battlemage: Restoration
set UNIT[4] = gg_unit_h029_0116 //Imperial Battlemage: Destruction
set PING = CreatePing(GetUnitX(UNIT[1]), GetUnitY(UNIT[1]), 1)
set NOTE = AddSpecialEffectTarget(MARK_SFX1, UNIT[1], "overhead")
call UnlockBuilding(7)
call UnlockBuilding(8)
call TriggerRegisterPlayerUnitEvent(TRIG, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(TRIG, function RunPart1)
endfunction
endlibrary
//TESH.scrollpos=18
//TESH.alwaysfold=0
library Quest3 uses SotPQuests, QuestMessageSystem, Ping, CinemaSystems, BuildingInOutSystem
globals
//Core
private constant integer QUEST_ID = 3
private questitem array QUEST_ITEM
//ThisQuestRelated
private constant integer ABIL_CODE = 'A02E'
private integer COUNTER = 0
private boolean NPC_BOOLEAN
private unit array UNIT
private Ping PING
private effect NOTE
private trigger TRIG = CreateTrigger()
endglobals
private function Finish takes nothing returns nothing
endfunction
private function SkipRunPart1 takes nothing returns nothing
call DestroyTrigger(TRIG)
endfunction
private function RunPart1 takes nothing returns nothing
local integer id = GetUnitTypeId(UNIT[1])
local string name = GetUnitName(UNIT[1])
if GetSpellTargetUnit() != UNIT[1] then
return
endif
call SkipRunPart1()
endfunction
function Quest3Start takes nothing returns nothing
local integer i = 1
set QUEST_NAME[QUEST_ID] = "Raise of the Fallen"
set QUEST_DESC[QUEST_ID] = ""
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNArcher.blp", true)
set GOLD_AWARD[QUEST_ID] = 0
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 0
set QUEST_ITEM_DESC[1] = "Find Trioh Hideout"
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[1] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[1])
set UNIT[1] = gg_unit_h00Y_0045 //Trioh
set PING = CreatePing(GetUnitX(gg_unit_n00X_0113), GetUnitY(gg_unit_n00X_0113), 1)
set NOTE = AddSpecialEffectTarget(MARK_SFX1, UNIT[1], "overhead")
call UnlockBuilding(5)
call UnlockBuilding(6)
call SaveBoolean(BIO_HASH, GetHandleId(gg_unit_n00X_0113), 0, false)
call SaveBoolean(BIO_HASH, GetHandleId(gg_unit_n00X_0009), 0, false)
call TriggerRegisterPlayerUnitEvent(TRIG, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerAddAction(TRIG, function RunPart1)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct quest501 extends array
private static constant integer QUEST_ID = 501
private static questitem array QUEST_ITEM
private static integer COUNTER = 0
private static integer MAX = 20
private static trigger T = CreateTrigger()
private static method run takes nothing returns nothing
if GetOwningPlayer(GetKillingUnit()) != Player(0) then
return
endif
if COUNTER < MAX then
set COUNTER = COUNTER + 1
endif
if COUNTER == MAX then
call DestroyTrigger(T)
call AddUnitToStock(NPC[QUEST_ID], QUEST_UNIT[1000+QUEST_ID], 0, 0)
call QuestItemSetCompleted(QUEST_ITEM[1], true)
set QUEST_ITEM_DESC[1] = "Slay 20 animals (20/20)"
set QUEST_ITEM_DESC[2] = "Return to Lia and claim your award"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 2, 3, 1, 0, 0, 0, 0, 0, 0)
set SFX[QUEST_ID] = AddSpecialEffectTarget(MARK_SFX2, NPC[QUEST_ID], "overhead")
set QUEST_ITEM[2] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[2])
call QuestItemSetDescription(QUEST_ITEM[1], QUEST_ITEM_DESC[1])
call QuestItemSetDescription(QUEST_ITEM[2], QUEST_ITEM_DESC[2])
set QUEST_DESC[QUEST_ID] = "I have killed 20 animals as Lia the Hunter wanted. I can claim my reward now."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
else
set QUEST_ITEM_DESC[1] = "Slay 20 animals (" + I2S(COUNTER) + "/20)."
call QuestItemSetDescription(QUEST_ITEM[1], QUEST_ITEM_DESC[1])
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0)
endif
endmethod
static method finish takes nothing returns nothing
call QuestFinish(QUEST_ID)
set QUEST_ITEM_DESC[1] = "Slay 20 animals (20/20)"
set QUEST_ITEM_DESC[2] = "Return to Lia and claim your award"
call QuestItemSetCompleted(QUEST_ITEM[2], true)
call QuestMsg(QUEST_ID, SOUND_QUEST_COMPLETED, 3, 2, 3, 3, 0, 0, 0, 0, 0, 0)
call QuestAward(QUEST_ID)
call QuestAwardEx(QUEST_ID)
endmethod
static method start takes nothing returns nothing
set QUEST_NAME[QUEST_ID] = "The Hunter In Training"
set QUEST_DESC[QUEST_ID] = "I met a strange woman in the woods by the name Lia the Hunter. She challenged me into hunting 20 any kind of forest animals. If I'm successful, she will show me some useful hunting tricks."
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNTimberWolf.blp", false)
set GOLD_AWARD[QUEST_ID] = 100
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 250
set QUEST_ITEM_DESC[1] = "Slay 20 animals (0/20)"
set QUEST_ITEM[1] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[1])
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
call TriggerRegisterPlayerUnitEvent(T, Player(10), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddAction(T, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=37
//TESH.alwaysfold=0
struct quest502 extends array
private static constant integer QUEST_ID = 502
private static questitem array QUEST_ITEM
private static item ITEM_1
private static item ITEM_2
private static integer I_1 = 2
private static integer I_2 = 2
private static trigger T = CreateTrigger()
private static Ping array PING
private static method run takes nothing returns nothing
if GetManipulatedItem() == ITEM_1 then
set I_1 = 3
call QuestItemSetCompleted(QUEST_ITEM[1], true)
call RemovePing(PING[1])
elseif GetManipulatedItem() == ITEM_2 then
set I_2 = 3
call QuestItemSetCompleted(QUEST_ITEM[2], true)
call RemovePing(PING[2])
else
return
endif
call RemoveItem(GetManipulatedItem())
if I_1 == 3 and I_2 == 3 then
call DestroyTrigger(T)
call AddUnitToStock(NPC[QUEST_ID], QUEST_UNIT[1000+QUEST_ID], 0, 0)
call QuestItemSetCompleted(QUEST_ITEM[1], true)
call QuestItemSetCompleted(QUEST_ITEM[2], true)
set QUEST_ITEM_DESC[1] = "Find and collect a Xerophyllum Flower"
set QUEST_ITEM_DESC[2] = "Find and collect a Dark Xerophyllum Flower"
set QUEST_ITEM_DESC[3] = "Return to Abel and claim your award"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 3, 3, 3, 1, 0, 0, 0, 0, 0)
set SFX[QUEST_ID] = AddSpecialEffectTarget(MARK_SFX2, NPC[QUEST_ID], "overhead")
set QUEST_ITEM[3] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[3])
set QUEST_DESC[QUEST_ID] = "I have found the flowers Abel wanted. I need to take them back to him and collect my award."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
else
set QUEST_ITEM_DESC[1] = "Find and collect a Xerophyllum Flower"
set QUEST_ITEM_DESC[2] = "Find and collect a Dark Xerophyllum Flower"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 2, I_1, I_2, 0, 0, 0, 0, 0, 0)
endif
endmethod
static method finish takes nothing returns nothing
call QuestFinish(QUEST_ID)
call QuestItemSetCompleted(QUEST_ITEM[3], true)
set QUEST_ITEM_DESC[1] = "Find and collect a Xerophyllum Flower"
set QUEST_ITEM_DESC[2] = "Find and collect a Dark Xerophyllum Flower"
set QUEST_ITEM_DESC[3] = "Return to Abel and claim your award"
call QuestMsg(QUEST_ID, SOUND_QUEST_COMPLETED, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0)
call QuestAward(QUEST_ID)
endmethod
static method start takes nothing returns nothing
set QUEST_NAME[QUEST_ID] = "Alchemist’s Assistant"
set QUEST_DESC[QUEST_ID] = "An old old man named Abel offerd me a reward if I find some two rare plants."
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNShimmerWeed.blp", false)
set GOLD_AWARD[QUEST_ID] = 200
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 0
set QUEST_ITEM_DESC[1] = "Find and collect a Xerophyllum Flower"
set QUEST_ITEM_DESC[2] = "Find and collect a Dark Xerophyllum Flower"
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 2, 1, 1, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[1] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[1])
set QUEST_ITEM[2] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[2])
set ITEM_1 = CreateItem('I013', -18575. , 25850. ) //Xerophyllum Flower
set ITEM_2 = CreateItem('I014', -12185. , 29040. ) //Dark Xerophyllum Flower
set PING[1] = CreatePing(GetItemX(ITEM_1), GetItemY(ITEM_1), 0)
set PING[2] = CreatePing(GetItemX(ITEM_2), GetItemY(ITEM_2), 0)
call TriggerRegisterPlayerUnitEvent(T, Player(0), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
call TriggerAddAction(T, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=67
//TESH.alwaysfold=0
struct quest503 extends array
private static constant integer QUEST_ID = 503
private static questitem array QUEST_ITEM
private static item ITEM
private static unit UNIT1
private static unit UNIT2
private static integer STAGE = 1
private static trigger T = CreateTrigger()
private static Ping PING
private static method run takes nothing returns nothing
if STAGE == 1 then
if GetEnteringUnit() == HERO then
call IssueImmediateOrder(HERO, "stop")
call CreateMessage(QUEST_ID,2)
call AddQuestMessage(QUEST_ID, GetUnitName(UNIT1) + ":|c00FFFFFF \n\nI saw these crates floating when \na bandit jumped me out of nowhere. \nHe took whatever was in them and \nran in the woods. \n\nKill him for me...")
call AddQuestMessage(QUEST_ID, "Arkail:|c00FFFFFF \n\nThank you warrior. \nI will avenge you so you can rest in pice!")
call EditMessage()
set QUEST_ITEM_DESC[1] = "Find Admiral John's Magic Magic Amulet"
set QUEST_ITEM_DESC[2] = "Find the bandit that collected the cargo and slay him"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[2] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[2])
set UNIT2 = CreateUnit(Player(11),'n001', -10700. , 18450. , 180.) //Grimzow
call RemovePing(PING)
set PING = CreatePing(GetUnitX(UNIT2), GetUnitY(UNIT2), 0)
set QUEST_DESC[QUEST_ID] = "I found the crates and a dying man named Warek lying next to them. he told me that a bandit attacked him, ransacked the crates and ran into the forest. I must find him and kill him."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
set STAGE = 2
endif
elseif STAGE == 2 then
if GetDyingUnit() == UNIT2 then
call RemoveUnit(UNIT1)
set QUEST_ITEM_DESC[1] = "Find and collect a Magic Amulet"
set QUEST_ITEM_DESC[2] = "Find the bandit that collected the cargo and slay him"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0)
set ITEM = CreateItem('I019', GetUnitX(UNIT2) , GetUnitY(UNIT2) ) //Magic Amulet
call RemovePing(PING)
set PING = CreatePing(GetItemX(ITEM), GetItemY(ITEM), 0)
call QuestItemSetCompleted(QUEST_ITEM[2], true)
set QUEST_DESC[QUEST_ID] = "I have the bandit who stole the cargo. I need to retrieve the Amulet."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
set STAGE = 3
endif
elseif STAGE == 3 then
if GetManipulatedItem() == ITEM then
call RemoveItem(GetManipulatedItem())
call AddUnitToStock(NPC[QUEST_ID], QUEST_UNIT[1000+QUEST_ID], 0, 0)
call RemovePing(PING)
set PING = CreatePing(GetUnitX(NPC[QUEST_ID]), GetUnitY(NPC[QUEST_ID]), 0)
set QUEST_ITEM_DESC[1] = "Find and collect a Magic Amulet"
set QUEST_ITEM_DESC[2] = "Find the bandit that collected the cargo and slay him"
set QUEST_ITEM_DESC[3] = "Return the Amulet to Admiral John"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 3, 3, 3, 1, 0, 0, 0, 0, 0)
set QUEST_ITEM[3] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[3])
call QuestItemSetCompleted(QUEST_ITEM[1], true)
set SFX[QUEST_ID] = AddSpecialEffectTarget(MARK_SFX2, NPC[QUEST_ID], "overhead")
set QUEST_DESC[QUEST_ID] = "I got the Amulet. I should take it to Admiral John and collect my reward."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
call DestroyTrigger(T)
endif
else
return
endif
endmethod
static method finish takes nothing returns nothing
call QuestFinish(QUEST_ID)
call QuestItemSetCompleted(QUEST_ITEM[3], true)
set QUEST_ITEM_DESC[1] = "Find and collect a Magic Amulet"
set QUEST_ITEM_DESC[2] = "Find the bandit that collected the cargo and slay him"
set QUEST_ITEM_DESC[3] = "Return the Amulet to Admiral John"
call QuestMsg(QUEST_ID, SOUND_QUEST_COMPLETED, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0)
call QuestAward(QUEST_ID)
call RemovePing(PING)
endmethod
static method start takes nothing returns nothing
local region rectRegion = CreateRegion()
set QUEST_NAME[QUEST_ID] = "Lost Cargo"
set QUEST_DESC[QUEST_ID] = "Admiral John lost one of his ship cargo in storm few days ago, he said that people saw some of goods floating carried by river. He just care about some old magic neclace that was ordered by some old and respected customer. He promised nice award for it."
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNCrate.blp", false)
set GOLD_AWARD[QUEST_ID] = 350
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 0
set QUEST_ITEM_DESC[1] = "Find and collect a Magic Amulet"
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[1] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[1])
set UNIT1 = CreateUnit(Player(1),'h01G', -14000. , 22850. , 270.) //Warek
set PING = CreatePing(GetUnitX(UNIT1), GetUnitY(UNIT1), 0)
call SetUnitAnimation( UNIT1, "death" )
call SetUnitInvulnerable( UNIT1, true )
call SetUnitState(UNIT1, UNIT_STATE_LIFE, 1)
call PauseUnit(UNIT1, true)
call TriggerRegisterPlayerUnitEvent(T, Player(0), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
call RegionAddRect(rectRegion, gg_rct_QUEST503_Rect)
call TriggerRegisterEnterRegion(T, rectRegion, null)
call TriggerRegisterPlayerUnitEvent(T, Player(11), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddAction(T, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=70
//TESH.alwaysfold=0
struct quest504 extends array
private static constant integer QUEST_ID = 504
private static questitem array QUEST_ITEM
private static item ITEM
private static unit UNIT1
private static unit UNIT2
private static integer STAGE = 1
private static trigger T = CreateTrigger()
private static region R
private static Ping PING
private static method run takes nothing returns nothing
if STAGE == 1 then
if GetEnteringUnit() == HERO then
call DisableTrigger(T)
call IssueImmediateOrder(HERO, "stop")
call CreateMessage(QUEST_ID,4)
call AddQuestMessage(QUEST_ID, GetUnitName(UNIT1) + ":|c00FFFFFF \n\nPssst, hey, I'm Ghan, \nUpir send something for me?")
call AddQuestMessage(QUEST_ID, "Arkail:|c00FFFFFF \n\nYeah, here, this message, \nbut how you know I will be the one...")
call AddQuestMessage(QUEST_ID, GetUnitName(UNIT1) + ":|c00FFFFFF \n\nSush, let me read...")
call AddQuestMessage(QUEST_ID, GetUnitName(UNIT1) + ":|c00FFFFFF \n\nInteresting, ok now take this note back to Upir! Go go go.")
call EditMessage()
call SetUnitInvulnerable( UNIT1, false )
call QuestItemSetCompleted(QUEST_ITEM[1], true)
set QUEST_ITEM_DESC[1] = "Find person named Ghan and show him message."
set QUEST_ITEM_DESC[2] = "Return back to Upir with new message"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 2, 3, 1, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[2] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[2])
set UNIT2 = NPC[4] //Upir
call RemovePing(PING)
set PING = CreatePing(GetUnitX(UNIT2), GetUnitY(UNIT2), 0)
set QUEST_DESC[QUEST_ID] = "Strange those two guys look little crazy, I must now go back to Upir once again."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
call RegionClearRect(R, gg_rct_QUEST504_Rect_1)
call RegionAddRect(R, gg_rct_QUEST504_Rect_2)
set STAGE = 2
call EnableTrigger(T)
endif
elseif STAGE == 2 then
if GetEnteringUnit() == HERO then
call DisableTrigger(T)
call IssueImmediateOrder(HERO, "stop")
call CreateMessage(QUEST_ID,3)
call AddQuestMessage(QUEST_ID, GetUnitName(UNIT2) + ":|c00FFFFFF \n\nHmmmmm, interesting for sure...")
call AddQuestMessage(QUEST_ID, "Arkail:|c00FFFFFF \n\nAnything for me sir, \nwhat should I do now?")
call AddQuestMessage(QUEST_ID, GetUnitName(UNIT2) + ":|c00FFFFFF \n\nThat would be all fellow, \nI don't have nothing to give you now \nbut I have hidden gold somewhere near camp, \nsearch for barrels or crates, \nif you find it you are free to take it.")
call EditMessage()
call QuestItemSetCompleted(QUEST_ITEM[2], true)
set QUEST_ITEM_DESC[1] = "Find person named Ghan and show him message."
set QUEST_ITEM_DESC[2] = "Return back to Upir with new message"
set QUEST_ITEM_DESC[3] = "I should colect award hiden in barrels somewhere near Camp."
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 3, 3, 3, 1, 0, 0, 0, 0, 0)
set QUEST_ITEM[3] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[3])
set ITEM = CreateItem('I005', -14016. , 25792. ) //Award
call RemovePing(PING)
set PING = CreatePing(GetItemX(ITEM), GetItemY(ITEM), 0)
call QuestItemSetCompleted(QUEST_ITEM[2], true)
set QUEST_DESC[QUEST_ID] = "I should look for award hidden somewhere in barrels or crates located next to Camp."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
set STAGE = 3
call EnableTrigger(T)
endif
elseif STAGE == 3 then
if GetManipulatedItem() == ITEM then
call RemoveItem(GetManipulatedItem())
set QUEST_DESC[QUEST_ID] = "Finally I found it, but what is this 1 gold coin, those guys are crazy for sure."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
call DestroyTrigger(T)
call thistype.finish()
endif
else
return
endif
endmethod
static method finish takes nothing returns nothing
call QuestFinish(QUEST_ID)
call QuestItemSetCompleted(QUEST_ITEM[3], true)
set QUEST_ITEM_DESC[1] = "Find person named Ghan and show him message."
set QUEST_ITEM_DESC[2] = "Return back to Upir with new message"
set QUEST_ITEM_DESC[3] = "I should colect award hiden in barrels somewhere near Camp."
call QuestMsg(QUEST_ID, SOUND_QUEST_COMPLETED, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0)
call QuestAward(QUEST_ID)
call RemovePing(PING)
endmethod
static method start takes nothing returns nothing
set R = CreateRegion()
set QUEST_NAME[QUEST_ID] = "Urgent Message"
set QUEST_DESC[QUEST_ID] = "An old man, named Upir, was upset about something he call Eye of the Storm. I must find man named Ghan and give him this small letter Upir gave me. It's crucial to deliver mesage personally."
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNScrollOfProtection.blp", false)
set GOLD_AWARD[QUEST_ID] = 1
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 0
set QUEST_ITEM_DESC[1] = "Find person named Ghan and show him message."
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[1] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[1])
set UNIT1 = CreateUnit(Player(1),'n011', -13248. , 28576. , 0.) //Ghan
set PING = CreatePing(GetUnitX(UNIT1), GetUnitY(UNIT1), 0)
call SetUnitInvulnerable( UNIT1, true )
call TriggerRegisterPlayerUnitEvent(T, Player(0), EVENT_PLAYER_UNIT_PICKUP_ITEM, null)
call RegionAddRect(R, gg_rct_QUEST504_Rect_1)
call TriggerRegisterEnterRegion(T, R, null)
call TriggerAddAction(T, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct quest505 extends array
private static constant integer QUEST_ID = 505
private static questitem array QUEST_ITEM
private static unit UNIT
private static timer TIMER = CreateTimer()
private static trigger T = CreateTrigger()
private static region R
private static Ping PING
private static method run takes nothing returns nothing
local unit u
if not (GetFloatGameState(GAME_STATE_TIME_OF_DAY) <= 6 or GetFloatGameState(GAME_STATE_TIME_OF_DAY) > 12) then
return
endif
if GetEnteringUnit() == HERO then
call PauseTimer(TIMER)
call DestroyTimer(TIMER)
call KillUnit(UNIT)
set u = CreateUnit(Player(15),'h01W', -9420. , 29850 , 270.)
call UnitApplyTimedLife(u, 'BTLF', 3)
set u = CreateUnit(Player(0),'h01V', -9420. , 29850 , 270.)
call UnitAddAbility(u, 'ACnr')
call UnitAddAbility(u, 'ANre')
set u = null
set QUEST_DESC[QUEST_ID] = "Such wonderful effects, magic power is really beautiful here."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
call DestroyTrigger(T)
call RemoveRegion(R)
call thistype.finish()
endif
endmethod
static method finish takes nothing returns nothing
call QuestFinish(QUEST_ID)
call QuestItemSetCompleted(QUEST_ITEM[1], true)
set QUEST_ITEM_DESC[1] = "Bring owl during night near Misty Cave."
call QuestMsg(QUEST_ID, SOUND_QUEST_COMPLETED, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0)
call QuestAward(QUEST_ID)
call RemovePing(PING)
call UnlockBuilding(9)
call UnlockBuilding(10)
endmethod
static method issueOrder takes nothing returns nothing
if not IS_IN_BUILDING then
call IssuePointOrder(UNIT, "move", GetUnitX(HERO) + GetRandomReal(-250, 250), GetUnitY(HERO) + GetRandomReal(-250, 250))
endif
endmethod
static method start takes nothing returns nothing
set R = CreateRegion()
set QUEST_NAME[QUEST_ID] = "Guardian of the Night"
set QUEST_DESC[QUEST_ID] = "Galldora the Enchantress said that if I bring spirit owl with miself on night into Misty Cave I will be able to unlock it's magic."
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNSentinel.blp", false)
set GOLD_AWARD[QUEST_ID] = 0
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 250
set QUEST_ITEM_DESC[1] = "Bring owl during night near Misty Cave."
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[1] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[1])
set UNIT = CreateUnit(Player(15),'h01T', GetUnitX(HERO) , GetUnitY(HERO) , 0.) //Owl
set PING = CreatePing(GetRectCenterX(gg_rct_QUEST505_Rect), GetRectCenterY(gg_rct_QUEST505_Rect), 0)
call TimerStart(TIMER, 1.25, true, function thistype.issueOrder)
call RegionAddRect(R, gg_rct_QUEST505_Rect)
call TriggerRegisterEnterRegion(T, R, null)
call TriggerAddAction(T, function thistype.run)
endmethod
endstruct
//TESH.scrollpos=109
//TESH.alwaysfold=0
struct quest506 extends array
private static constant integer QUEST_ID = 506
private static questitem array QUEST_ITEM
private static item ITEM
private static unit array UNIT
private static integer COUNTER = 0
private static integer MAX = 5
private static integer STAGE = 1
private static region REGION
private static trigger T = CreateTrigger()
private static Ping PING
private static method stageDelay4 takes nothing returns nothing
call IssueImmediateOrder(HERO, "stop")
call CreateMessage(QUEST_ID,1)
call AddQuestMessage(QUEST_ID, "Arkail:|c00FFFFFF \n\nA bandit hideout!")
call EditMessage()
set QUEST_ITEM_DESC[1] = "Investigate Tom Watson House"
set QUEST_ITEM_DESC[2] = "Search the basement"
set QUEST_ITEM_DESC[3] = "Slay the giant spider"
set QUEST_ITEM_DESC[4] = "Search the strange hole"
set QUEST_ITEM_DESC[5] = "Slay the bandits in new found hideout"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 5, 2, 2, 3, 2, 1, 0, 0, 0)
set QUEST_ITEM[5] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[5])
call RegionClearRect(REGION, gg_rct_QUEST506_Rect_3)
call UnlockBuilding(21)
call UnlockBuilding(22)
set QUEST_DESC[QUEST_ID] = "I have discovered bandit hideout in tunnels below Waterville Village. I should slay all of them and bring peace to Village once again"
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
endmethod
private static method stageDelay3 takes nothing returns nothing
call RemoveUnit(UNIT[0])
call CreateMessage(QUEST_ID,1)
call AddQuestMessage(QUEST_ID, "Arkail:|c00FFFFFF \n\nWhat a powerful creature. \n\nThere is a hole in a wall it must come true there! \nI should check it out.")
call EditMessage()
set QUEST_ITEM_DESC[1] = "Investigate Tom Watson House"
set QUEST_ITEM_DESC[2] = "Search the basement"
set QUEST_ITEM_DESC[3] = "Slay the giant spider"
set QUEST_ITEM_DESC[4] = "Search the strange hole"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 4, 2, 2, 3, 1, 0, 0, 0, 0)
call QuestItemSetCompleted(QUEST_ITEM[3], true)
set QUEST_ITEM[4] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[4])
set UNIT[1] = CreateUnit(Player(11), 'n006', -7552.00, -896.00, 220.00)
set UNIT[2] = CreateUnit(Player(11), 'n007', -7296.00, -992.00, 220.00)
set UNIT[3] = CreateUnit(Player(11), 'n006', -7072.00, -1920.00, 120.00)
set UNIT[4] = CreateUnit(Player(11), 'n007', -7008.00, -1696.00, 120.00)
set UNIT[5] = CreateUnit(Player(11), 'n006', -7936.00, -1888.00, 90.00)
call UnlockBuilding(19)
call UnlockBuilding(20)
set QUEST_DESC[QUEST_ID] = "There is strange hole in basement wall. It seams it leads to some kind of cave. I should keep going."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
endmethod
private static method stageDelay2 takes nothing returns nothing
call IssueImmediateOrder(HERO, "stop")
call CreateMessage(QUEST_ID,1)
call AddQuestMessage(QUEST_ID, "Arkail:|c00FFFFFF \n\nWhat on earth is that. \nI should slay it right away!")
call EditMessage()
set QUEST_ITEM_DESC[1] = "Investigate Tom Watson House"
set QUEST_ITEM_DESC[2] = "Search the basement"
set QUEST_ITEM_DESC[3] = "Slay the giant spider"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 3, 2, 2, 1, 0, 0, 0, 0, 0)
set QUEST_ITEM[3] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[3])
call RegionClearRect(REGION, gg_rct_QUEST506_Rect_2)
set QUEST_DESC[QUEST_ID] = "I found huge hostile spider in basement of Tom Watson's hose. I should slay him and continue my research."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
endmethod
private static method stageDelay1 takes nothing returns nothing
call IssueImmediateOrder(HERO, "stop")
call CreateMessage(QUEST_ID,1)
call AddQuestMessage(QUEST_ID, "Arkail:|c00FFFFFF \n\nThere is nothing strange here. \nI should check basement perhaps.")
call EditMessage()
set QUEST_ITEM_DESC[1] = "Investigate Tom Watson House"
set QUEST_ITEM_DESC[2] = "Search the basement"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[2] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[2])
call QuestItemSetDescription(QUEST_ITEM[2], QUEST_ITEM_DESC[2])
set UNIT[0] = CreateUnit(Player(11),'n015', -16832. , -3648. , 90.) //Shiva the Spider
call RemovePing(PING)
call RegionClearRect(REGION, gg_rct_QUEST506_Rect_1)
call UnlockBuilding(17)
call UnlockBuilding(18)
set QUEST_DESC[QUEST_ID] = "I found nothing in Tom Watson's house, I should search the basement."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
endmethod
private static method run takes nothing returns nothing
if STAGE == 1 then
if GetEnteringUnit() == HERO then
set STAGE = 2
call TimerStart(CreateTimer(), 3.00, false, function thistype.stageDelay1 )
endif
elseif STAGE == 2 then
if GetEnteringUnit() == HERO then
set STAGE = 3
call TimerStart(CreateTimer(), 3.00, false, function thistype.stageDelay2 )
endif
elseif STAGE == 3 then
if GetDyingUnit() == UNIT[0] then
set STAGE = 4
call TimerStart(CreateTimer(), 3.00, false, function thistype.stageDelay3 )
endif
elseif STAGE == 4 then
if GetEnteringUnit() == HERO then
set STAGE = 5
call TimerStart(CreateTimer(), 3.00, false, function thistype.stageDelay4 )
endif
elseif STAGE == 5 then
if GetDyingUnit() == UNIT[1] or GetDyingUnit() == UNIT[2] or GetDyingUnit() == UNIT[3] or GetDyingUnit() == UNIT[4] or GetDyingUnit() == UNIT[5] then
if COUNTER < MAX then
set COUNTER = COUNTER + 1
endif
if COUNTER == MAX then
call DestroyTrigger(T)
call AddUnitToStock(NPC[QUEST_ID], QUEST_UNIT[1000+QUEST_ID], 0, 0)
call QuestItemSetCompleted(QUEST_ITEM[5], true)
set QUEST_ITEM_DESC[1] = "Investigate Tom Watson House"
set QUEST_ITEM_DESC[2] = "Search the basement"
set QUEST_ITEM_DESC[3] = "Slay the giant spider"
set QUEST_ITEM_DESC[4] = "Search the strange hole"
set QUEST_ITEM_DESC[5] = "Slay the bandits in new found hideout"
set QUEST_ITEM_DESC[6] = "Return to Tom Watson"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 2, 6, 2, 2, 3, 2, 3, 1, 0, 0)
set SFX[QUEST_ID] = AddSpecialEffectTarget(MARK_SFX2, NPC[QUEST_ID], "overhead")
set QUEST_ITEM[6] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[6])
set QUEST_DESC[QUEST_ID] = "I have slayed bandits in hideout. I should now return and speak with Tom Watson."
call QuestSetDescription(QUEST[QUEST_ID], QUEST_DESC[QUEST_ID])
set STAGE = 6
endif
call RemoveUnit(GetDyingUnit())
endif
endif
endmethod
static method finish takes nothing returns nothing
call QuestFinish(QUEST_ID)
call QuestItemSetCompleted(QUEST_ITEM[1], true)
call QuestItemSetCompleted(QUEST_ITEM[2], true)
call QuestItemSetCompleted(QUEST_ITEM[4], true)
call QuestItemSetCompleted(QUEST_ITEM[6], true)
set QUEST_ITEM_DESC[1] = "Investigate Tom Watson House"
set QUEST_ITEM_DESC[2] = "Search the basement"
set QUEST_ITEM_DESC[3] = "Slay the giant spider"
set QUEST_ITEM_DESC[4] = "Search the strange hole"
set QUEST_ITEM_DESC[5] = "Slay the bandits in new found hideout"
set QUEST_ITEM_DESC[6] = "Return to Tom Watson"
call QuestMsg(QUEST_ID, SOUND_ITEM_COMPLETED, 3, 6, 3, 3, 3, 3, 3, 3, 0, 0)
call QuestAward(QUEST_ID)
call RemovePing(PING)
endmethod
static method start takes nothing returns nothing
set QUEST_NAME[QUEST_ID] = "There is something in my house"
set QUEST_DESC[QUEST_ID] = "Tom Watson can't sleep at night, he said strange noices come from below ground in his own house, sounds like screaming, laughtning. He wasn't home for few days to scared to leave the Inn."
call QuestAdd(QUEST_ID, QUEST_NAME[QUEST_ID], QUEST_DESC[QUEST_ID], "ReplaceableTextures\\CommandButtons\\BTNUndeadCaptureFlag.blp", false)
set GOLD_AWARD[QUEST_ID] = 350
set LUMBER_AWARD[QUEST_ID] = 0
set EXP_AWARD[QUEST_ID] = 0
set QUEST_ITEM_DESC[1] = "Investigate Tom Watson House"
call QuestMsg(QUEST_ID, SOUND_QUEST_NEW, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
set QUEST_ITEM[1] = QuestAddItem(QUEST_ID, QUEST_ITEM_DESC[1])
call UnlockBuilding(15)
call UnlockBuilding(16)
set PING = CreatePing(GetUnitX(gg_unit_n00X_0253), GetUnitY(gg_unit_n00X_0253), 0)
set REGION = CreateRegion()
call RegionAddRect(REGION, gg_rct_QUEST506_Rect_1)
call RegionAddRect(REGION, gg_rct_QUEST506_Rect_2)
call RegionAddRect(REGION, gg_rct_QUEST506_Rect_3)
call TriggerRegisterEnterRegion(T, REGION, null)
call TriggerRegisterPlayerUnitEvent(T, Player(11), EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddAction(T, function thistype.run)
endmethod
endstruct