Spell Energy Empower

Dinowc

don't expect anything, prepare for everything
Reaction score
223
Energy Empower
v1.6
manaflare.gif

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 :p)
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 = 'A000' // ID of the main spell
    private constant integer CHARGE_ID = 'A001' // ID of the charge spell
    private constant integer PURGE_ID = 'A002' // dummy's spell
    private constant integer BUFF_ID = 'B000'
    private constant integer DUMMY_ID = 'h000'
    private constant integer EFFECT_DUMMY = 'h001'
    
    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, 'BTLF', 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, 'BTLF', 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
81461287.jpg

-energy blast
45864078.jpg

71053678.jpg


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.
 

Azlier

Old World Ghost
Reaction score
461
...Why are debug messages showing up during the spell? What's the point of that?
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
they show how much dmg is inflicted...
I just added it for testing

it can be removed by deleting 1 line (where the call BJDebugMsg appears)
 

Romek

Super Moderator
Reaction score
964
Why on earth are you destroying timers you create with NewTimer()?

Oh, and spells with visible Debug Messages won't be approved. It's an easy removal anyway.
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
so I should use ReleaseTimer() instead?

and I'll remove the debug message when I return from school

I needed it for testing
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
BUMP

map updated.

please give comments/suggestions :eek:
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
bump.

aw come on...

is the spell really so bad? why nobody says anything? :(

I've already made v1.3
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
JASS:
local unit u = GetTriggerUnit()
local integer i = GetUnitIndex(u)
local data d = data.create(u)
set D<i> = d</i>


JASS:
local data d = D[GetUnitIndex(GetTriggerUnit())]


I'm making it, am I?
it needs the timer so it can check hero's mana

I still suck in vJass so not sure am I doing it the correct way :(
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
lol didn't know about that (first time using PUI)

I'll try it now


EDIT:

I got some problems now

the spell isn't MUI anymore :(

I must have done something wrong...
how do I use that PUI struct system?

is there any tutorial?
 

Viikuna

No Marlo no game.
Reaction score
265
Use one global dummy for casting those purges, instead of creating new one alla time.
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
one global dummy

uhm I don't get it...

how do you do that with 1 dummy?

EDIT: I did it like you posted here and it doesn't work...
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
EDIT: yeah it works now
thanks! :)

v1.6 uploaded (read changelog)
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
but still I got no comments of the spell :(

I just wanna know what ppl think of it and should I continue improving it or not
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top