Spell Blade Barrier

BlackRose

Forum User
Reaction score
239
Blade Barrier by BlackRose

v1.04 - 04/07/2010​

Screenshot:
Screenshot.jpg

Description:
Creates a barrier of blades around the caster, dealing damage to enemy units nearby.​

  • MUI
  • Coded in vJass

Requires:

Ability code:
JASS:
library BladeBarrier initializer onInit requires GT, KT, AIDS, SimError, Table
//+----------------------------------------------------------------------------------+
//|                                     v1.04b - 11/07/2010 Sunday
//|     Blade Barrier by BlackRose
//|
//+----------------------------------------------------------------------------------+
//|
//| Description: Creates a barrier of blades around the caster unit, damaging enemy 
//|              units that get in the way. 
//|
//| Requires: - JassHelper [latest - <a href="http://www.wc3c.net/showthread.php?t=88142]" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?t=88142]</a>
//|           - GTrigger    by Jesus4Lyf
//|           - KeyTimer2   by Jesus4Lyf
//|           - AIDS        by Jesus4Lyf
//|           - SimError    by Vexorian
//|           - Table       by Vexorian
//| 
//| Usage: call BladeBarrier_Create( unit source, unit target, integer level )
//|
//| How to import:
//| -------------
//| 1) Copy this trigger, and all requirements listed above into your map. 
//|    (You can copy the folder)
//| 2) Go to AIDS system, and follow it&#039;s implementation steps.
//| 3) Copy any object with Blade Barrier in it.
//| 4) Import the custom pitchModel into your map.
//| 5) Update all rawcodes.
//|
//+----------------------------------------------------------------------------------+
//|
//| - All credit to Tossrock, creator or Pudge Wars Advanced for the spell concept.
//|
//+----------------------------------------------------------------------------------+

//+-----------------------------------------------------------------------------------------------------------------------------------+\\
//+                                                     CONFIGURABLES SECTION
//+-----------------------------------------------------------------------------------------------------------------------------------+\\
    globals
        private constant integer ABILITY_ID = &#039;A004&#039;   // &quot;Blade Barrier&quot; ability ID. This causes the response.
        private constant integer DUMMY_ID   = &#039;h001&#039;   // Rawcode of the required dummy unit. Must used the PitchDummy.MDX model.
                
        private constant real    TIMER_PERIOD  = 0.03  // Movement of Blades done every TIMER_PERIOD.
        private constant real    DAMAGE_PERIOD = 0.10  // Units are damaged every DAMAGE_PERIOD.
        
        private constant boolean ALLOW_MULTI_INSTANCE = false // If enabled, more than one Blade Barrier&#039;s can be made per unit.
        private constant string  ERROR_MSG            = &quot;You can only have one Blade Barrier at once.&quot;
        
        //=====================================================
        
        private constant attacktype ATTACK_TYPE      = ATTACK_TYPE_CHAOS
        private constant damagetype DAMAGE_TYPE      = DAMAGE_TYPE_NORMAL
        private constant weapontype WEAPON_TYPE      = null
        private constant real       COLLISION_SIZE   = 32    // Collision size of units... well Pudge. 
        
        private constant real       BLADE_SPINSPEED  = 8.00
        private constant real       BLADE_ANGLESPEED = 0.12
        
        //=====================================================

        // Where damage effects are made.
        private constant boolean DO_DMG_SFX = true
        private constant string  DMG_SFX    = &quot;Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl&quot;
        private constant string  DMG_LOC    = &quot;chest&quot;
        
        // When a unit is killed by Blade Barrier, create these effects.
        private constant boolean DO_DEATH_SFX = false
        private constant string  DEATH_SFX    = &quot;&quot;
        private constant string  DEATH_LOC    = &quot;&quot;
        
        //=====================================================
        // Sounds:
        // --------
        // They are played every x ticks of the TIMER_PERIOD, which is 0.075 seconds. One of the sounds below is chosen to play.
        // Note: Some sounds cannot be played rapidly.
        
        private constant real    SOUND_EVERY  = 0.09  // It has to be a multiple of TIMER_PERIOD.
        private constant integer SOUND_VOLUME = 50    // The volume of the created sounds. Max is 127.
        
        private constant string  SOUND_ONE   = &quot;Sound\\Units\\Combat\\MetalLightSliceMetal1.wav&quot;
        private constant string  SOUND_TWO   = &quot;Sound\\Units\\Combat\\MetalLightSliceMetal2.wav&quot;
        private constant string  SOUND_THREE = &quot;Sound\\Units\\Combat\\MetalLightSliceMetal3.wav&quot;
        
        private constant string  SOUND_PARAM = &quot;MetalLightSliceMetal&quot;
        private constant string  SOUND_EAX   = &quot;CombatSoundsEAX&quot;
        
        private constant integer SOUND_DUR_1 = 376
        private constant integer SOUND_DUR_2 = 480
        private constant integer SOUND_DUR_3 = 461
        
        //=====================================================
        // Models:
        // -------
        // What shall your Blade Barrier look like?
        private constant boolean FADE       = true // Or else its death animation will be played.
        private constant real RANGE_OFFSET  = 20   // Blade will be created at RADIUS (function) + GetRandomReal( -20, 20 )
        
        // The unit is not created with this colour for effiency.
        // You must make sure these match the Object Editor&#039;s values unless you want an odd result.
        private constant integer RED        = 255
        private constant integer GREEN      = 255
        private constant integer BLUE       = 255
        
        private constant real    HEIGHT     = 60.00
        
        private constant string MODEL_ONE   = &quot;Abilities\\Weapons\\BloodElfSpellThiefMISSILE\\BloodElfSpellThiefMISSILE.mdl&quot;
        private constant string MODEL_TWO   = &quot;Abilities\\Weapons\\BloodElfSpellThiefMISSILE\\BloodElfSpellThiefMISSILE.mdl&quot;
        private constant string MODEL_THREE = &quot;Abilities\\Weapons\\BloodElfSpellThiefMISSILE\\BloodElfSpellThiefMISSILE.mdl&quot;
        
        // Should the death animation be that of the original Pudge Wars?
        private constant boolean ORIGINAL_DEATH_ANIM = false 
    endglobals
 
    //+------------------------+
    //|   Don&#039;t touch below.   |
    //+------------------------+
    native UnitAlive takes unit id returns boolean
    private keyword BladeBarrier
    
    globals
        private constant integer INLINED_VOLUME = R2I(SOUND_VOLUME * 127.00 * 0.01)
        private BladeBarrier tempData = 0
    endglobals
    
    // Now you may start poking numbers again.

    //===========================================================\\
    // Unit filter:
    // - Organic
    // - Living
    // - Enemy

    private function IsTargetValid takes unit whichUnit returns boolean
        return  IsUnitEnemy( whichUnit, tempData.owner )                    and /* Enemy
        */      IsUnitType( whichUnit, UNIT_TYPE_STRUCTURE ) == false       and /* Structure
        */      UnitAlive( whichUnit )                                      and /* Alive
                Don&#039;t touch this one.                                           
        */      IsUnitInGroup( whichUnit, tempData.damageGroup ) == false
    endfunction

    //===========================================================\\
    // Damage per second.

    private function DPS takes integer level returns real
        return level * 250.
    endfunction

    //===========================================================\\
    // Blade Barrier duration.

    private function DURATION takes integer level returns real
        return 20.00
    endfunction

    //===========================================================\\
    // Area of the spell. 
    private function RADIUS takes integer level returns real
        return 200.00
    endfunction
    
    //===========================================================\\
    // How many Blade effects are created?
    private function BLADES takes integer level returns integer
        return level * 20
    endfunction
    
//+-----------------------------------------------------------------------------------------------------------------------------------+\\
//+                                                        END CONFIGURABLES
//+                                                    BLADE BARRIER STARTS HERE.
//+-----------------------------------------------------------------------------------------------------------------------------------+\\
            
            
    static if not ALLOW_MULTI_INSTANCE then             // Do not create the group if its true. Waste of variable.
        globals
            private group ACTIVE_GROUP = CreateGroup()  // Required group if you only want one barrier per unit.
        endglobals
    endif
    
    //----------------------------------------------------
    // BladeUnitData: Handles the blade units.
    //----------------------------------------------------
    private struct BladeUnitData extends array
        //! runtextmacro AIDS()
        unit    blade
        effect  fxpath
        integer pitch
        
        real pitchDir
        real rotationDir
        real angle
        real angleDir
        real radius
        
        static method AIDS_filter takes unit u returns boolean
            return GetUnitTypeId( u ) == DUMMY_ID
        endmethod
        
        method cleanup takes nothing returns nothing
            call DestroyEffect( this.fxpath )
            static if FADE then
                call RemoveUnit( this.blade )
            else
                call KillUnit( this.blade )
            endif
        endmethod
    endstruct
    
//------------------------------------------------------------------------------------------
//                                      DAMAGE SECTION
//------------------------------------------------------------------------------------------

    private struct DamageData
        BladeBarrier     originData // Used to keep track of the parent data.
        unit target     = null      // Assigned target.
        real dps        = 0.00      // Damage per Second.
        
        real radius_45  = 0.00
        real radius_80  = 0.00
        
        private static method periodic takes nothing returns boolean
            local thistype this = KT_GetData()
            local real tx    = GetUnitX( this.target )
            local real ty    = GetUnitY( this.target )
            local real tempX = this.originData.cx - tx
            local real tempY = this.originData.cy - ty
            
            if  this.originData.sec &gt;= this.originData.dur                  or   /* Expired
            */  ( tempX*tempX+tempY*tempY ) &gt; this.radius_45                or   /* Exit barrier radius
            */  not UnitAlive( this.originData.caster )                     or   /* Dead caster
            */  not UnitAlive( this.target )                                then // dead target 
            
                call GroupRemoveUnit( this.originData.damageGroup, this.target )
                call this.destroy()
                return true
            endif
            
            if ( tempX*tempX+tempY*tempY ) &gt; this.radius_80 then
                static if DO_DMG_SFX then
                    call DestroyEffect( AddSpecialEffectTarget( DMG_SFX, this.target, DMG_LOC ) )
                endif
                call UnitDamageTarget( this.originData.source, this.target, this.dps, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE )

                if not UnitAlive( this.target ) then
                    static if DO_DEATH_SFX then
                        call call DestroyEffect( AddSpecialEffectTarget( DEATH_SFX, this.target, DEATH_SFX_LOC ) )
                    endif
                    call this.destroy()
                    return true
                endif
            endif
            
            return false
        endmethod
        
        static method create takes unit u, BladeBarrier i returns thistype
            local thistype this = thistype.allocate()
            
            set this.originData = i
            set this.target     = u
            set this.dps        = DPS( i.level ) * DAMAGE_PERIOD // Level is stored, incase you leveled up the skill while the blade is active.
            
            set this.radius_45  = (i.radius+45)*(i.radius+45)
            set this.radius_80  = (i.radius-80)*(i.radius-80)
            
            call GroupAddUnit( i.damageGroup, u )
            call KT_Add( function thistype.periodic, this, DAMAGE_PERIOD )
            return this
        endmethod
    endstruct
                
    private struct BladeBarrier
        boolean early  = false  // Was the spell cancelled early?
    
        unit   source  = null
        player owner   = null
        unit   caster  = null

        integer level  = 0

        real   cx      = 0.00
        real   cy      = 0.00
        real   cz      = 0.00
        real   radius  = 0.00
        
        real ticks    = 0.00
        integer alpha = 255
        real sec      = 0.00
        real dur      = 0.00
        
        group bladeGroup  = null
        group damageGroup = null

        trigger t = null

        static HandleTable data  = 0

        // Creates yet another blade to add into the barrier.
        private method AddBlade takes nothing returns nothing
            local unit blade = CreateUnit( this.owner, DUMMY_ID, this.cx, this.cy, 0 )
            local BladeUnitData bdata = BladeUnitData[blade]
            local integer n = GetRandomInt( 0, 2 )
            
            // Add a bit of variety into the blades, aye?
            set bdata.rotationDir = GetRandomReal( 0.40, 1.60 )
            set bdata.pitchDir    = GetRandomReal( 0.40, 1.60 )
            set bdata.angleDir    = GetRandomReal( 0.40, 1.60 )
            
            if GetRandomInt( 0, 1 ) == 0 then
                set bdata.rotationDir = bdata.rotationDir * -1
                set bdata.angleDir    = bdata.angleDir    * -1
            else
                set bdata.pitchDir    = bdata.pitchDir    * -1
            endif

            set bdata.blade  = blade
            set bdata.pitch  = GetRandomInt( 0 ,180 )
            set bdata.radius = this.radius + GetRandomReal( -RANGE_OFFSET, RANGE_OFFSET )
            set bdata.angle  = GetRandomReal( -bj_PI, bj_PI )

            if n == 0 then
                set bdata.fxpath = AddSpecialEffectTarget( MODEL_ONE, blade, &quot;origin&quot; )
            elseif n == 1 then
                set bdata.fxpath = AddSpecialEffectTarget( MODEL_TWO, blade, &quot;origin&quot; )
            elseif n == 2 then
                set bdata.fxpath = AddSpecialEffectTarget( MODEL_THREE, blade, &quot;origin&quot; )
            endif
            call GroupAddUnit( this.bladeGroup, blade )
            
            set blade = null
        endmethod
        
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    
        private static method rotateBlade takes nothing returns nothing
            local unit bladeUnit  = GetEnumUnit()
            local BladeUnitData bdata = BladeUnitData[bladeUnit]
            local integer newPitch    = ModuloInteger( bdata.pitch + R2I( bdata.pitchDir * BLADE_SPINSPEED ), 180 )
            local real newFacing      = GetUnitFacing( bladeUnit ) + bdata.rotationDir   * BLADE_SPINSPEED
            local real x = tempData.cx + bdata.radius * Cos( bdata.angle )
            local real y = tempData.cy + bdata.radius * Sin( bdata.angle )

            call SetUnitAnimationByIndex( bladeUnit, newPitch )
            call SetUnitFacing( bladeUnit, newFacing )
            call SetUnitX( bladeUnit, x )
            call SetUnitY( bladeUnit, y )
            set bdata.angle = bdata.angle + bdata.angleDir * BLADE_ANGLESPEED
            
            set bladeUnit = null
        endmethod
        
        private method createBladeSound takes nothing returns nothing
            local integer r = GetRandomInt( 0, 2 )
            local sound   s = null

            if r == 0 then
                set s = CreateSound( SOUND_ONE, false, true, true, 10, 10, SOUND_EAX )
                call SetSoundParamsFromLabel( s, SOUND_PARAM )
                call SetSoundDuration( s, SOUND_DUR_1 )
            elseif r == 1 then
                set s = CreateSound( SOUND_TWO, false, true, true, 10, 10, SOUND_EAX )
                call SetSoundParamsFromLabel( s, SOUND_PARAM )
                call SetSoundDuration( s, SOUND_DUR_2 )
            elseif r == 2 then
                set s = CreateSound( SOUND_THREE, false, true, true, 10, 10, SOUND_EAX )
                call SetSoundParamsFromLabel( s, SOUND_PARAM )
                call SetSoundDuration( s, SOUND_DUR_3 )
            endif

            call SetSoundVolume( s, INLINED_VOLUME )
            call SetSoundPosition( s, this.cx, this.cy, GetUnitFlyHeight( this.caster ) )
            call StartSound( s )
            call KillSoundWhenDone( s )
            
            set this.ticks = 0.00
            set s = null
        endmethod
        
        private static method adjustHeight takes nothing returns nothing
            call SetUnitFlyHeight( GetEnumUnit(), tempData.cz + HEIGHT, 0.00 )
        endmethod

        private static method periodic takes nothing returns boolean
            local thistype this = KT_GetData()
            local real     z    = GetUnitFlyHeight( this.caster )
            
            set this.cx = GetUnitX( this.caster )
            set this.cy = GetUnitY( this.caster )
            
            set tempData = this
            call ForGroup( this.bladeGroup, function thistype.rotateBlade )
            
            if z != this.cz then
                set this.cz = z
                call ForGroup( this.bladeGroup, function thistype.adjustHeight )
            endif
            
            set this.ticks = this.ticks + TIMER_PERIOD
            if ModuloReal( this.ticks, SOUND_EVERY ) == 0.00 then
                call this.createBladeSound()
            endif
            
            set this.sec = this.sec + TIMER_PERIOD
            if this.sec &gt;= this.dur or not UnitAlive( this.caster ) then
                static if not ALLOW_MULTI_INSTANCE then 
                    call GroupRemoveUnit( ACTIVE_GROUP, this.caster )
                endif
                call thistype.data.flush( this.t )
                call DestroyTrigger( this.t )
                
                static if ORIGINAL_DEATH_ANIM then
                    set this.sec  = 15.00
                endif
                set this.ticks    = 0

                static if FADE then
                    call KT_Add( function thistype.release, this, TIMER_PERIOD )
                else
                    call this.destroy()
                endif
                
                return true
            endif
            return false
        endmethod
        
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        private static method GroupDestroy takes nothing returns nothing
            call BladeUnitData[GetEnumUnit()].cleanup()
        endmethod
                
        private static method deathBlade takes nothing returns nothing
            local unit u = GetEnumUnit()
            local BladeUnitData bdata = BladeUnitData<u>
            
            call SetUnitAnimationByIndex( u, ModuloInteger( bdata.pitch + R2I( bdata.pitchDir * BLADE_SPINSPEED ), 180 ) )
            call SetUnitFacing( u, GetUnitFacing( u ) + bdata.rotationDir * BLADE_SPINSPEED )
            call SetUnitX( u, tempData.cx + bdata.radius * Cos( bdata.angle ) )
            call SetUnitY( u, tempData.cy + bdata.radius * Sin( bdata.angle ) )
            
            set bdata.radius = bdata.radius - 18 / ( tempData.sec - 13 )
            call SetUnitVertexColor( u, RED, GREEN, BLUE, tempData.alpha ) 
        endmethod
        
        private static method release takes nothing returns boolean
            local thistype this = KT_GetData()

            set tempData = this
            call ForGroup( this.bladeGroup, function thistype.deathBlade )
            
            set this.ticks = this.ticks + 1
            set this.sec   = this.sec   + TIMER_PERIOD
            set this.alpha = R2I( 255 - this.ticks * 3 )
            
            if this.alpha &lt;= 0.00 then
                call this.destroy()
                return true
            endif
        
            return false
        endmethod

        private static method damageCond takes nothing returns boolean
            local unit u = GetTriggerUnit()
            if IsTargetValid( u ) then 
                call DamageData.create( u, thistype( thistype.data[GetTriggeringTrigger()] ) )
            endif
            set u = null
            return false
        endmethod
        
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        private method onDestroy takes nothing returns nothing
            call ForGroup( this.bladeGroup, function thistype.GroupDestroy )
        endmethod
        
        static method create takes unit sourceUnit, unit whichUnit, integer level returns thistype
            local thistype this = thistype.allocate()
            local integer  i    = 0
            
            // sourceUnit  --&gt; Who cast the spell. They will be responsible for damage.
            // whichUnit   --&gt; Who is the centre of the barrier.
            // whichPlayer --&gt; Who owns the Blade Barrier.
            
            static if not ALLOW_MULTI_INSTANCE then
                if IsUnitInGroup( whichUnit, ACTIVE_GROUP ) then
                    call SimError( GetOwningPlayer( sourceUnit ), ERROR_MSG )
                    set this.early = true
                    call this.deallocate()
                    return 0
                endif
            endif
            
            if this.bladeGroup == null then
                set this.bladeGroup = CreateGroup()
            else
                call GroupClear( this.bladeGroup )
            endif
            
            if this.damageGroup == null then
                set this.damageGroup = CreateGroup()
            else
                call GroupClear( this.damageGroup )
            endif

            set this.source = sourceUnit
            set this.caster = whichUnit
            set this.cx     = GetUnitX( whichUnit )
            set this.cy     = GetUnitY( whichUnit )
            set this.cz     = GetUnitFlyHeight( whichUnit )
            set this.owner  = GetOwningPlayer( sourceUnit )
            set this.level  = level
            set this.dur    = DURATION( this.level ) 
            set this.radius = RADIUS  ( this.level )
            
            loop
                exitwhen i == BLADES( this.level )
                call this.AddBlade()
                set i = i + 1
            endloop
                        
            set tempData = this
            set this.t = CreateTrigger()
            set thistype.data[this.t] = this
            call TriggerRegisterUnitInRange( this.t, this.caster, this.radius + ( 45 - COLLISION_SIZE ), null )
            call TriggerAddCondition( this.t, function thistype.damageCond )
            
            static if not ALLOW_MULTI_INSTANCE then
                call GroupAddUnit( ACTIVE_GROUP, this.caster )
            endif   

            call KT_Add( function thistype.periodic, this, TIMER_PERIOD )
            return this
        endmethod
    endstruct
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Event responses:
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    private function onCast takes nothing returns boolean
        local unit u = GetTriggerUnit()
        if IsUnitInGroup( u, ACTIVE_GROUP ) then
            call PauseUnit( u, true )
            call IssueImmediateOrder( u, &quot;stop&quot; )
            call PauseUnit( u, false )
            call SimError( GetTriggerPlayer(), ERROR_MSG )
        endif
        set u = null
        return false
    endfunction
    
    // onEffect: response to the no target ability, it directly utilizes the struct.
    private function onEffect takes nothing returns boolean
        local unit u = GetTriggerUnit()
        call BladeBarrier.create( u, u, GetUnitAbilityLevel( u, ABILITY_ID ) )
        set u = null
        return false
    endfunction
    
    // BladeBarrier_Create: uses a boolean for determining whether a instance was 
    // successful or not, eg: powerups.
    public function Create takes unit source, unit target, integer level returns boolean
        local BladeBarrier barrier = BladeBarrier.create( source, target, level )

        if barrier == 0 then
            return false
        endif

        return true
    endfunction
    
    private function onInit takes nothing returns nothing
        call GT_AddStartsEffectAction( function onEffect, ABILITY_ID )
        static if not ALLOW_MULTI_INSTANCE then
            call GT_AddBeginsChanellingAction( function onCast, ABILITY_ID )
        endif
        set BladeBarrier.data = Table.create()
    endfunction

endlibrary</u>


CHANGELOG:

v1.04b - 11/07/2010
  • Made one more [ljass]IsUnitType( unit, UNIT_TYPE_DEAD )[/ljass] call to [ljass]UnitAlive[/ljass].

v1.04a - 01/07/2010
  • Removed dependency on Damage. Added configurable [ljass]attacktype[/ljass], [ljass]damagetype[/ljass], and [ljass]weapontype[/ljass].
  • Made one barrier per instance blocked in the create method as well.
  • Added a possible death animation if a unit is killed by this ability.
  • SOUND_EVERY is now in seconds.
  • Blade Barrier will now track it's target's height.
  • The number of blades created can now be adjusted by a configurable function which takes a level.
  • Changed [ljass]IsUnitType( unit, UNIT_TYPE_DEAD )[/ljass] calls to [ljass]UnitAlive[/ljass].
  • DamageData now ends if the damage dealt kills the target rather than on the next timer iteration.
  • BladeUnitData now longer checks for a null effect or nulls the unit.
  • Cleaned up the BladeBarrier struct a bit.
  • Added colouring global configs. for the Blade Barrier units.
  • Create method no longer takes a player, but takes a integer level now.
  • Inlined the INLINED_VOLUME.
  • Added a new function: [ljass]public function Create takes unit source, unit target, integer level returns boolean[/ljass]
  • No longer using GroupUtils for recylcing.

v1.03 - 26/06/2010
  • It actually was not MUI. Fixed this.
  • Privatalized a shitload of members. I don't know why.
  • When a unit in the damage group left the radius, they couldn't get back in, fixed this.

v1.02 - 03/06/2010
  • Code optimisation
  • Added a configurable to have the original death animation
  • Fixed the configurables
  • Create method takes a player, and a unit - sourceUnit and whichPlayer
  • Fixed the target Blade Barrier - still no support for one instance per target.
  • Removed the target from the 'damage whirl' when they die.

v1.01 - 16/05/2010
  • Code improvement
  • Allowed option for instant removal of blades or fade out
  • Allowed option for one barrier per unit
  • Changed creation method of struct to take a unit, to allow in making a 'target' Blade Barrier (Dinowc)

v1.00 - 13/05/2010
  • Initial release
 

Attachments

  • Blade Barrier v1.04b.w3x
    110.4 KB · Views: 466

Chaos_Knight

New Member
Reaction score
39
MRFAN, just a question, How do you highlight those
JASS:
/* COMMENT HERE */
??

Otherwise, awsome spell. Maybe way to many Blades... 25 would be enough. :thup:
 

BlackRose

Forum User
Reaction score
239
I thought my name had numbers in it
images


What do you mean highlight? If you mean how to highlight delimited comments in NewGen, update your Tesh. Here is one: http://cjass.xgm.ru/#horus

But I think there is an updated one by Artificial somewhere? I dunno.

--

Thanks! And the number of blades IS configurable. But original Pudge Wars had 60.
 

Furby

Current occupation: News poster
Reaction score
144
You're using local variable in periodic method of type sound which has no use in whole function.
 

BlackRose

Forum User
Reaction score
239
Oops. I originally had the soundmethod in the if, but moved it. I'll fix that up along with a few other things :D
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
JASS:
private function DPS takes integer level returns real
       return level * 100.
endfunction

damage per level is not configurable

same with duration and AOE

you could also make a Unit Target version of the spell

anyway, looks pretty neat, but maybe a bit too much blades for my taste :p
 

BlackRose

Forum User
Reaction score
239
Yeah. I had been meaning to set them into funcs. And why isn't DPS configurable? o_O

[ljass]call BladeData.create( whichUnit )[/ljass] - As the one in Pudge War's is done.
 

BlackRose

Forum User
Reaction score
239
constant function? or constant global? There's no use in having it as global constant when you just modify it directly o_O?
 

Viikuna

No Marlo no game.
Reaction score
265
Id rather just make some custom special effect for Blade Barrier. ( Example )

Anyways, its still pretty cool, though.
 

BlackRose

Forum User
Reaction score
239
Ionno how to model .__.

Updated!

Added a target version too! Although the one instance per unit is not supported by that one.
 

BlackRose

Forum User
Reaction score
239
I don't :D

But if something deals damage, I use Damage, I'm use to that lol.

And nothing wrong with SimError? I need it to show you can only have one barrier per unit if enabled. Yes I could actually make it myself or copy it entirely in but I'd prefer having like this :D
 

Laiev

Hey Listen!!
Reaction score
188
I don't see any problem with simerror and damage, most of people use then... so, no problem :rolleyes:
 

Crazy_Dead

New Member
Reaction score
24
I think, maybe people dont want overdriven many systems in their maps, just taking up memory, when you simply can use:

JASS:
call UnitDamageTarget(/*ARGUMENTS HERE*/)

instead of
JASS:
call UnitDamageTargetEx(/*<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />*/)
 

BlackRose

Forum User
Reaction score
239
Well, some people might use some other Damage system. And if they are, they should have enough knowledge to edit it themselves.
 
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