- Joined
- Mar 18, 2012
- Messages
- 1,716
The last project I was working on before I stopped modding was some sort of Diablo3 wc3 clone. Howevery quite awesome compared to those, which already exist.
This may be useful for someone, instead of dumping it I rather post it here.
Doesn't work for minion/associated/summoned units, but it's not really difficult to implement such a feature aswell.
This may be useful for someone, instead of dumping it I rather post it here.
Doesn't work for minion/associated/summoned units, but it's not really difficult to implement such a feature aswell.
JASS:
library BonusExperience /* v1.0.0.0
*************************************************************************************
*
* Adds bonus exp to hero type units after killing a specific amount of units
* within a configurable time interval.
*
* Unit Indexer version. Works with any Unit Indexer there is.
*
*************************************************************************************
*
* */uses/*
*
* */ TimerUtils /*
* */ optional RegisterPlayerUnitEvent /*
*
************************************************************************************
*
* Credits
*
* To Vexorian
* -----------------------
*
* For TimerUtils
*
* To Maghteridon96
* -----------------------
*
* For RegisterPlayerUnitEvent
*
**************************************************************************************
*
* 1. Import instruction
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the BonusExperience script and TimerUtils into your map.
* Your map needs an UnitIndexer.
*
* 2. API
* ¯¯¯¯¯¯
* function RegisterBonusExperienceUnit takes unit who returns nothing
* function RemoveBonusExperienceUnit takes unit who returns nothing
* function RestartBonusExperienceTimer takes unit who returns nothing
* function RegisterBonusExperienceEvent takes code func returns triggercondition
*
* 3. Configuration
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*/
globals
/*
* You can read these 3 fields from everywhere. They are set before the exp event trigger fires.
* Simple put library BonusExperience as a requirement or declare it as a scope.
*/
integer BONUS_EXP_EVENT_COUNTER = 0//Amount of killed units
integer BONUS_EXP_EVENT_AMOUNT = 0//Amount of gained bonus experience
unit BONUS_EXP_EVENT_UNIT = null//Event unit
/*
* Within this timegap a new unit has to die in order to reset the countdown.
* The countdown can also be manually reset via function RestartBonusExperienceTimer(unit)
*/
private constant real CLOCK_EXPIRES = 5.
/*
* Eyecandy upon hero level up.
*/
private constant boolean SHOW_EYE_CANDY = true
/*
* Minimum amount of units, triggering the exp event.
*/
private constant integer MINIMUM_UNITS_KILLED = 5
endglobals
/*
* Filter out specific dying units, which are not included in the bonus exp system.
*/
private function FilterUnit takes unit dying returns boolean
return true
endfunction
/*
* Change the formula to your needs. This one is a very simple linear calculation.
* Your arguments are the unit gaining exp and the amount of killed units.
*/
private function GetExperience takes unit who, integer counter returns integer
return 10*counter
endfunction
//Script code. Do not change anything below
private keyword INITITALIZE_BONUS_EXP_SYSTEM
private struct BonusExperience extends array
timer clock
integer counter
unit hero
static trigger EXP_EVENT_TRIGGER = CreateTrigger()
private static method callback takes nothing returns nothing
local thistype this = thistype(GetTimerData(GetExpiredTimer()))
if (counter >= MINIMUM_UNITS_KILLED) then
set BONUS_EXP_EVENT_UNIT = hero
set BONUS_EXP_EVENT_COUNTER = counter
set BONUS_EXP_EVENT_AMOUNT = GetExperience(BONUS_EXP_EVENT_UNIT, BONUS_EXP_EVENT_COUNTER)
call AddHeroXP(BONUS_EXP_EVENT_UNIT, BONUS_EXP_EVENT_AMOUNT, SHOW_EYE_CANDY)
call TriggerEvaluate(EXP_EVENT_TRIGGER)
set BONUS_EXP_EVENT_AMOUNT = 0
set BONUS_EXP_EVENT_UNIT = null
set BONUS_EXP_EVENT_COUNTER = 0
endif
set counter = 0
endmethod
private static method onDeathEvent takes nothing returns boolean
local unit killer = GetKillingUnit()
local thistype this = thistype(GetUnitUserData(killer))
if (clock != null) and (IsUnitEnemy(killer, GetTriggerPlayer())) and FilterUnit(GetTriggerUnit()) then
set counter = counter + 1
call TimerStart(clock, CLOCK_EXPIRES, false, function thistype.callback)
endif
set killer = null
return false
endmethod
method restart takes nothing returns nothing
debug if hero == null or clock == null then
debug call BJDebugMsg("ERROR: library BonusExperience, method restart, unit or timer doesn't exist.")
debug endif
call TimerStart(clock, CLOCK_EXPIRES, false, function thistype.callback)
endmethod
method clear takes nothing returns nothing
debug if (0 == this) then
debug call BJDebugMsg("ERROR: library BonusExperience, method clear, 0 == UnitIndex, Attempt to remove a not indexed unit.")
debug return
debug endif
debug if (hero == null) then
debug call BJDebugMsg("ERROR: library BonusExperience, method clear, hero == null, Attempt to remove a not registered unit.")
debug endif
if (clock != null) then
call ReleaseTimer(clock)
set clock = null
endif
set hero = null
endmethod
static method register takes unit who returns nothing
local thistype this = thistype(GetUnitUserData(who))
debug if (0 == this) then
debug call BJDebugMsg("ERROR: library BonusExperience, static method register, 0 == UnitIndex, Attempt to add a not indexed unit")
debug return
debug endif
debug if not IsUnitType(who, UNIT_TYPE_HERO) then
debug call BJDebugMsg("ERROR: library BonusExperience, static method register, UnitTypeCheck, Attempt to add a none hero unit" + GetUnitName(who))
debug return
debug endif
if (clock == null) then
set clock = NewTimerEx(this)
endif
if (hero != null) then
debug if (hero == who) then
debug call BJDebugMsg("ERROR: BonusExperience is already initialized for " + GetUnitName(who))
debug return
debug endif
call this.clear()
endif
set counter = 0
set hero = who
endmethod
implement INITITALIZE_BONUS_EXP_SYSTEM
endstruct
private module INITITALIZE_BONUS_EXP_SYSTEM
private static method onInit takes nothing returns nothing
static if LIBRARY_RegisterPlayerUnitEvent then
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.onDeathEvent)
else
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, Condition(function thistype.onDeathEvent))
set t = null
endif
endmethod
endmodule
//Wrappers
function RegisterBonusExperienceUnit takes unit who returns nothing
call BonusExperience.register(who)
endfunction
function RemoveBonusExperienceUnit takes unit who returns nothing
call BonusExperience(GetUnitUserData(who)).clear()
endfunction
function RestartBonusExperienceTimer takes unit who returns nothing
call BonusExperience(GetUnitUserData(who)).restart()
endfunction
function RegisterBonusExperienceEvent takes code func returns triggercondition
return TriggerAddCondition(BonusExperience.EXP_EVENT_TRIGGER, Condition(func))
endfunction
endlibrary