Spell Hydrovacuum

Immolation

Member
Reaction score
20
Hydrovacuum​
Conjures several sharp water blades that move to the center of the target area.
When the blades hit an enemy, they dissolve and the damaged unit gets knocked in the centre of the spell.


GUI/vJASS= vJASS
Leakless?= Yes(I hope).
Lagless= Yes.
MUI/MPI?= MUI


Changelog:
v1.1
-Improved code and documentation.

v1.00
-Public release.

Code:
JASS:
scope Hydrovacuum initializer Init
//-------------------------------------------------------------
//                  Hydrovacuum by Immolation                
//-------------------------------------------------------------

// Description:
//---------------------------
// Conjures several sharp water blades that move to the center of the target area. 
// When the blades hit an enemy, they dissolve and the damaged unit gets knocked in the centre of the spell.

// What do I need to import it in my map?
//---------------------------
// You need to download JASS NewGen, available at the following links:

// -http://www.thehelper.net/forums/showthread.php?t=73936-
// -http://www.wc3c.net/showthread.php?t=90999-

// Download and install it.
//---------------------------
// 1. Copy:
//  a. The "Hydrovacuum" ability, the "Spell Damage" ability.
//  b. Export the "dummy.mdx" file and import it back into your map.
//  c. Export the "KnockbackWater.mdl" file and import it into your map. Be sure that its file name is "KnockbackWater.mdl"
//  c. Copy the "Water Blade" unit and the "Dummy Unit" in your map.
//  d. Copy the "UtilityLibs" trigger directory.
//  e. Copy this trigger.
// 2. Press CTRL + D while in Abilities section in Object Editor to find out the rawcode of:
//  a. The "Hydrovacuum" ability. Change the SPELL_ID to the rawcode that you find(it's 'A000' in this map).
//  b. The "Spell Damage" ability. Change the DUMMY_SPELLID to the rawcode that you find(it's 'A001' in this map).
//  c. The "Dummy Unit" unit. Change the DUMMY_ID in the KBS trigger to the rawcode that you find(it's 'n000' in this map).
//  c. The "Water Blade Dummy" unit. Change the DUMMY_UNITID to the rawcode that you find(it's 'n001' in this map).
// 3. You have succesfully imported the spell <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />

// Changelog:
//---------------------------
// v1.1:
// -Improved code and documentation.
//
// v1.00:
//  -Initial release.
//---------------------------
// TheHelper.net

// Credits:
//---------------------------
// Thanks to:
// -Darthfett for EnterRange system.
// -Cohadar for PUI.
// -KBS by kenny!
// -CSData by Vexorian.

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//                             LIST OF CONFIGURABLES
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//About Configurables:
// You can configure most of the spell in the object editor, but for amount of rays called
//  and the rawcode of the abilities(and the dummy unit) check the map header.

    globals
        private constant integer SPELL_ID = &#039;A000&#039; //Rawcode of the &quot;Hydrovacuum&quot; ability.
        private constant integer DUMMY_SPELLID = &#039;A001&#039; //Rawcode of the &quot;Spell Damage&quot; ability.
        private constant integer DUMMY_UNITID = &#039;n001&#039; //Rawcode of the &quot;Water Blade Dummy&quot;.
        private constant real SPELL_AREA = 400.00 //Area of the spell.
        private constant real BLADE_AREA = 100.00 //Area of each blade(it damages a unit once it enters within X range of it). 
        private constant real DISTANCE_FACTOR = 3.00 //Distance factor; putting a lower number will result in bigger knockback and viceversa.
                                                            //Suggested between 3 and 5.
        private constant real DURATION_FACTOR = 300.00 //Knockback duration factor; putting a lower number will result in longer knockback and viceversa
                                                            //Suggested between 300 and 500.
        private constant integer BLADES_PER_LEVEL = 2 //Additional blades gained for each level of the spell.
        private constant integer BLADES_BASE = 6 //Standard amount of blades; without counting the spell level.
        private constant real DAMAGE_PER_LEVEL = 10.00 // mount of damage that each blade does each level of the spell
        private constant real DAMAGE_BASE = 30.00 //Amount of damage without counting spell level.
        private constant boolean BLADE_KNOCK = true //If set to true, knocks enemies towards the centre of the spell.
        private constant boolean BLADE_DISPEL = true //If set to true, blades will dispel upon impact.
        private constant boolean BLADE_DAMAGE = true //If set to true, blades will deal damage upon impact.
        private constant boolean DAMAGE_ALLIES = false //If set to true, blades will deal damage and knock allies upon impact.
        private constant string EFFECT_CREATE = &quot;Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl&quot; 
                                                //Effect that is created when spawning a blade.
        private constant string EFFECT_KNOCK = &quot;KnockbackWater.mdl&quot; // Effect that is crated when knocking back a unit.
        private constant string EFFECT_DAMAGE = &quot;Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl&quot;
                                                //Effect that is created when dealing damage to the unit.
    endglobals

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    private function Cond takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ID
    endfunction
        
    private function KnockCond takes nothing returns boolean
        return IsPlayerAlly(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetCenterUnit())) == false
    endfunction
    
    private function Knock takes nothing returns nothing
        local unit hitunit = GetTriggerUnit()
        local unit blade = GetCenterUnit()
        local integer level = GetUnitAbilityLevel(blade, DUMMY_SPELLID)
        local location loc = GetOrderPointLoc()
        local real x = GetLocationX(loc)
        local real y = GetLocationY(loc)
        local real x2 = GetUnitX(hitunit)
        local real y2 = GetUnitY(hitunit)
        local effect sfx
        local real dx = x2 - x
        local real dy = y2 - y
        local real distance = SquareRoot(dx * dx + dy * dy)
        if BLADE_KNOCK == true then
            call KBS_BeginEx (hitunit, distance / DISTANCE_FACTOR, (distance / DURATION_FACTOR) , GetUnitFacing(blade), EFFECT_KNOCK, -150.00,true,true)
            else 
            endif
        if BLADE_DAMAGE == true then
            call UnitDamageTarget(blade, hitunit, ((DAMAGE_PER_LEVEL * level) + DAMAGE_BASE), false, false, null, null, null)
            set sfx = AddSpecialEffect(EFFECT_DAMAGE, x2, y2)
            call DestroyEffect(sfx)
            else
            endif
        if BLADE_DISPEL == true then
            call KillUnit(GetCenterUnit())
            else
            endif
        set hitunit = null
        set blade = null
        set loc = null
    endfunction
        
    private function Main takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local player p = GetOwningPlayer(caster)
        local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
        local location targetloc = GetSpellTargetLoc()
        local integer start = 1
        local integer end = ((BLADES_PER_LEVEL * level) + BLADES_BASE)
        local real degreeperblade = (360.00 / I2R(end))
        local real degree = 0.00
        local real x = GetLocationX(targetloc)
        local real y = GetLocationY(targetloc)
        local real x2
        local real y2
        local effect sfx
        local trigger t2
        local boolean a 
        local unit dummy 
        loop
            exitwhen start &gt; end
            set x2 = x + SPELL_AREA * Cos(degree * bj_DEGTORAD)
            set y2 = y + SPELL_AREA * Sin(degree * bj_DEGTORAD)
            set dummy = CreateUnit(p, DUMMY_UNITID, x2, y2, degree + 180.00)
            set sfx = AddSpecialEffect( EFFECT_CREATE, x2, y2)
            call DestroyEffect(sfx)
            call SetUnitFlyHeight(dummy, 20.00, 2.00 )
            //Units with Fly pathabily move pretty weird so I set their flying height.
            call UnitApplyTimedLife(dummy, &#039;BTLF&#039;, (SPELL_AREA / 400.00))
            call IssuePointOrder(dummy, &quot;move&quot;, x, y)
            set a = UnitAddAbility(dummy, DUMMY_SPELLID)
            call SetUnitAbilityLevel(dummy, DUMMY_SPELLID, level)
            set t2 = TriggerRegisterUnitEnterRangeEvent(dummy, BLADE_AREA, null)
            if DAMAGE_ALLIES == false then
                call TriggerAddCondition(t2, Condition(function KnockCond))
                else
                endif
            call TriggerAddAction(t2, function Knock)
            set degree = (degree + degreeperblade)
            set start = start + 1
        endloop
        set targetloc = null
        set dummy = null
        set caster = 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 Cond) )
        call TriggerAddAction( t, function Main )
    endfunction
endscope



It's my first pretty complex JASS spell. Comment and rate ;)
 

Attachments

  • Hydrovacuum v1.1.w3x
    88.2 KB · Views: 243

Romek

Super Moderator
Reaction score
963
All the IDs, special effect paths, damages, distances, etc should be configurables at the top of the map script.
 

BlackRose

Forum User
Reaction score
239
JASS:
        if BLADE_DISPEL == true then
            call KillUnit(GetCenterUnit())
            else

- You don't need else to do nothing.
- Just do if BLADE_DISPEL then

- WTF? How far do you knock enemies back? 5 seconds? 900 distance?
- Sorry but, effects are, dissapoint me for a water spell :( It is simple, boom and go in slide.
 

Romek

Super Moderator
Reaction score
963
It is possible to have configurable functions you know, not only variables.
Damage, distance, etc should all be config. functions.

Also, you leak a few locations which aren't destroyed - only nulled.

I'll take a look at this (as well as most of the other resources) in more detail once my exams are over.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      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