Dinowc
don't expect anything, prepare for everything
- Reaction score
- 223
Energy Empower
v1.6
Type: Instant, Point Target
Targets: Enemy
Description:
Activates a magic shell charging energy every time hero loses mana. He can then blast an area with energy dealing part of the lost mana in damage and slowing enemies by 50% for 4 seconds.
Can store up to 25 x hero's intelligence mana.
Level 1 - 30% of lost mana, 300 AOE.
Duration 25 seconds.
Level 2 - 40% of lost mana, 350 AOE.
Duration 30 seconds.
Level 3 - 50% of lost mana, 400 AOE.
Duration 35 seconds.
Level 4 - 60% of lost mana, 450 AOE.
Duration 40 seconds.
Requires: TU, PUI, dummy model (you can export the dummy model from the map cause I can't remember the link )
Import Difficulty: Not very simple (you need 2 systems, 2 spells and 2 dummies)
JASS:
////////////////////////////////////////////////////////
//
// ENERGY EMPOWER - by Dinowc
//
// Changelog:
//
// v1.6 - fixed the code, used one global dummy for casting purge instead of creating many, increased the duration of slow to 5 seconds
// v1.5 - improved the spell (it deals damage on effect explosion, looks much better)
// v1.4 - improved and optimized the code
// v1.3 - modified spell and code, add a new spell mode, fixed some bugs
// v1.2 - further improved code and the spell, added eye-candy effects
// v1.1 - modified the spell, fixed the code, added a floating text that shows damage done (can be turned off)
// v1.0 - initial release
//
// Pros:
// - MUI, leakless, lagless (might lag if you spam)
// - fully configurable
//
// Cons:
//
// - requires 2 systems
// - huge code
// - first time cast lag (needs preloading)
// - the more/bigger effects you use, the more lag could appear
//
// Requirements: NewGen, TimerUtils, PUI, Vexorian's dummy model (everything included in map)
//
// Installation:
//
// 1. create a new trigger, go to Edit > Convert to Custom text and copy this code into it
// 2. create 2 abilities - 1 hero and 1 unit ability, hero ability must be instant, unit must be point targeted
// 3. write their raw codes in "SPELL_ID" and "CHARGE_ID" fields
// 4. save and test the map
//
// if you got any problems or encounter any bug, pm me!
//
scope energy initializer init
//changeable:
globals
private constant integer SPELL_ID = 039;A000039; // ID of the main spell
private constant integer CHARGE_ID = 039;A001039; // ID of the charge spell
private constant integer PURGE_ID = 039;A002039; // dummy's spell
private constant integer BUFF_ID = 039;B000039;
private constant integer DUMMY_ID = 039;h000039;
private constant integer EFFECT_DUMMY = 039;h001039;
private constant real INTERVAL = 0.25 // every [this value] seconds checks unit's mana, the lower it is the more precise it will be, but also lagier
private constant real DMG_INTERVAL = 0.50 // wait [this value] seconds before dealing dmg
private constant real DamageFactor = 0.20 // + (level of ability * 0.1) of stored mana dealt in damage
private constant real ManaCapacity = 25. // * hero's intelligence -> maximum mana stored
private constant string MANA_EFFECT = "Abilities\\Spells\\Other\\Charm\\CharmTarget.mdl" //mana gain effect, type null to show no effect
private constant string MANA_EFFECT_ATTACH = "chest"
private constant string DMG_EFFECT = "Abilities\\Spells\\Human\\Feedback\\ArcaneTowerAttack.mdl" // the effect that appears on damaged units, type null to show no effect
private constant string DMG_EFFECT_ATTACH = "chest"
private constant string SPELL_EFFECT1 = "Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.mdl" // type null to show no effect
private constant real SPELL_EFFECT1_FACTOR = 250. // size of SPELL_EFFECT1 (smaller effects require smaller value)
private constant string SPELL_EFFECT2 = "Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl" // type null to show no effect
private constant real SPELL_EFFECT2_FACTOR = 125. // size of SPELL_EFFECT2 (smaller effects require smaller value)
private constant boolean SHOW_DMG = true // whether to show floating text or not
private constant real AOE = 250. // + (level of ability * 50) - the size of the SPELL_EFFECTS depends on this
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_LIGHTNING
private constant unitstate SPELL_MODE = UNIT_STATE_MANA // type UNIT_STATE_LIFE if you want to gain damage every time unit loses hp instead
endglobals
//don't touch this:
private function damage takes integer level returns real
return (level * 0.1) + DamageFactor
endfunction
private function AoE takes integer level returns real
return (level * 50) + AOE
endfunction
function SetUnitSize takes unit whichUnit, real a, real b, integer level returns nothing
call SetUnitScale(whichUnit, a + (b * level), a + (b * level), a + (b * level))
endfunction
private function floatText takes unit u, real dmg returns nothing
local real x
local real y
local texttag text = CreateTextTag()
call SetTextTagText(text, I2S(R2I(dmg)) + "!", 0.023)
call SetTextTagPos(text, GetUnitX(u), GetUnitY(u), 50.)
call SetTextTagColor(text, 0, 255, 255, 255)
call SetTextTagPermanent(text, false)
call SetTextTagLifespan(text, 2.)
call SetTextTagFadepoint(text, 1.)
set x = 0.0532 * Cos(90. * bj_DEGTORAD)
set y = 0.0532 * Sin(90. * bj_DEGTORAD)
call SetTextTagVelocity(text, x, y)
set text = null
endfunction
//////////////////////////////////////////////////////////
private struct data
//! runtextmacro PUI()
unit caster
real storedMana
real currentMana
real x
real y
player p
real newMana
timer t
static method create takes unit whichUnit returns data
local data d = data.allocate()
set d.caster = whichUnit
set d.storedMana = 0.
set d.currentMana = 0.
set d.t = NewTimer()
return d
endmethod
private method onDestroy takes nothing returns nothing
call ReleaseTimer(.t)
endmethod
endstruct
//////////////////////////////////////////////////////////
globals
private unit DUMMY
private unit U
private unit Picked
private real DAMAGE
private player P
private group G = CreateGroup()
endglobals
/////////////////////////////////////////////////////////
private function cond1 takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function cond2 takes nothing returns boolean
return GetSpellAbilityId() == CHARGE_ID and GetUnitAbilityLevel(GetTriggerUnit(), SPELL_ID) > 0
endfunction
///////////////////////////////////////////////////////////
private function manaStore takes nothing returns nothing
local data d = GetTimerData(GetExpiredTimer())
if GetUnitAbilityLevel(d.caster, BUFF_ID) > 0 then
set d.newMana = GetUnitState(d.caster, SPELL_MODE)
if d.newMana < d.currentMana then
if d.storedMana < ManaCapacity * GetHeroInt(d.caster, true) then
call DestroyEffect(AddSpecialEffectTarget(MANA_EFFECT, d.caster, MANA_EFFECT_ATTACH))
set d.storedMana = d.storedMana + (d.currentMana - d.newMana)
else
set d.storedMana = ManaCapacity * GetHeroInt(d.caster, true)
endif
endif
set d.currentMana = GetUnitState(d.caster, SPELL_MODE)
call TimerStart(d.t, INTERVAL, false, function manaStore)
else
call d.destroy()
endif
endfunction
private function filterFunc takes nothing returns boolean
set Picked = GetFilterUnit()
if IsUnitEnemy(Picked, P) == true and GetWidgetLife(Picked) > 0. then
call UnitDamageTarget(U, Picked, DAMAGE, true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
call SetUnitX(DUMMY, GetUnitX(Picked))
call SetUnitY(DUMMY, GetUnitY(Picked))
call IssueTargetOrder(DUMMY, "purge", Picked)
call DestroyEffect(AddSpecialEffectTarget(DMG_EFFECT, Picked, DMG_EFFECT_ATTACH))
if SHOW_DMG == true then
call floatText(Picked, DAMAGE)
endif
endif
return false
endfunction
private function blastEffect takes nothing returns nothing
local data d = GetTimerData(GetExpiredTimer())
set P = GetOwningPlayer(d.caster)
set U = d.caster
call SetUnitOwner(DUMMY, P, false)
call GroupEnumUnitsInRange(G, d.x, d.y, AoE(GetUnitAbilityLevel(d.caster, SPELL_ID)), Condition(function filterFunc))
call d.release()
endfunction
//////////////////////////////////////////////////////////
private function actions2 takes nothing returns nothing
local data d = data[GetTriggerUnit()]
local location target = GetSpellTargetLoc()
local unit dummy
set d.x = GetLocationX(target)
set d.y = GetLocationY(target)
call UnitRemoveAbility(d.caster, BUFF_ID)
set U = d.caster
set d.p = GetOwningPlayer(U)
set DAMAGE = d.storedMana * damage(GetUnitAbilityLevel(U, SPELL_ID))
set dummy = CreateUnit(d.p, EFFECT_DUMMY, d.x, d.y, 0.)
call SetUnitSize(dummy, (AOE / SPELL_EFFECT1_FACTOR), AOE / SPELL_EFFECT1_FACTOR, (GetUnitAbilityLevel(U, SPELL_ID)))
call DestroyEffect(AddSpecialEffectTarget(SPELL_EFFECT1, dummy, "origin"))
call UnitApplyTimedLife(dummy, 039;BTLF039;, 0.10)
set dummy = CreateUnit(d.p, EFFECT_DUMMY, d.x, d.y, 0.)
call SetUnitSize(dummy, (AOE / SPELL_EFFECT2_FACTOR), AOE / SPELL_EFFECT2_FACTOR, (GetUnitAbilityLevel(U, SPELL_ID)))
call DestroyEffect(AddSpecialEffectTarget(SPELL_EFFECT2, dummy, "origin"))
call UnitApplyTimedLife(dummy, 039;BTLF039;, 0.10)
call UnitRemoveAbility(d.caster, CHARGE_ID)
call SetTimerData(d.t, d)
call TimerStart(d.t, DMG_INTERVAL, false, function blastEffect)
call RemoveLocation(target)
set target = null
set dummy = null
endfunction
//////////////////////////////////////////////////////////
private function actions1 takes nothing returns nothing
local unit u = GetTriggerUnit()
local data d = data.create(u)
set data<u> = d
call UnitAddAbility(d.caster, CHARGE_ID)
call SetUnitAbilityLevel(d.caster, CHARGE_ID, GetUnitAbilityLevel(d.caster, SPELL_ID))
call SetTimerData(d.t, d)
call TimerStart(d.t, INTERVAL, false, function manaStore)
set u = null
endfunction
//=========================================================
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function cond1))
call TriggerAddAction(t, function actions1)
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function cond2))
call TriggerAddAction(t, function actions2)
set t = null
set DUMMY = CreateUnit(Player(13), DUMMY_ID, 0., 0., 0.)
endfunction
endscope</u>
-mana charge
-energy blast
no point judging from the screenshots, try it out ingame
Changelog:
v1.6 - fixed the code, used one global dummy for casting purge instead of creating many, increased the duration of slow to 5 seconds
v1.5 - improved the spell (it deals damage on effect explosion, looks much better)
v1.4 - improved and optimized the code
v1.3 - modified spell and code, add a new spell mode, fixed some bugs
v1.2 - further improved code and the spell, added eye-candy effects
v1.1 - modified the spell, fixed the code, added a floating text that shows damage done (can be turned off)
v1.0 - initial release
updated daily.