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: 525
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:
 
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.
 
You're using local variable in periodic method of type sound which has no use in whole function.
 
Oops. I originally had the soundmethod in the if, but moved it. I'll fix that up along with a few other things :D
 
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
 
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.
 
constant function? or constant global? There's no use in having it as global constant when you just modify it directly o_O?
 
Id rather just make some custom special effect for Blade Barrier. ( Example )

Anyways, its still pretty cool, though.
 
Ionno how to model .__.

Updated!

Added a target version too! Although the one instance per unit is not supported by that one.
 
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
 
I don't see any problem with simerror and damage, most of people use then... so, no problem :rolleyes:
 
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" />*/)
 
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.
  • Ghan Ghan:
    But the electorate would have to demand it and vote people in to do it.
  • Ghan Ghan:
    Government spending, foreign policy, and the southern border are all bigger issues than the income tax right now I'd say.
  • The Helper The Helper:
    For you those are the bigger issues. Cannabis legalization and get rid of Income tax are mine.
  • Ghan Ghan:
    We have so much cannabis up here in Oklahoma. Can't go a block without running into 3 dispensaries. xD
  • The Helper The Helper:
    if the demand is there
  • jonas jonas:
    I think the biggest issue in USA is how divided the country has become
  • Ghan Ghan:
    There's a big split happening in fundamental values that is very worrisome.
  • jonas jonas:
    I think there's always been a split in values. But now there's a split in what reality is. No matter whom you ask, they think a third of the country is insane and wants to destroy the country
  • The Helper The Helper:
    pretty big split
  • The Helper The Helper:
    Happy Saturday!
    +1
  • V-SNES V-SNES:
    Happy Saturday!
    +1
  • The Helper The Helper:
    Dont forget to check out the list of all the recipes on the site at the Recipe Index - I am about to take Ghan up on the offer of making that a site :) https://www.thehelper.net/threads/main-recipes-menu-recipes-index-version-2-0.189517/
  • The Helper The Helper:
    We should add that as part of site navigation
  • Varine Varine:
    I just don't think Trump actually understands how the government works. I'm not going to pretend like I can understand the entirety of government but in my industry he kind of caused massive fucking issues. Tarriffs and the international counters had a pretty significant impact on what I do, it was actually kind of interesting to see though. I live in Idaho so I'm not really concerned with it, it'll be R pretty much the entire way down. We do have ranked choice on our ballot this year though and I DO really care about that. But if we are going to have a federal government we kind of need income tax. They could abolish it and tax states I guess, but then states are just going to raise income taxes. It's not really viable without a very significant and holistic overhaul of how the federal government works, and that isn't something I would expect Trump to do.
  • Varine Varine:
    I don't expect Harris to do it either. I want to see wealth and church taxes, but those also aren't things I'm going to hold my breath for.
  • jonas jonas:
    I mean he definitely doesn't, which is why he had to retract most of his executive orders, didn't manage to get rid of obamacare etc.
  • jonas jonas:
    B
  • jonas jonas:
    Replacing income tax with a wealth tax would be amazing imho, but I can't even imagine that this would happend
  • Ghan Ghan:
    Wealth tax would be a disaster. Imagine having to liquidate retirement accounts because you have a tax bill just for unrealized gains. Or your house goes up in price and you have to sell it to pay the tax bill.
  • jonas jonas:
    I'm not talking about an income tax on wealth gain.
  • jonas jonas:
    we already have a wealth tax on our house, it's called a property tax. I'm talking about extending that to other income-generating assets like private equity, bonds and stocks.
  • jonas jonas:
    I agree that the effect of that would be to depress asset prices, but I think that's a good thing. Makes it easier for hard working young people to grow their retirement income
    +1
  • seph ir oth seph ir oth:
    Potential problem for a wealth tax for the US would be the ultra rich just offshoring assets in another country without a wealth tax. Those that would eat the wealth tax on, say, stocks, would be the middle class that puts money slowly into the market via the likes of funds.
  • seph ir oth seph ir oth:
    happy US election day btw!
  • Varine Varine:
    Oh election day

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top