Snippet Mana Cost Event

uberfoop

~=Admiral Stukov=~
Reaction score
177
Mana Cost event

Requires:
vJass
Event by Jesus4Lyf

Description:
A snippet offering an event which can be used in a map instead of 'a unit starts the effect of an ability'. In addition to event responses filling the same function as the regular event, this event has an event response which gives the mana cost of the ability. It does, however, function slightly differently, which is described in the documentation of the trigger script:

JASS:
//ManaCostEvent
//
//By uberfoop
//
//Requires:
//-vJass
//-Event
//
//Description:
//Replaces 'unit starts effect of an ability' events with a system
//that detects the mana cost of the ability. Register your spell
//trigger with the registration function in this system instead of
//the regular one to use. Event response functions are slightly
//different.
//
//Implimentation:
//Create a trigger called 'ManaCostEvent', go to edit -->
//"Convert to Custom Text", and replace everything in it
//with this script.
//
//Limitations and Quirks:
//-If for some reason you DO use the regular starts effect of
//ability event, do NOT modify a unit's mana in that thread or
//any other thread created to run instantly from that thread.
//-Disrupting a caster in a trigger from the special event 
//will NOT stop the ability's basic effects from taking place,
//whereas with a regular event, it stops the effects, although
//mana is still lost.
//Like the normal event, does not detect autocast-on-attack
//abilities like searing arrows unless manually cast.
//
//Use:
//Register the event as you would regularily, but with:
//RegisterSpellManaEvent(<trigger>)
//
//Use the following event response functions:
//
//function GetSpellManaCost takes nothing returns real
//--Returns the mana cost of the spell
//
//function GetSpellManaCaster takes nothing returns unit
//--Replaces GetSpellAbilityUnit and GetTriggerUnit
//
//function GetSpellManaTarget takes nothing returns unit
//--Replaces GetSpellTargetUnit
//
//function GetSpellManaId takes nothing returns integer
//--Replaces GetSpellAbilityId
//
//function GetSpellManaX takes nothing returns real
//function GetSpellManaY takes nothing returns real
//--Replaces GetSpellTargetX and GetSpellTargetY
//
//========================================================

library Mana initializer Init requires Event
private struct Packet
    unit SpellAbilityUnit
    unit SpellTargetUnit
    integer SpellRawcode
    real SpellX
    real SpellY
    real Mana
endstruct

globals
    private Event ManaCostEvent
    private Packet P
    private timer ManaT = CreateTimer()
    private Packet array PA
    private integer PacketCount = -1
endglobals

//===Event Response===

function GetSpellManaCaster takes nothing returns unit
    return P.SpellAbilityUnit
endfunction

function GetSpellManaTarget takes nothing returns unit
    return P.SpellTargetUnit
endfunction

function GetSpellManaId takes nothing returns integer
    return P.SpellRawcode
endfunction

function GetSpellManaX takes nothing returns real
    return P.SpellX
endfunction

function GetSpellManaY takes nothing returns real
    return P.SpellY
endfunction

function GetSpellManaCost takes nothing returns real
    return P.Mana
endfunction

//====================

private function ManaCostCallback takes nothing returns nothing
    loop
        set P = PA[PacketCount]
        set P.Mana = P.Mana - GetUnitState(P.SpellAbilityUnit,UNIT_STATE_MANA)
        call ManaCostEvent.fire()
        call P.destroy()
        set PacketCount = PacketCount - 1
        exitwhen PacketCount == -1
    endloop
endfunction

private function RunManaCost takes nothing returns boolean
    local Packet D = Packet.create()
    set D.SpellAbilityUnit = GetTriggerUnit()
    set D.SpellTargetUnit = GetSpellTargetUnit()
    set D.SpellRawcode = GetSpellAbilityId()
    set D.SpellX = GetSpellTargetX()
    set D.SpellY = GetSpellTargetY()
    set D.Mana = GetUnitState(D.SpellAbilityUnit,UNIT_STATE_MANA)
    set PacketCount = PacketCount + 1
    set PA[PacketCount] = D
    call TimerStart(ManaT,0.,false,function ManaCostCallback)
    return false
endfunction

function RegisterSpellManaEvent takes trigger t returns nothing
    call ManaCostEvent.register(t)
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 RunManaCost))
    set ManaCostEvent = Event.create()
endfunction
endlibrary



A use demonstration is included in the demo map; use any ability and it will display general information about it.
 

Attachments

  • ManaCostEvent.w3x
    20.2 KB · Views: 238

Jesus4Lyf

Good Idea™
Reaction score
397
Only comment codewise is
JASS:
set ManaT = CreateTimer()

can be inlined into the global declaration.

Hm. I suppose the only thing left to conclude is is this useful?

And I suppose the answer is... I suppose it is (for things like damage based on casting any spell within an aura or something).

The only failure situation is an ability that gives you mana? (Huh? Seems uncommon, but there is such a thing in DotA.) Can this be solved?
 

uberfoop

~=Admiral Stukov=~
Reaction score
177
can be inlined into the global declaration.
Fixed.

The only failure situation is an ability that gives you mana? (Huh? Seems uncommon, but there is such a thing in DotA.) Can this be solved?
Native abilities that modify mana (ie modified Rejuvination) have worked fine in testing.

With triggered abilities, unfortuanately, the simplest solution that i can think of is to just use the SpellManaEvent instead of the basic event for all abilities capable of resulting in instantly modified mana.
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
Hrm. 4.998?
50mfr.jpg


Also, does this work for autocast-on-attack abilities, like searing arrows?
 

uberfoop

~=Admiral Stukov=~
Reaction score
177
Hrm. 4.998?
That's...interesting.
Gotta hate what wc3 does with real operations :(

Also, does this work for autocast-on-attack abilities, like searing arrows?
Ugh, I knew I was forgetting something. It wouldn't, unless you manually casted the ability.

The really big problem here being that there is basically no general method whatsoever for detecting autocast-attack casts. The only thing I know of that can do it properly is the native mana flare spell.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>Gotta hate what wc3 does with real operations
Or mana regen in 0.0 seconds.

Perhaps this could be triggered off a global manaflare instance?

Then this would be useful for more than just getting the mana cost!
(But if that's all we want, then I think it acceptable not to register autocast attacks. Still...)
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
Perhaps this could be triggered off a global manaflare instance?
I experimented a little with Mana Flare, and it seems to never target invulnerable or spell-immune casters, regardless of its target settings or "ultimate" status. :( That's a bit limited.

(But if that's all we want, then I think it acceptable not to register autocast attacks. Still...)
Yeah, that's fair enough.
 

Weep

Godspeed to the sound of the pounding
Reaction score
400
I dunno if this is quite the right place for it, but I've done a little more experimenting using Mana Flare to detect a unit's moment of actual attack, not aggro nor projectile hit.

If a unit is given a disabled spell book with a copy of Searing Arrows in it, and the unit's default active ability is that copy of Searing Arrows, it will always have it active and the player won't be able to turn it off. Searing Arrows overrides orb effects but can coexist with buff placers, and it should be an "ultimate" so it will still fire against spell immune targets.

The Searing Arrows needs to have non-0 mana cost, so the attacking units will always need to have at least 1 mana. The event can be distinguished from other spellcasts because the unit's order string will be "attack" or null, except for instant spells like activating Mana Shield, Divine Shield, Immolation, Berserk, Wind Walk, and Bladestorm which also are null. Its target can be cached from a Unit Is Attacked event, which will always happen beforehand.

The attacking unit must not be spell invulnerable or plain ol' invulnerable. Anti-Magic Shell does not interfere if it has shield life; a duration-only impenetrable shell will interfere. Spell Damage Resistance does not interfere even at 100%.

A dummy with a copy of Mana Flare with ∞ AOE, blank targets allowed, 0 cast range, non-0 damage per mana and maximum damage (0.01 works fine), and 0 casting time, cooldown, damage cooldown, and duration works as the detector.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top