• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[System] [vJass] Anachron's CustomAura 1.0.0

This bundle is marked as awaiting update. A staff member has requested changes to it before it can be approved.
This system was not made by me, but Anachron. The original system by Anachron can be found here.

Why ?

In latest W3 Reforged versions, you cannot install it anymore because it has a dependency to Earth-Fury's Bonus Mod & SetUnitMaxState, that requires Lua ObjectMerger to install, or manually copying 106 abilities to your map...

So I ported it as follow:
  • I removed the not necessary dependences to grim001's AbilityPreload, AutoIndex
  • I replaced Earth-Fury's Bonus & State mods by Chopinski's New Bonus, with has been developped from it (so has the same API at 90%), but only requires to copy/paste 14 abilities to your map.

Requirements

How to install
  • Copy/paste the "Requirements" trigger category to your map. Eventually merge with your existing systems.
  • Copy/paste the "CustomAura" trigger category to your map
  • If your map doesn't have a Dummy unit already
    • Import the "dummy.mdx" asset to your map
    • Copy the "CustomDummy" unit to your map
  • Set "CD_UNIT_ID" to your dummy unit in "CustomDummy" trigger from the Requirements category
  • Copy the 14 special abilities whose name starts with "NewBonus" to your map
  • Set the ability IDs in "NewBonus" trigger frm the Requirements category
JASS:
        private constant integer DAMAGE_ABILITY           = 'A004'
        private constant integer ARMOR_ABILITY            = 'A001'
        private constant integer STATS_ABILITY            = 'A000'
        private constant integer HEALTH_ABILITY           = 'A006'
        private constant integer MANA_ABILITY             = 'A00A'
        private constant integer HEALTHREGEN_ABILITY      = 'A00D'
        private constant integer MANAREGEN_ABILITY        = 'A00E'
        private constant integer ATTACKSPEED_ABILITY      = 'A002'
        private constant integer MOVEMENTSPEED_ABILITY    = 'A00B'
        private constant integer SIGHT_RANGE_ABILITY      = 'A00C'
        private constant integer MAGIC_RESISTANCE_ABILITY = 'A009'
        private constant integer CRITICAL_STRIKE_ABILITY  = 'A003'
        private constant integer EVASION_ABILITY          = 'A005'
        private constant integer LIFE_STEAL_ABILITY       = 'A008'


Examples using the system (included in the demo map)

JASS:
library HolyDevotion requires AuraTemplate

    globals
        private constant integer BUFF_ID = 'buf1'
        private constant integer BUFF_SPELL = 'spl1'
        private constant string BUFF_ORDER = "slow"
        private constant integer SPELL_ID = 'hldv'
    endglobals
 
    private struct HolyDevotionAura extends AuraTemplate
        //! runtextmacro AuraTemplateMethods()
 
        method onLevelup takes integer theLevel returns nothing
            set .dmg = - theLevel * 2
        endmethod
 
        method getRadius takes nothing returns real
            return 500.
        endmethod
 
        method unitFilter takes unit theUnit returns boolean
            //: Do some checks whether the unit is a valid target
            return IsUnitEnemy(theUnit, GetOwningPlayer(.theUnit)) and GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.40
        endmethod
    endstruct

endlibrary

JASS:
library DevotionAura requires AuraTemplate

    globals
        private constant integer BUFF_ID = 'BHad'
        private constant integer BUFF_SPELL = 'spl2'
        private constant string BUFF_ORDER = "slow"
        private constant integer SPELL_ID = 'dvar'
    endglobals
 
    private struct DevotionAura extends AuraTemplate
        //! runtextmacro AuraTemplateMethods()
 
        method onLevelup takes integer newLevel returns nothing
            set .amr = - newLevel * 2
        endmethod
 
        method getRadius takes nothing returns real
            return 500.
        endmethod
 
        method unitFilter takes unit theUnit returns boolean
            //: Do some checks whether the unit is a valid target
            return IsUnitEnemy(theUnit, GetOwningPlayer(.theUnit)) and GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.40
        endmethod
    endstruct

endlibrary

JASS:
library MagicImmunityAura initializer init requires CustomAura

    globals
        private constant integer SPELL_BOOK = 'MIbk'
    endglobals
 
    private function init takes nothing returns nothing
        local integer i = 0
 
        loop
            exitwhen i > bj_MAX_PLAYERS
            call SetPlayerAbilityAvailable(Player(i), SPELL_BOOK, false)
            set i = i + 1
        endloop
    endfunction
 
    struct MagicImmunityAura extends CustomAura
 
        method activeCond takes nothing returns boolean
            return true
        endmethod
 
        method onRegister takes unit theUnit returns nothing
            call UnitAddAbility(theUnit, SPELL_BOOK)
        endmethod
 
        method onUnregister takes unit theUnit returns nothing
            call UnitRemoveAbility(theUnit, SPELL_BOOK)
        endmethod
 
        method getRadius takes nothing returns real
            return 500.
        endmethod
 
        method unitFilter takes unit theUnit returns boolean
            //: Only for alive, non-reincarnating units
            return GetUnitState(theUnit, UNIT_STATE_LIFE) > 0.40
        endmethod
    endstruct

endlibrary
Contents

CustomAura 0.0.6 (Map)

Reviews
Wrda
You should make more descriptive names rather than thistype.a and thistype.i in CustomAura. public stub method aliveCond takes nothing returns boolean return GetUnitAbilityLevel(.theUnit, .spellId) > 0 endmethod Use UnitAlive, declare it above...

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,888
You should make more descriptive names rather than thistype.a and thistype.i in CustomAura.
JASS:
public stub method aliveCond takes nothing returns boolean
    return GetUnitAbilityLevel(.theUnit, .spellId) > 0
endmethod
Use UnitAlive, declare it above globals (where you set PERIOD) with:
JASS:
native UnitAlive takes unit id returns boolean
Should also comment that users must delete this line if they already have declared it somewhere else, or if they get an error stating duplicated function names.

JASS:
//: Replaces call GroupAddGroup(.affect, .last)
set bj_groupAddGroupDest = .last
call ForGroup(.affect, function GroupAddGroupEnum)
You can use BlzGroupAddGroupFast instead.

JASS:
call GroupClear(.affect)
call GroupEnumUnitsInRange(.affect, GetUnitX(.theUnit), GetUnitY(.theUnit), .getRadius(), Condition(function thistype.tryRegister))
call ForGroup(.last, function thistype.tryUnregister)
Condition(function thistype.tryRegister) is a leak, must be cleaned up afterwards.
In CABonus, you should use "elseif" in addBonus method instead of seperate ifs statements.

Auras are stacking by default, perhaps you could add an option for non-stacking, that the highest level takes precedence.
Aura systems are quite hard to do performance wise, so far 4 heroes with devotion aura and holy devotion both with 1500 radius against 40 enemy units hit the fps a bit. Not bad for maps where there's not a lot of units.
 
Last edited:
Top