• 🏆 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!

[vJASS] Phoenix Strike v1.0.0.8

In proving how the amount of code is inversely proportional to the amount of library used, I present to you my first ever vJASS spell to be uploaded. The code is short enough and the library count is high enough also.

Besides, I haven't uploaded anything in a while. So why not?

PHOENIX STRIKE

Gives a percentage chance to unleash a raging phoenix that deals damage to enemies in its wake when attacking.

Level 1 - 3xAGI damage, 10% chance.
Level 2 - 5xAGI damage, 20% chance.
Level 3 - 7xAGI damage, 30% chance.
Level 4 - 9xAGI damage, 40% chance.

Required Libraries:

Optional Library (for more swag):

Credit:
  • Dirac for Missile, Linked List Module, Loc, Adv Loc.
  • Cokemonkey11 for Structured DD, DamageType.
  • Garfield1337 for GetTerrainZ | UnitZ.
  • Maker for ArcingFloatingText.
  • Nestharus for Alloc Alternative, UnitIndexer, Event, World Bounds, Dummy, CTL, Error Message.
  • Vexorian for JassHelper, Table.


  • Step 1: Copy all required libraries to your map.
  • Step 2: Copy al library-related objects in the test map (1 dummy, 1 ability) to your map. Readjust the raw codes in the Dummy library and the DamageType library.
  • Step 3: Copy the Phoenix Strike ability and configure it.
  • Step 4: ???
  • Step 5: Profit!!!

Script:

JASS:
library PhoenixStrike /* v1.0.0.8 by Doomlord
*************************************************************************************
*
*   Gives a percentage chance to unleash a raging phoenix 
*   that deals damage to enemies in its wake when attacking.
*
*************************************************************************************
*
*   Credits
*
*       Dirac
*       -----------------------
*
*           Missile library
*
*       Cokemonkey11
*       -----------------------
*
*           DamageType library
*
*       Garfield1337
*       -----------------------
*
*           UnitZ library
*
*       Nestharus
*       -----------------------
*
*           Alloc Alternative
*
*       Maker
*       -----------------------
*
*           Arcing Floating Text library
*
*************************************************************************************
*
*   */ uses /*
*   
*       */ Missile                      /* hiveworkshop.com/forums/jass-resources-412/system-missile-207854/
*       */ DamageType                   /* hiveworkshop.com/forums/jass-resources-412/system-damagetype-structureddd-extension-228883/
*       */ UnitZ                        /* hiveworkshop.com/forums/jass-resources-412/snippet-getterrainz-unitz-236942/
*       */ Alloc                        /* hiveworkshop.com/forums/jass-resources-412/snippet-alloc-alternative-221493/
*       */ optional FloatingTextArc     /* hiveworkshop.com/forums/spells-569/arcing-floating-text-1-0-0-3-a-228710/
*
************************************************************************************
*
*   SETTINGS
*
*/
    
    globals
        // Ability raw code
        private constant integer ABI_ID = 'A002'
        // Maximum travel range
        private constant real MAX_TRAVEL_RANGE = 1000
        // Missile model
        private constant string MISSILEFX = "Units\\Human\\Phoenix\\Phoenix.mdl" 
        // On Collide Model
        private constant string COLLIDEFX = "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
        // Attachment point
        private constant string ATTACHPOINT = "chest"
        // Attack type
        private constant attacktype ATT = ATTACK_TYPE_HERO
        // Damage type
        private constant damagetype DAM = DAMAGE_TYPE_NORMAL
        // Weapon type
        private constant weapontype WEA = WEAPON_TYPE_METAL_HEAVY_SLICE
    endglobals
    
    // Trigger chance
    private function getChance takes integer level returns boolean
        return GetRandomInt(1, 100) <= 10*level
    endfunction
    
    // Area of effect
    private function getAoE takes integer level returns real
        return 200.
    endfunction
    
    // Agility multiplier
    private function getMultiplier takes integer level returns integer
        return 1 + level*2
    endfunction
    
    // Damage on collide
    private function getDamage takes unit u, integer level, integer multiplier returns real
        if not IsUnitType(u, UNIT_TYPE_HERO) then
            return 100 + level*50.
        endif
        
        return GetHeroAgi(u, true)*multiplier*1.
    endfunction
    
    // Missile speed per 0.03125s
    private function getSpeed takes integer lvl returns real
        return 45.
    endfunction
    
    // Filter out some targets
    private function filterUnit takes unit caster, unit u returns boolean
        return /*
        
        */ IsUnitEnemy(u, GetOwningPlayer(caster)) and /* Target is an enemy of caster
        */ not IsUnitType(u, UNIT_TYPE_DEAD) and /* Target is alive
        */ GetUnitAbilityLevel(u, 'Avul') == 0 and /* Target is not invulnerable
        */ not IsUnitType(u, UNIT_TYPE_STRUCTURE) /* Target is not a structure
        */
    endfunction
    
    // Just skip this if you want. There is not much to read anyway.
    private struct PS extends array
        implement Alloc

        Missile m
        
        static method onFinish takes Missile m returns boolean
            call DestroyEffect(AddSpecialEffect(MISSILEFX, m.impact.x, m.impact.y))
            call thistype(m.data).deallocate()
            return true
        endmethod
        
        static method onCollide takes Missile m, unit justHit returns boolean
            if filterUnit(m.source, justHit) then
                // Reproduce the weapon sound
                call UnitDamageTarget(m.source, justHit, 0, false, false, ATT, DAM, WEA)
                // The function somehow reverses the damage dealt. Hence the need to use a negative amount.
                call DamageType.dealCodeDamage(m.source, justHit, getDamage(m.source, GetUnitAbilityLevel(m.source, ABI_ID), getMultiplier(GetUnitAbilityLevel(m.source, ABI_ID))))
                call DestroyEffect(AddSpecialEffectTarget(COLLIDEFX, justHit, ATTACHPOINT))
            endif
            
            return false
        endmethod
        
        implement MissileStruct
        
        private static method create takes nothing returns thistype
            local real a = GetRandomReal(-bj_PI, bj_PI)
            local unit u = GetEventDamageSource()
            local integer i = GetUnitAbilityLevel(u, ABI_ID)
            local real r = GetRandomReal(300, MAX_TRAVEL_RANGE)
            local real x = GetUnitX(u) + r*Cos(a)
            local real y = GetUnitY(u) + r*Sin(a)
            local unit u1 = GetTriggerUnit()
            local thistype this = thistype.allocate()
            
            set .m = Missile.create (x, y, GetUnitZ(u), Atan2(GetUnitY(u1) - y, GetUnitX(u1) - x), MAX_TRAVEL_RANGE, GetUnitZ(u1))
            set m.source = u
            set m.speed = getSpeed(i)
            set m.model = MISSILEFX
            set m.collision = getAoE(i)
            set m.scale = 1.5
            set m.data = this
                    
            static if LIBRARY_FloatingTextArc then
                call ArcingTextTag.create("|c00ECEC00 PHOENIX STRIKE!|r", u)
            endif

            call launch(m)
            return this
        endmethod
    
        static method handler takes nothing returns nothing
            local unit u = GetEventDamageSource ()
        
            if DamageType.get() == DamageType.ATTACK  and /*
            */ GetUnitAbilityLevel(u, ABI_ID) > 0 and /*
            */ IsUnitEnemy(GetTriggerUnit(), GetOwningPlayer(u)) and /*
            */ getChance(GetUnitAbilityLevel(u, ABI_ID)) then
            
                call thistype.create ()
                
            endif
            
            set u = null
        endmethod
        
        private static method onInit takes nothing returns nothing
            call StructuredDD.addHandler(function thistype.handler)
        endmethod
    endstruct
endlibrary


+ v1.0.0.0: Initial release.
+ v1.0.0.1: Made struct PS extends array.
+ v1.0.0.2: Idiot-proofed create/destroy method.
+ v1.0.0.3: Switched to using Nestharus' Alloc Alternative.
+ v1.0.0.4: Improved code readability.
+ v1.0.0.5: Improved code readability further.
+ v1.0.0.6: Fixed an issue with physical damage type.
+ v1.0.0.7: Updated spell lib with new Alloc.
+ v1.0.0.8: Updated spell lib with new StructuredDD and DamageType.


Tip to other spell makers: Always mention Magtheridon96's name in the keyword for maximum swag.

Keywords:
phoenix, swag, yolo, magtheridon96, vJASS
Contents

Phoenix Strike (Map)

Reviews
13:45, 22nd Jul 2013 PurgeandFire: Approved. A wonderful, swagtastic spell.

Moderator

M

Moderator

13:45, 22nd Jul 2013
PurgeandFire: Approved. A wonderful, swagtastic spell.
 
Top