Spell Blade Barrier

BlackRose

Forum User
Blade Barrier by BlackRose

v1.04 - 04/07/2010​

Screenshot:

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 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'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 = 'A004'   // &quot;Blade Barrier&quot; ability ID. This causes the response.
        private constant integer DUMMY_ID   = 'h001'   // 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'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'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'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'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

Chaos_Knight

New Member
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
I thought my name had numbers in it


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.
 

Dinowc

don't expect anything, prepare for everything
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
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.
 

Viikuna

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

Anyways, its still pretty cool, though.
 

BlackRose

Forum User
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
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!!
I don't see any problem with simerror and damage, most of people use then... so, no problem :rolleyes:
 

Crazy_Dead

New Member
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" data-shortname=":p" />*/)
 

BlackRose

Forum User
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 The Helper:
    Friday Yay!
  • mgarcia mgarcia:
    did you guys catch Carl's interview? https://www.youtube.com/watch?v=kuHiMXABkGs
  • mgarcia mgarcia:
    he's the one that informed me about the DVD's working!
  • mgarcia mgarcia:
    he also mentioned the progress on the controllers!
  • The Helper The Helper:
    I did actually it was cool to see the NUON mention
  • The Helper The Helper:
    https://discord.com/channels/985377399338332202/985377399950696481 you can still use this chat too we are two fisted now :)
  • thewrongvine thewrongvine:
    costs me $80 to fill gas tank sad face
  • Ghan Ghan:
    Oof
  • The Helper The Helper:
    Yeah that gas is some expensive stuff :)
  • The Helper The Helper:
    ghan does not have to worry about it he has a tesla and I have a small tank so it does not cost me usually more than 50
  • The Helper The Helper:
    fyi Ghan we are getting an error trying to access stats or world editor tutorials Error 526 Ray ID: 72128c6bf99f6707 • 2022-06-26 02:35:15 UTCInvalid SSL certificate
  • Ghan Ghan:
    An artifact of switching to Cloudflare... the Let's Encrypt certs can't autorenew through Cloudflare.
  • Ghan Ghan:
    I got the forum updated before things expired but there were some other casualties.
  • Ghan Ghan:
    Everything should be fixed now....
  • The Helper The Helper:
    Thank you Ghan!
  • The Helper The Helper:
    Happy Monday!
  • The Helper The Helper:
    new NUON forum mod cubanral!
    +1
  • The Helper The Helper:
  • tom_mai78101 tom_mai78101:
    Started learning how to make tools-assisted speedruns, so I'm lately busy.
  • tom_mai78101 tom_mai78101:
    Here's my current project.
    +3
  • O Old Mountain Shadow:
    that was pretty good!
  • jonas jonas:
    really cool! I saw the game before but always thought it's just a half as good double dragon. Now I realize it actually has a lot of depth!
  • The Helper The Helper:
    I just saw a bunch of running and jumping past all the enemies look like it was scripted as he said I guess I should have watched the whole thing. I only got a couple of minutes in. You should post that video in the forum Tom
  • Darthfett Darthfett:
    "Hi in the chat!"
    +1
  • tom_mai78101 tom_mai78101:
    Currently busy with making the run even better, so I'll post that new one once I'm done. Right now, I had to modify the emulator itself, the tools that makes this video, and some RAM address disassembling / reverse-engineering to get the right values, and such.
    +1

    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