1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. The poll for our 11th Music Contest is up! Help us choose the most awesome cinematic tracks by casting a vote!
    Dismiss Notice
  3. Melee Mapping contest #3 - Poll is up! Vote for the best 4v4 melee maps!
    Dismiss Notice
  4. The 30th edition of the Modeling Contest is finally up! The Portable Buildings need your attention, so come along and have a blast!
    Dismiss Notice
  5. The Aftermath has been revealed for the 19th Terraining Contest! Be sure to check out the Results and see what came out of it.
    Dismiss Notice

Massive Cleave V1.01

Submitted by Tank-Commander
This bundle is marked as approved. It works and satisfies the submission rules.
Massive Cleave

Tooltip

Icon
[​IMG]


Q - Massive Cleave
Cleaves enemies in an arc in front of the caster sending them flying in terror

Level 1 - 100 damage, small area
Level 2 - 120 damage, medium area
Level 3 - 140 damage, large area


Code
Show
Code (vJASS):

////////////////////////////////////////////////////////////////////
//                     MASSIVE CLEAVE V1.01                       //
//  Author: Tank-Commander                                        //
//  Purpose: A powerful keepaway ability for scaring opposition   //
//                                                                //
//  Requires:                                                     //
//    - (optional) BUS_Knockback by Tank-Commander                //
//      remove lines outlined by "******" in code if not used     //
//                                                                //
//  Notes:                                                        //
//    -  Read the readme before you try modifying the config      //
//    -  Use the "Helpful files" to help you import the system    //
//                                                                //
//  Credits:                                                      //
//    -  (Dummy.mdl) Vexorian                                     //
//                                                                //
//  If you have used this spell in your map, you are required     //
//  to give credits to Tank-Commander for the creation of it      //
//  If you would like to use snippets of code from this for       //
//  whatever, getting permission and crediting the source/linking //
//  would be much appreciated.                                    //
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
//  README:                                                       //
//    Before modifying this spell a few things need to be         //
//    understood and read, this is one of those things, while     //
//    most modification can be considered intuitive, it still     //
//    helps to read through these intstructions, as they will     //
//    inform you about how to configure this spell to your        //
//    desire.                                                     //
//----------------------------------------------------------------//
//  Initial importing: The variable creator trigger can be        //
//  imported first and if you have the correct settings (file,    //
//  preferences, General, automatically create unknown variables  //
//  checked, then when you paste in the variable creator it       //
//  will automatically give you all the variables you need for    //
//  this spell                                                    //
//                                                                //
//  While the remaining object editor based data is not required  //
//  to function (provided they're replaced with equivelents)      //
//  it's recommended that they are also imported, if their data   //
//  value are not the same as listed in the configuration, those  //
//  configurables will need to be changed to work correctly       //
//----------------------------------------------------------------//
//                           MISC                                 //
//----------------------------------------------------------------//
//  TimerSpeed: the time in seconds between each iteration of     //
//  the main loop function (default is 0.031250000) it's          //
//  recommended you leave it like that                            //
constant function MC_TimerSpeed takes nothing returns real
    return 0.031250000
endfunction
//----------------------------------------------------------------//
//  Ability: This is the data value of the ability used as the    //
//  base, make sure it is based off channel (to view raw data     //
//  press ctrl + d, pressing again switches back)                 //
constant function MC_Ability takes nothing returns integer
    return 'A000'
endfunction
//----------------------------------------------------------------//
//  DummyID: This is the data value of the unit to be used as the //
//  dummy for blood effects generated by the cleave               //
constant function MC_DummyID takes nothing returns integer
    return 'u000'
endfunction
//----------------------------------------------------------------//
//  OrderID: This is the order ID used by the ability to tell if  //
//  the unit is still channelling the ability and cancelling it   //
//  if it stops (852474 is default for 1.28)                      //
constant function MC_OrderID takes nothing returns integer
    return 852473
endfunction
//----------------------------------------------------------------//
//  Attachmentpoint: This is the location on the Dummy unit that  //
//  blood effects will be placed on                               //
constant function MC_AttachmentPoint takes nothing returns string
    return "origin"
endfunction
//----------------------------------------------------------------//
//  Clockwise: Determines what direction the cleave will take     //
//  (set it to match the handedness of the unit(s) using the      //
//  ability, righthanded: anticlockwise, lefthanded: clockwise    //
constant function MC_Clockwise takes nothing returns boolean
    return false
endfunction
//----------------------------------------------------------------//
//  Timer: How long in seconds dummy units are alive for          //
constant function MC_Timer takes nothing returns real
    return 3.
endfunction
//----------------------------------------------------------------//
//  DummyPlayer: The owning player of the dummy units             //
constant function MC_DummyPlayer takes nothing returns player
    return Player(14)
endfunction
//----------------------------------------------------------------//
//  AttackType: The attack type used when dealing damage         //
constant function MC_AttackType takes nothing returns attacktype
    return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//  DamageType: The damage type used when dealing damage          //
constant function MC_DamageType takes nothing returns damagetype
    return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
//                        MAIN ABILITY                            //
//----------------------------------------------------------------//
//  AOE: The Area around the caster that the cleave reaches       //
function MC_AOE takes real level returns real
    return 250 + (25 * level)
endfunction
//----------------------------------------------------------------//
//  EffectDistance: How far away from the caster blood effects    //
//  are created
function MC_EffectDistance takes real level returns real
    return 150 + (25 * level)
endfunction
//----------------------------------------------------------------//
//  Angle: The angle covered by the cleave (radians) bj_PI = 90   //
//  degrees, it will eb centered around the unit facing angle     //
function MC_Angle takes real level returns real
    return 1.7 + (0.26 * level)
endfunction
//----------------------------------------------------------------//
//  Divisions: This is the amount of segments in your cleave      //
//  it's recommended to have at least 3 for all levels            //
function MC_Divisions takes real level returns real
    return 2 + (1 * level)
endfunction
//----------------------------------------------------------------//
//  HealthDamage: The amount of damage your cleave deals to       //
//  the health of units hit                                       //
function MC_HealthDamage takes real level returns real
    return 80 + (20 * level)
endfunction
//----------------------------------------------------------------//
//  ManaDamage: The amount of damage your cleave deals to the     //
//  mana of units hit                                             //
function MC_ManaDamage takes real level returns real
    return 0.
endfunction
//----------------------------------------------------------------//
//  InitialDelay: The time after starting the ability that the    //
//  first cleave segment is used and units are hit in seconds     //
function MC_InitialDelay takes real level returns real
    return .20 + (-0.01 * level)
endfunction
//----------------------------------------------------------------//
//  DivisionDelay: The time between each cleave segment being     //
//  used and units getting hit in seconds                         //
function MC_DivisionDelay takes real level returns real
    return 0.04 + (-0.01 * level)
endfunction
//----------------------------------------------------------------//
//  KnockbackForce: The force at which units are hit by the       //
//  cleave (only relevent to knockback and not damage)            //
function MC_KnockbackForce takes real level returns real
    return 50 + (10 * level)
endfunction
//----------------------------------------------------------------//
//  KnockbackCleaveAngle: This is the angle taken from straight   //
//  forward that units are knocked back in (positive values       //
//  lead to the unit getting pushed in the direction of the       //
//  cleaver)                                                      //
constant function MC_KnockbackCleaveAngle takes nothing returns real
    return  bj_PI / 3
endfunction
//----------------------------------------------------------------//
//  PitchCalcVal: The hit height of the cleaver on target units   //
//  (used to work out their angle when launched, higher values    //
//  result in more steep arcs but may need more KnockbackForce    //
//  to be effective)                                              //
constant function MC_PitchCalcVal takes nothing returns real
    return 200.
endfunction
//----------------------------------------------------------------//
//  CleaveHitEffect: The effect created when the cleaver hits     //
//  a unit successfully                                           //
constant function MC_CleaveHitEffect takes nothing returns string
    return "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
endfunction
//----------------------------------------------------------------//
//  CleaveHitScale: The size of the effect created when the       //
//  cleave hits a unit successfully (1 = 100% model size)         //
constant function MC_CleaveHitScale takes real level returns real
    return 1 + (0.2 * level)
endfunction
//----------------------------------------------------------------//
//  FilterMaxZ: The Highest fly height a unit can have while      //
//  still being considered a valid target                         //
constant function MC_FilterMaxZ takes nothing returns real
    return 0.01
endfunction
//----------------------------------------------------------------//
//  CleaveAngleLet: Added to angles to compensate for floating    //
//  point arithmetic errors (read-only)                           //
constant function MC_CleaveAngleLet takes nothing returns real
    return 0.01
endfunction
//----------------------------------------------------------------//
//  AngleCorrection: Used to convert negative angles into         //
//  positive ones (read-only)                                     //
constant function MC_AngleCorrection takes nothing returns real
    return bj_PI * 2
endfunction
//----------------------------------------------------------------//
//                      END OF CONFIGURATION                      //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
//  Target filter function used to differentiate between units    //
//  that can be hit by the spell and those that cannot            //
////////////////////////////////////////////////////////////////////
function MC_TargetFilter takes unit u, player pl returns boolean
    return (not IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (GetUnitFlyHeight(u) <= MC_FilterMaxZ()) and (not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) and (IsUnitEnemy(u, pl)) and (GetUnitTypeId(u) != MC_DummyID()) and not(IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0)
endfunction

////////////////////////////////////////////////////////////////////
//  Check cleave function used ot prevent two channels being done //
//  by the same unit at the same time                             //
////////////////////////////////////////////////////////////////////
function MC_CheckCleave takes unit u returns nothing
    local integer Node = udg_MC_NextNode[0]
   
    loop
        exitwhen (Node == 0) or (udg_MC_Unit[Node] == u)
        set Node = udg_MC_NextNode[Node]
    endloop
   
    set udg_MC_Delay[Node] = 0.
    set udg_MC_Angle[Node] = udg_MC_AngleLimit[Node]
endfunction

////////////////////////////////////////////////////////////////////
//  AbsAngle function used to convert negative angles (rads) into //
//  positive angles (rads), standardises angles so formulas can   //
//  be used effectively                                           //
////////////////////////////////////////////////////////////////////
function MC_AbsAngle takes real angle returns real
    if angle < 0. then
        return angle + MC_AngleCorrection()
    else
        return angle
    endif
endfunction
////////////////////////////////////////////////////////////////////
//  Validate Angle function used to check if a given unit is      //
//  within the boundaries of the current cleave segment           //
////////////////////////////////////////////////////////////////////
function MC_ValidateAngle takes real boundary, real boundary2, real angle returns boolean

    //Check what direction the cleave is going in
    //And then check if the angle is within the two boundaries
    if MC_Clockwise() then
   
        if boundary <= 0 and angle < boundary2 then
            set angle = angle - MC_AngleCorrection()
        endif
        return (boundary - angle >= -MC_CleaveAngleLet() and boundary2 - angle <= MC_CleaveAngleLet())
    else
   
        if boundary2 >=  MC_AngleCorrection() and angle < boundary then
            set angle = angle + MC_AngleCorrection()
        endif
        return (boundary2 - angle >= -MC_CleaveAngleLet() and boundary - angle <= MC_CleaveAngleLet())
    endif
   
    return false
endfunction

////////////////////////////////////////////////////////////////////
//  Loop function used to control the cleave, damaging units      //
//  knocking them in the air and creating effects                 //
////////////////////////////////////////////////////////////////////
function MC_MassiveCleaveLoop takes nothing returns nothing
    //Set up Locals
    local integer Node = udg_MC_NextNode[0]
    local real angle
    local real angle2
    local real tempReal
    local real x
    local real y
    local real x2
    local real y2
    local real dy
    local real dx
    local boolean bool
    local unit u
   
    //Cycle through each node
    loop
        exitwhen Node == 0
       
        //Check if it's time to create another cleave point
        if udg_MC_Delay[Node] < MC_TimerSpeed() then
       
            //Check if the cleave is finished
            if (udg_MC_Angle[Node] >= (udg_MC_AngleLimit[Node] - MC_CleaveAngleLet()) and not(MC_Clockwise())) or ((udg_MC_Angle[Node] <= (udg_MC_AngleLimit[Node] + MC_CleaveAngleLet())) and MC_Clockwise()) then
                set udg_MC_RecycleNodes[udg_MC_RecyclableNodes] = Node
                set udg_MC_RecyclableNodes = udg_MC_RecyclableNodes + 1
                set udg_MC_NextNode[udg_MC_PrevNode[Node]] = udg_MC_NextNode[Node]
                set udg_MC_PrevNode[udg_MC_NextNode[Node]] = udg_MC_PrevNode[Node]
                       
                //Pause timer if this was the last instance
                if (udg_MC_PrevNode[0] == 0) then
                    call PauseTimer(udg_MC_Timer)
                endif
            else
           
                set x = GetUnitX(udg_MC_Unit[Node])
                set y = GetUnitY(udg_MC_Unit[Node])
                set bool = false
                set udg_MC_Delay[Node] = udg_MC_DelayReset[Node]
                set angle = udg_MC_Angle[Node] + udg_MC_Division[Node]

                //Find units to cleave
                call GroupEnumUnitsInRange(udg_MC_TempGroup, x, y, udg_MC_AOE[Node], null)
                loop
                    set u = FirstOfGroup(udg_MC_TempGroup)
                    exitwhen u == null
               
                    //Valid target type
                    if  MC_TargetFilter(u, udg_MC_Player[Node]) then
                        set x2 = GetUnitX(u)
                        set y2 = GetUnitY(u)
                        set dy = y2 - y
                        set dx = x2 - x
                        set angle2 = Atan2(dy, dx)

                        if angle2 < 0. then
                            set angle2 = angle2 + MC_AngleCorrection()
                        endif
                   
                        //Within the correct arc
                        if (MC_ValidateAngle(udg_MC_Angle[Node], angle, angle2)) then
                            set bool = true
                            //Damage unit and setup knockback data
                            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_MC_ManaDamage[Node])
                            call UnitDamageTarget(udg_MC_Unit[Node], u, udg_MC_HealthDamage[Node], true, false,  MC_AttackType(), MC_DamageType(), null)

                            //*********************************************
                            //Knockback (delete if not using BUS_Knockback)
                            if MC_Clockwise() then
                                set angle2 = angle2 - MC_KnockbackCleaveAngle()
                            else
                                set angle2 = angle2 + MC_KnockbackCleaveAngle()
                            endif

                            set tempReal = SquareRoot(dx * dx + dy * dy)

                            call BUS_StartKnockback(u, udg_MC_KnockbackForce[Node], x2 + tempReal * Cos(angle2), x2, y2 + tempReal * Sin(angle2), y2, 0., MC_PitchCalcVal())
                            //*********************************************
                        endif
                   
                    endif
                    call GroupRemoveUnit(udg_MC_TempGroup, u)
                endloop
           
                //Create blood effect if a unit was hit
                if bool then
                    //Find position
                    set angle2 = udg_MC_Angle[Node] + udg_MC_AngleAdjust[Node]
               
                    //Create effect
                    set u = CreateUnit(MC_DummyPlayer(), MC_DummyID(), x + udg_MC_EffectDistance[Node] * Cos(angle2), y + udg_MC_EffectDistance[Node] * Sin(angle2), angle2 * bj_RADTODEG)
                    call SetUnitScale(u, udg_MC_CleaveScale[Node], 0., 0.)
                    call DestroyEffect(AddSpecialEffectTarget(MC_CleaveHitEffect(), u, MC_AttachmentPoint()))
                    call UnitApplyTimedLife(u, 'BHwe', MC_Timer())
                    set u = null
                endif
           
                //Move Position
                set udg_MC_Angle[Node] = angle
            endif

        else
            set udg_MC_Delay[Node] = udg_MC_Delay[Node] - MC_TimerSpeed()
           
            if not(GetUnitCurrentOrder(udg_MC_Unit[Node]) == MC_OrderID()) then
                set udg_MC_Delay[Node] = 0.
                set udg_MC_Angle[Node] = udg_MC_AngleLimit[Node]
            endif
           
        endif
       
        set Node = udg_MC_NextNode[Node]
    endloop
   
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to start the channel process when the abiliyt   //
//  has been cast                                                 //
////////////////////////////////////////////////////////////////////
function MC_StartCleave takes nothing returns boolean
    //Set up locals
    local integer Node
    local real level
    local real offset
    local real facing
    local unit u
   
    //Start the channel
    if (GetSpellAbilityId() == MC_Ability()) then
        //Get unit and check for multiple channels
        set u = GetTriggerUnit()
        call MC_CheckCleave(u)
       
        //Set up Node
        if (udg_MC_RecyclableNodes == 0) then
            set udg_MC_NodeNumber = udg_MC_NodeNumber + 1
            set Node = udg_MC_NodeNumber
        else
            set udg_MC_RecyclableNodes = udg_MC_RecyclableNodes - 1
            set Node = udg_MC_RecycleNodes[udg_MC_RecyclableNodes]
        endif

        set udg_MC_NextNode[Node] = 0
        set udg_MC_NextNode[udg_MC_PrevNode[0]] = Node
        set udg_MC_PrevNode[Node] = udg_MC_PrevNode[0]
        set udg_MC_PrevNode[0] = Node
       
        //Start timer if this is the only instance
        if (udg_MC_PrevNode[Node] == 0) then
            call TimerStart(udg_MC_Timer, MC_TimerSpeed(), true, function MC_MassiveCleaveLoop)
        endif
       
        //Set up cleave data
        set udg_MC_Unit[Node] = u
        set udg_MC_Player[Node] = GetTriggerPlayer()
        set level = GetUnitAbilityLevel(udg_MC_Unit[Node], MC_Ability())
        set facing = GetUnitFacing(udg_MC_Unit[Node]) * bj_DEGTORAD
        set offset = MC_Angle(level)

        if MC_Clockwise() then
            set udg_MC_Division[Node] = offset / -MC_Divisions(level)
            set offset = offset / 2
            set udg_MC_AngleLimit[Node] = MC_AbsAngle(facing + offset)
            set udg_MC_Angle[Node] = udg_MC_AngleLimit[Node] - offset * 2
        else
            set udg_MC_Division[Node] = offset / MC_Divisions(level)
            set offset = offset / -2
            set udg_MC_Angle[Node] = MC_AbsAngle(facing + offset)
            set udg_MC_AngleLimit[Node] = udg_MC_Angle[Node] - offset * 2
        endif
       
        set udg_MC_AOE[Node] = MC_AOE(level)
        set udg_MC_EffectDistance[Node] = MC_EffectDistance(level)
        set udg_MC_AngleAdjust[Node] = (udg_MC_Division[Node] / 2)
        set udg_MC_HealthDamage[Node] = MC_HealthDamage(level)
        set udg_MC_ManaDamage[Node] = MC_ManaDamage(level)
        set udg_MC_Delay[Node] = MC_InitialDelay(level)
        set udg_MC_DelayReset[Node] = MC_DivisionDelay(level)
        set udg_MC_KnockbackForce[Node] = MC_KnockbackForce(level)
        set udg_MC_CleaveScale[Node] = MC_CleaveHitScale(level)
    endif

    return false
endfunction

////////////////////////////////////////////////////////////////////
//  Function used to register the trigger of the ability          //
////////////////////////////////////////////////////////////////////
function InitTrig_Massive_Cleave takes nothing returns nothing
    //Set up local variables
    local trigger t = CreateTrigger()

    //Set up trigger
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function MC_StartCleave))
   
endfunction
////////////////////////////////////////////////////////////////////
//END OF THE SPELL                                                //
////////////////////////////////////////////////////////////////////
 



Spell Information

- 478 lines of pure JASS
- 25 Configurables reaching all aspects of the ability
- Throw enemies miles
- Feel the power
- Cleft thy foes in twain
- Uses BUS Knockback systems to make the code significantly shorter
- Extensive Readme to help you configure the ability
- Doesn't interfere with game scorescreen
- Compatible with Vanilla WE
- Functions for ground and flying heroes (though I wouldn't suggest it for fliers generally)
- Arcs are stable on uneven terrain
- Features can be adapted to your liking due to the configuration including complete removal
- Attractive yet functional
- Makes your big monsters actually a bit more intimidating instead of oversized footmen
- Comes with omnipresent Mr. Fluffy and his entourage of Tanks

Tips and Tricks

- You don't really need this, a massive cleaver is pretty straight forward
- Aim to hit as many as possible
- Run if enemy has it

Helpful Files

- Variable Creator: Copy and paste into your map, you now have all the variables needed for the spell to run
- Comes with the variable creators for the relevant parts of the used systems
Variable Creator
  • Variable Creator
    • Events
    • Conditions
    • Actions
      • Set MC_AOE[0] = 0.00
      • Set MC_Angle[0] = 0.00
      • Set MC_AngleAdjust[0] = 0.00
      • Set MC_AngleLimit[0] = 0.00
      • Set MC_CleaveScale[0] = 0.00
      • Set MC_Delay[0] = 0.00
      • Set MC_DelayReset[0] = 0.00
      • Set MC_Division[0] = 0.00
      • Set MC_EffectDistance[0] = 0.00
      • Set MC_HealthDamage[0] = 0.00
      • Set MC_KnockbackForce[0] = 0.00
      • Set MC_ManaDamage[0] = 0.00
      • Set MC_NextNode[0] = 0
      • Set MC_NodeNumber = 0
      • Set MC_Player[0] = Player 1 (Red)
      • Set MC_RecyclableNodes = 0
      • Set MC_RecycleNodes[0] = 0
      • Set MC_TempGroup = MC_TempGroup
      • Set MC_Timer = MC_Timer
      • Set MC_Unit[0] = No unit



Images


Changelog

Show

-=null=-
- Added note for updated OrderID if used in 1.28
- Added a variable missing from the variable creator onto it
-=V1.01=-
- Added channel checking to prevent both multiple casts and allow interrupts to work properly
- Corrected "*****" border
- Loop slightly restructured to match channel checking
- Slight efficiency improvements
-=V1.00=-
- Initial Upload


[tr]

Keywords:
Cleave, Mash, AOE, Knockback, Cleft, Brain not necessary, Powertrip, intimidation, thy foe, who being naughty in My sight, shall snuff it.[/tr]
Contents

Massive Cleave V1.01 (Map)

Reviews
Moderator
4th Apr 2016 Your resource has been reviewed by BPower. In case of any questions or for reconfirming the moderator's rating, please make use of the Quick Reply function of this thread. Review: The cleaving effect works out perfectly with...
  1. 4th Apr 2016

    General Info

    Your resource has been reviewed by BPower.
    In case of any questions or for reconfirming the moderator's rating,
    please make use of the Quick Reply function of this thread.

    Review:

    The cleaving effect works out perfectly with the unit animation.
    I can imagine it beeing used for example as a boss / semi-boss ability.
    The knockback brings in an unpredictable apsect to any fight. Doubtless an amazing spell!

    Decent configuration options, great coding and documentation. I couldn't ask for more.
    Approved with a rating of 5/5, Highly Recommended.

    Troubleshooting:

    • Nothing

    Review changelog:
    1. -
     
  2. Tank-Commander

    Tank-Commander

    Spell Reviewer

    Joined:
    May 26, 2009
    Messages:
    1,547
    Resources:
    44
    Packs:
    1
    Spells:
    41
    Tutorials:
    2
    Resources:
    44
    Since I often make large things which don't get used too often in maps (probably due to their size) for my 40th Submission I've made something for you guys which is a bit more small & compact but still has a good pleasing effect to it for your big monsters
     
  3. [​IMG]

    Interesting and quite useful, great job, as always!
     
  4. Emm-A-

    Emm-A-

    Joined:
    Jul 1, 2008
    Messages:
    1,313
    Resources:
    0
    Resources:
    0
    Cool Spell, might be useful to include the possibility to show the thrown units death animation during the flight in my opinion ...
     
  5. Tank-Commander

    Tank-Commander

    Spell Reviewer

    Joined:
    May 26, 2009
    Messages:
    1,547
    Resources:
    44
    Packs:
    1
    Spells:
    41
    Tutorials:
    2
    Resources:
    44
    You mean forcing them to play the animation? I had considered it but there's select few models it works well with (footman, archer, units that fall backwards for example) but terribly on others (huntress, knight, units that fall forward & units that explode/other animation that makes no sense when knocked back) - it also wouldn't change anything if the stun option for BUS Knockback was set to false; hence why I chose not to in the end
     
  6. Emm-A-

    Emm-A-

    Joined:
    Jul 1, 2008
    Messages:
    1,313
    Resources:
    0
    Resources:
    0
    I meant exactly this.
    Hmm I understand.
    I thought about manually storing animation indices for each unit, but this would be a lot of work ... You're right, better leave it out then.
     
  7. mondragon

    mondragon

    Joined:
    Feb 22, 2015
    Messages:
    7
    Resources:
    0
    Resources:
    0
    GUI please, I don't understand jass
     
  8. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,443
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    You only need to understand english to use his resource.



    Definitely one of your more simple uploads. Great spell nonethless. The air movement and landing is really smooth, and I really like how short the code is.
     
  9. Ofel

    Ofel

    Joined:
    Mar 29, 2012
    Messages:
    406
    Resources:
    10
    Spells:
    10
    Resources:
    10
    Maybe using point target instead of instant since the caster facing angle can easily be annoyed.
     
  10. Rheiko

    Rheiko

    Joined:
    Aug 27, 2013
    Messages:
    2,942
    Resources:
    7
    Icons:
    2
    Spells:
    3
    Tutorials:
    2
    Resources:
    7
    Lmao, it did remind me to sauron and then this popped up when I scroll down.
     
  11. Tank-Commander

    Tank-Commander

    Spell Reviewer

    Joined:
    May 26, 2009
    Messages:
    1,547
    Resources:
    44
    Packs:
    1
    Spells:
    41
    Tutorials:
    2
    Resources:
    44
    As one of the advantages of basing the ability of channel - you can easily change the targeting method to any method of your choosing as a matter of preference without needing to make a new dummy ability
     
  12. Ofel

    Ofel

    Joined:
    Mar 29, 2012
    Messages:
    406
    Resources:
    10
    Spells:
    10
    Resources:
    10
    Hmm.. I see now
    Simple, and cool as always :)

    5/5
     
  13. apcrabnightlive

    apcrabnightlive

    Joined:
    Oct 7, 2014
    Messages:
    1,922
    Resources:
    1
    Maps:
    1
    Resources:
    1
    That keywords tho.

    Anyways it's a cool cleave you got there.
     
  14. Flux

    Flux

    Joined:
    Feb 6, 2014
    Messages:
    2,334
    Resources:
    28
    Maps:
    1
    Spells:
    19
    Tutorials:
    2
    JASS:
    6
    Resources:
    28
    This got approved so fast but I already checked it out so here are my thoughts
    Major:
    • I fail to see the purpose of MC_DivisionDelay, isn't configuring this the same as configuring the timeout?
    • This part
      Code (vJASS):

          if MC_Clockwise() then
              set angle2 = angle2 - MC_KnockbackCleaveAngle()
          else
              set angle2 = angle2 + MC_KnockbackCleaveAngle()
          endif
         
          set tempReal = Pow(dx * dx + dy * dy, 0.5)
          set x = x2 + tempReal * Cos(angle2)
          set y = y2 + tempReal * Sin(angle2)
       

      should be included in the things to be deleted when not using the Knockback.
    Minor:
    • SquareRoot
      is faster than
      Pow(base, 0.5)
      according to the Math Library by lfh.
    • R2I
      in
      real level
      is unnecessary.
    • local integer Node = 0
      should not be initialized, the next code execution after the locals declaration will literally overwrite integer Node anyway. Or you could make it
      local integer Node = udg_MC_NextNode[Node]
      and then move
      set Node = udg_MC_NextNode[Node]
      before
      endloop
    Suggestion:
    • You could use
      GetUnitX, GetUnitY
      (periodically) on the caster instead of storing the casting location because currently, it will cleave units in the casting position so if the caster is instantly moved by some other spell which involve moving while in the middle of the cleave, the cleaving will continue from the casting position instead from the caster's current location.
    • Also, you could make the Node instance immediately end when the caster stops channeling the cleave. Because if the caster is stunned while in the middle of the cleave, the cleaving still continues.
     
  15. BPower

    BPower

    Joined:
    Mar 18, 2012
    Messages:
    1,745
    Resources:
    21
    Spells:
    15
    Tutorials:
    1
    JASS:
    5
    Resources:
    21
    Hats off! These are aspects I didn't consider.
    I definitly agree on storing the casters location and the current order comparison.

    As these are non critical issues I suggest we leave the resource status approved.
    I guess you'll update as soon as you find the time for it.
     
  16. Empirean

    Empirean

    Joined:
    Jun 20, 2014
    Messages:
    385
    Resources:
    8
    Spells:
    8
    Resources:
    8
    this is awesome! you can start a tennis map with this resource
     
  17. Tank-Commander

    Tank-Commander

    Spell Reviewer

    Joined:
    May 26, 2009
    Messages:
    1,547
    Resources:
    44
    Packs:
    1
    Spells:
    41
    Tutorials:
    2
    Resources:
    44
    Major:
    It's a bit different - it's easier to notice if the division delay is high but essentially it times the difference between each hit in the cleave - obviously if the value is lower than the timerspeed then it results in a delay the same as the timeout but if greater results in a Ceiling(Delay / TimerSpeed) gap between each part of the cleave (works well with units with slow animations)

    - I'll update the markers to include the other parts, won't take long

    Minor:
    - I'll change Pow() to SquareRoot then
    - I don't recall any part of the code using R2I?
    - I'm not sure if that's the case, I have experience of the linked list failing if Node is not initialised to 0 (though initialising it NextNode[0] and moving the iteration line would work perfectly well)

    Suggestions:
    - I can see the use of it, would be a matter of weighing realistic speed of the cleave vs the likelyhood of moving and the efficiency of getting those values periodically (it may also require the introduction of more local variables given that it's a value used pretty often) I'll look into it
    - I'll add the option to end the instance when the channel ends, it'll be pretty fast to implement
     
  18. Flux

    Flux

    Joined:
    Feb 6, 2014
    Messages:
    2,334
    Resources:
    28
    Maps:
    1
    Spells:
    19
    Tutorials:
    2
    JASS:
    6
    Resources:
    28
    Oh, that was suppose to be I2R(). But it's very minor and hardly make a difference. Because JASS automatically type cast integers to reals so having it is redundant.

    About MC_Division, ok, it's like a configurable Timeout but can be configured to fill in per level instead of a constant value.
     
  19. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,889
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    Probably your shortest code ;)

    Pretty cool spell, Love it. Your spells are a nice addition to the spell section.