• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Cutting Edge v2.1

  • Like
Reactions: Oljin and Dragoncy
Level 1: Saithis charges her crescent blade with magical powers then releases it creating a magical blade that drives forwards to the target point. Damages enemy units in it's wake by 100 and make them bleeding that damages them by 10 hit points per seconds.
Level 2: Saithis charges her crescent blade with magical powers then releases it creating a magical blade that drives forwards to the target point. Damages enemy units in it's wake by 150 and make them bleeding that damages them by 20 hit points per seconds.
Level 3: Saithis charges her crescent blade with magical powers then releases it creating a magical blade that drives forwards to the target point. Damages enemy units in it's wake by 200 and make them bleeding that damages them by 30 hit points per seconds.

  • Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Visibility - Disable fog of war
      • Visibility - Disable black mask
      • -------- Configureables on each level --------
      • -------- Level 1 --------
      • Set Damage[1] = 100.00
      • Set Distance[1] = 800.00
      • -------- Level 2 --------
      • Set Damage[2] = 150.00
      • Set Distance[2] = 900.00
      • -------- Level 3 --------
      • Set Damage[3] = 200.00
      • Set Distance[3] = 1000.00
  • Cutting Edge
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Cutting Edge
    • Actions
      • -------- The statement below is true. --------
      • -------- The statement above is false. --------
      • -------- ----------------------------------------------------------------------------- --------
      • -------- Index recycling part. Do not touch it! --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CEHas[CELastRecycled] Equal to True
        • Then - Actions
          • Set CEMax = (CEMax + 1)
          • Set CEIndex = CEMax
        • Else - Actions
          • Set CEIndex = CELastRecycled
          • Set CELastRecycled = CERecycledList[CELastRecycled]
      • -------- ----------------------------------------------------------------------------- --------
      • -------- Creating the effects and setting the variables. --------
      • Set CECaster[CEIndex] = (Triggering unit)
      • Set CETargetPoint[CEIndex] = (Target point of ability being cast)
      • Set CECasterPoint[CEIndex] = (Position of CECaster[CEIndex])
      • Set CEMaxDistance[CEIndex] = Distance[(Level of Cutting Edge for CECaster[CEIndex])]
      • Set CEDistance[CEIndex] = 0.00
      • Set CEDamage[CEIndex] = Damage[(Level of Cutting Edge for CECaster[CEIndex])]
      • Set CEHas[CEIndex] = True
      • -------- ----------------------------------------------------------------------------- --------
      • -------- The blast effect. --------
      • Set CETempPoint = (CECasterPoint[CEIndex] offset by 75.00 towards ((Angle from CETargetPoint[CEIndex] to CECasterPoint[CEIndex]) + 45.00) degrees)
      • Unit - Create 1 Effect for (Owner of CECaster[CEIndex]) at CETempPoint facing ((Angle from CECasterPoint[CEIndex] to CETargetPoint[CEIndex]) + 180.00) degrees
      • Animation - Change (Last created unit)'s animation speed to 150.00% of its original speed
      • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
      • -------- ----------------------------------------------------------------------------- --------
      • -------- The parts of the "blade". --------
      • Unit - Create 1 Edge1 for (Owner of CECaster[CEIndex]) at CECasterPoint[CEIndex] facing CETargetPoint[CEIndex]
      • Animation - Change (Last created unit)'s animation speed to 10.00% of its original speed
      • Unit Group - Add (Last created unit) to CEDummyGroup[CEIndex]
      • Unit - Create 1 Edge1R for (Owner of CECaster[CEIndex]) at CECasterPoint[CEIndex] facing CETargetPoint[CEIndex]
      • Animation - Change (Last created unit)'s animation speed to 10.00% of its original speed
      • Unit Group - Add (Last created unit) to CEDummyGroup[CEIndex]
      • Unit - Create 1 Edge2 for (Owner of CECaster[CEIndex]) at CECasterPoint[CEIndex] facing CETargetPoint[CEIndex]
      • Unit Group - Add (Last created unit) to CEDummyGroup[CEIndex]
      • Unit - Create 1 Edge2R for (Owner of CECaster[CEIndex]) at CECasterPoint[CEIndex] facing CETargetPoint[CEIndex]
      • Unit Group - Add (Last created unit) to CEDummyGroup[CEIndex]
      • Custom script: call RemoveLocation (udg_CETempPoint)
      • Set CECount = (CECount + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Cutting Edge Loop <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Cutting Edge Loop <gen>
        • Else - Actions
  • Cutting Edge Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer CEInteger) from 0 to CEMax, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • CEHas[CEInteger] Equal to True
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • CEDistance[CEInteger] Less than CEMaxDistance[CEInteger]
                • Then - Actions
                  • Set CEDistance[CEInteger] = (CEDistance[CEInteger] + 30.00)
                  • Set CETempPoint = (CECasterPoint[CEInteger] offset by CEDistance[CEInteger] towards (Angle from CECasterPoint[CEInteger] to CETargetPoint[CEInteger]) degrees)
                  • Unit Group - Pick every unit in CEDummyGroup[CEInteger] and do (Unit - Move (Picked unit) instantly to CETempPoint)
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Units within 100.00 of CETempPoint matching ((((Matching unit) belongs to an enemy of (Owner of CECaster[CEInteger])) Equal to True) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) and do (Actions)
                    • Loop - Actions
                      • Unit Group - Add (Picked unit) to CEDebuffGroup[CEInteger]
                      • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Other\Stampede\StampedeMissileDeath.mdl
                      • Special Effect - Destroy (Last created special effect)
                      • Unit - Create 1 Dummy for (Owner of CECaster[CEInteger]) at CETempPoint facing Default building facing degrees
                      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
                      • Unit - Add Debuff to (Last created unit)
                      • Unit - Set level of Debuff for (Last created unit) to (Level of Cutting Edge for CECaster[CEInteger])
                      • Unit - Order (Last created unit) to Night Elf Warden - Shadow Strike (Picked unit)
                      • Unit - Cause CECaster[CEInteger] to damage (Picked unit), dealing CEDamage[CEInteger] damage of attack type Spells and damage type Normal
                  • Custom script: call RemoveLocation (udg_CETempPoint)
                • Else - Actions
                  • -------- ----------------------------------------------------------------------------- --------
                  • -------- Clearing leaks, removing dummies and turning off the spell. --------
                  • Unit Group - Pick every unit in CEDummyGroup[CEInteger] and do (Unit - Remove (Picked unit) from the game)
                  • Unit Group - Remove all units from CEDebuffGroup[CEInteger]
                  • Unit Group - Remove all units from CEDummyGroup[CEInteger]
                  • Custom script: call RemoveLocation (udg_CECasterPoint[udg_CEInteger])
                  • Custom script: call RemoveLocation (udg_CETargetPoint[udg_CEInteger])
                  • Set CECount = (CECount - 1)
                  • Set CEHas[CEInteger] = False
            • Else - Actions
              • Set CERecycledList[CEInteger] = CELastRecycled
              • Set CELastRecycled = CEInteger
              • -------- ----------------------------------------------------------------------------- --------
              • -------- Turn off when nobody uses the spell and reseting loop length. --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • CECount Equal to 0
                • Then - Actions
                  • Set CEMax = 0
                  • Set CERecycledList[CEInteger] = 0
                  • Set CELastRecycled = 0
                  • Trigger - Turn off (This trigger)
                • Else - Actions
v2.0->v2.1
fixed system bug
v1.9->v2.0
added little documentation
added an extra recycling part
icreased the size of 2 of the group variables
removed group creating part
v1.8->v1.9
changes made
improved index system
v1.7->v1.8
added little documentation
easier configure for begginers
modified the code a bit
v1.6->v1.7
new index recycling system
now damage is triggered
v1.5->v1.6
fixed the bug that makes the spell non-MUI
v1.4->v1.5
fixed the bug that stops the ability if it got firstly casted
v1.3->v1.4
minor changes made
made it faster
reduced lagg
added extra effect
v1.2->v1.3
added extra dummies that made the spell looking better so:
5fitlw.jpg

v1.1->v1.2
fixed little things
v1.0->v1.1
fixed things
changed debuff
added extra condition to prevent multicasting the debuff


Keywords:
strike, slash, spell, target, dark, cut, kill, assassinate, magical, magic, blade,
Contents

Just another Warcraft III map (Map)

Reviews
Bribe: I'm not sure why you initialize these two groups as you just overwrite them later (memory leaks): Custom script: set udg_CEDummyGroup[udg_CEIndex] = CreateGroup() Custom script: set udg_CEDebuffGroup[udg_CEIndex] = CreateGroup()...

Moderator

M

Moderator

Bribe:

I'm not sure why you initialize these two groups as you just overwrite them later (memory leaks):

Custom script: set udg_CEDummyGroup[udg_CEIndex] = CreateGroup()
Custom script: set udg_CEDebuffGroup[udg_CEIndex] = CreateGroup()

The spell itself I found to be a bit underwhelming. This might have to do that a shadow-strike mixed with the crushing-wave effect you chose doesn't seem to fit. Stunning the units instead of critical striking them would have fit better.

Maker, v2.0, 14.07.2011
Approved, could be useful. A simple spell. You should add importing instructions.
 
Level 8
Joined
Jun 30, 2010
Messages
259
I can't test this due to my WE problem...
However, the triggering looks fine and leakless.
You are using a maximum of 100 casts at the same time, it should not exceed that limit, I guess.
The way you are applying the debuff is delayed, but that should not be a too big problem.
4/5, due to the late applying of the debuff, and that I don't think that an armor decreasing debuff fits this spell... Since it is based off the Warden, why not use a Shadow Strike debuff?
Vote for approval.
 
Level 5
Joined
Oct 24, 2007
Messages
90
Well done, Marsal2000. It's a pretty simple spell, in my opinion... However, the triggering is done efficiently, and the spell is leakless and MUI. It fits the Warden hero - especially with the bleed effects. Good work on the triggering part. Overall, I'll give it a 4/5 and vote for approval :thumbs_up:
 
Level 16
Joined
Jun 24, 2009
Messages
1,409
Ah thanks :grin:
I can't test this due to my WE problem...
However, the triggering looks fine and leakless.
You are using a maximum of 100 casts at the same time, it should not exceed that limit, I guess.
The way you are applying the debuff is delayed, but that should not be a too big problem.
4/5, due to the late applying of the debuff, and that I don't think that an armor decreasing debuff fits this spell... Since it is based off the Warden, why not use a Shadow Strike debuff?
Vote for approval.

The maximum can be increased to the maximum array size you just need to modify the CEMax integer value at the init. Dunno but the shadow strike could be good ~.~
How could I apply it without delay?
there's something disturbing me, the special effect still appear even if the enemy is spell immune.

Hmm I'll check this.
edit: Ah just a little missclick, instead of magic immune i've chosen the etheral.
 
Last edited:
Level 8
Joined
Jun 30, 2010
Messages
259
Ah thanks :grin:


The maximum can be increased to the maximum array size you just need to modify the CEMax integer value at the init. Dunno but the shadow strike could be good ~.~
How could I apply it without delay?


Hmm I'll check this.
edit: Ah just a little missclick, instead of magic immune i've chosen the etheral.

Well, as my Buff System so-called "spell" specifies, you can add items to the targeted units to instantly add buffs or debuffs.
This is not commercial for my spell, since I am highly considering making it a tutorial.
 
Level 9
Joined
Dec 3, 2010
Messages
162
  • Unit Group - Pick every unit in CETempGroup and do (Actions)
    • Loop - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Picked unit) is alive) Equal to True
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is Magic Immune) Equal to True
            • Then - Actions
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is in CEDebuffGroup[CEInteger]) Equal to True
                • Then - Actions
                • Else - Actions
                  • Unit Group - Add (Picked unit) to CEDebuffGroup[CEInteger]
                  • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Other\Stampede\StampedeMissileDeath.mdl
                  • Special Effect - Destroy (Last created special effect)
                  • Unit - Create 1 Dummy for (Owner of CECaster[CEInteger]) at CETempPoint facing Default building facing degrees
                  • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
                  • Unit - Add Debuff to (Last created unit)
                  • Unit - Set level of Debuff for (Last created unit) to (Level of Cutting Edge for CECaster[CEInteger])
                  • Unit - Order (Last created unit) to Night Elf Warden - Shadow Strike (Picked unit)
        • Else - Actions

This part. You can really just filter all the units when you set the unit group. Just to remove that massive If/Then/Else part. And it's better to filter the units when you set the group, rather looping through all the units in the group, then filtering them.

As for your periodic timer of 0.02 seconds, I think that's quite an overkill. I think using 0.03 or 0.04 seconds wouldn't make much of a difference, especially for human eyes.

And about this condition:

  • (CETempGroup2 is empty) Equal to True
From what I know, this function is pretty inefficient. What it does is that it loops through the unit group to find the number of units in a unit group. Instead of doing this, I suggest you manually use an integer variable to count the number of units.

Lastly, this is just an opinion, but wouldn't hashtables be more efficient in terms of MUI? Just an opinion though. Your method works just fine.

Anyways, pretty nice spell :)
 
Level 16
Joined
Jun 24, 2009
Messages
1,409
This part. You can really just filter all the units when you set the unit group. Just to remove that massive If/Then/Else part. And it's better to filter the units when you set the group, rather looping through all the units in the group, then filtering them.

As for your periodic timer of 0.02 seconds, I think that's quite an overkill. I think using 0.03 or 0.04 seconds wouldn't make much of a difference, especially for human eyes.


And about this condition:

  • (CETempGroup2 is empty) Equal to True
From what I know, this function is pretty inefficient. What it does is that it loops through the unit group to find the number of units in a unit group. Instead of doing this, I suggest you manually use an integer variable to count the number of units.

Lastly, this is just an opinion, but wouldn't hashtables be more efficient in terms of MUI? Just an opinion though. Your method works just fine.

Anyways, pretty nice spell :)

i've made this spell in a hurry so the trigger isn't the best but it's leakless and MUI so the main function is okay
at 0.05 it looks like you have looping mini lag


hmm... okay
I don't like hashtables, they are too complicated and slower than the indexing (as I know)
edit: oookay updated it
 
Level 9
Joined
Dec 3, 2010
Messages
162
i've made this spell in a hurry so the trigger isn't the best but it's leakless and MUI so the main function is okay
at 0.05 it looks like you have looping mini lag


hmm... okay
I don't like hashtables, they are too complicated and slower than the indexing (as I know)

True, hashtables may be slower. However, you won't need to needlessly loop 100 times per 0.02 seconds. Plus, Hashtables are basically 2D-Arrays, which is very efficient for storing lots of values. Though, you could imitate 2D-Arrays with global variables too.
 
Level 19
Joined
Feb 25, 2009
Messages
2,004
True, hashtables may be slower. However, you won't need to needlessly loop 100 times per 0.02 seconds. Plus, Hashtables are basically 2D-Arrays, which is very efficient for storing lots of values. Though, you could imitate 2D-Arrays with global variables too.

You wouldn't need to loop 100 times if you were using normal indexing system,
which loops through all created instances, instead through each of them,
which will also give the oppurtunity to use 8192 slots, instead of 100. Also, indexing allows you to use 2D arrays as well, you just need to know how.

On spell:

- Periodic should always be 0.03 to minimize lag from created/used objects

  • Set CECaster[CEIndex] = (Casting unit)
(Triggering Unit) is faster and more reliable

  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • CECount Equal to 0
  • Then - Actions
  • Trigger - Turn off (This trigger)
  • Else - Actions
Can be inside the loop to reduce length

I also don't agree with the fact that you have a limit over the possible instances, but thats all your decision to make. You might also want to change the "bleeding" spell to something else, because most maps uses shadow-strike already it will only cause it to overrite the buff.

3/5 Overall.
 
Level 8
Joined
Jun 30, 2010
Messages
259
You wouldn't need to loop 100 times if you were using normal indexing system,
which loops through all created instances, instead through each of them,
which will also give the oppurtunity to use 8192 slots, instead of 100. Also, indexing allows you to use 2D arrays as well, you just need to know how.

On spell:

- Periodic should always be 0.03 to minimize lag from created/used objects

  • Set CECaster[CEIndex] = (Casting unit)
(Triggering Unit) is faster and more reliable

  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • CECount Equal to 0
  • Then - Actions
  • Trigger - Turn off (This trigger)
  • Else - Actions
Can be inside the loop to reduce length

I also don't agree with the fact that you have a limit over the possible instances, but thats all your decision to make. You might also want to change the "bleeding" spell to something else, because most maps uses shadow-strike already it will only cause it to overrite the buff.

3/5 Overall.

You don't nesseccarily need to make it 0.03, just make sure it is 0.03 or Slower.
A limit is ok in my opinion, allthought I think that it should be around 300, this has a very small chance of being overridden and it is a fair ammount.
 
Level 16
Joined
Jun 24, 2009
Messages
1,409
You wouldn't need to loop 100 times if you were using normal indexing system,
which loops through all created instances, instead through each of them,
which will also give the oppurtunity to use 8192 slots, instead of 100. Also, indexing allows you to use 2D arrays as well, you just need to know how.

On spell:

- Periodic should always be 0.03 to minimize lag from created/used objects

  • Set CECaster[CEIndex] = (Casting unit)
(Triggering Unit) is faster and more reliable

  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • CECount Equal to 0
  • Then - Actions
  • Trigger - Turn off (This trigger)
  • Else - Actions
Can be inside the loop to reduce length

I also don't agree with the fact that you have a limit over the possible instances, but thats all your decision to make. You might also want to change the "bleeding" spell to something else, because most maps uses shadow-strike already it will only cause it to overrite the buff.

3/5 Overall.

I'm not a kind of a pro triggerer but, hey it works and leakless. You can change the ability whatever you want easily example: a cripple. The period and the maximum instances can be modified too... Easy to edit these things...
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Why do you loop through all indices in order to find one that has been recycled? You can simply do a singular-linked list to track instances valid for recycling:

  • -------- Add new index to be recycled --------
  • Set recycleList[CEInteger] = lastRecycled
  • Set lastRecycled = CEInteger
  • -------- Get a recycled index --------
  • Set CEInteger = lastRecycled
  • Set lastRecycled = recycleList[lastRecycled]
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
There are some things going on with the code that just don't make sense.

CEHas[CELastRecycled] Equal to True

I recommend just checking "CELastRecycled Equal to 0". It's more simple and avoids creating a recycle boolean array.

At that point you can also remove the part where you initialize the groups in your map initialization trigger.

If you used just one single dummy unit (with the dummy.mdx model) it would avoid creating four different units for each different special effect. You would then just attach the appropriate effects to the dummy units and destroy the effects when the dummy units died. With this change you could add configurables in your setup trigger which would allow users to very easily define what the spell should look like (and also avoid having to c & p 4 different dummy units just to make your spell work).

It took me a while to figure out what it is I was really uneasy about due to the unique way you coded this, but these attribute to why I haven't approved it yet.
 
Level 16
Joined
Jun 24, 2009
Messages
1,409
There are some things going on with the code that just don't make sense.

CEHas[CELastRecycled] Equal to True

I recommend just checking "CELastRecycled Equal to 0". It's more simple and avoids creating a recycle boolean array.


At that point you can also remove the part where you initialize the groups in your map initialization trigger.

If you used just one single dummy unit (with the dummy.mdx model) it would avoid creating four different units for each different special effect. You would then just attach the appropriate effects to the dummy units and destroy the effects when the dummy units died. With this change you could add configurables in your setup trigger which would allow users to very easily define what the spell should look like (and also avoid having to c & p 4 different dummy units just to make your spell work).

It took me a while to figure out what it is I was really uneasy about due to the unique way you coded this, but these attribute to why I haven't approved it yet.

That was the first I tried but it made the spell non-MUI.


Wut? o_O

The dummies have different sizes,colors and animation speed so I can't do that if I want to get the same effect.


It's really not that hard ~.~ If you want I can make a documentation that explains everything.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
The sizes, colors and animation speed can be adjusted with triggers, it will make the effects larger or smaller or different colors depending on the properties of the unit they are attached to.

Adding some comments to your triggers is definitely a step in the right direction.

That comparision to 0 thing I showed you would not break multi-unit-instanciability. That's the most common recycling trick and all the well-written vJass resources are using it (including the built-in vJass structs).

And what I was suggesting was to remove this:

  • For each (Integer A) from 1 to CEMax, do (Actions)
    • Loop - Actions
      • Custom script: set udg_CEDummyGroup[GetForLoopIndexA()] = CreateGroup()
      • Custom script: set udg_CEDebuffGroup[GetForLoopIndexA()] = CreateGroup()
Because it's really not needed when you include that indexing change I suggested.
 
Level 16
Joined
Jun 24, 2009
Messages
1,409
The sizes, colors and animation speed can be adjusted with triggers, it will make the effects larger or smaller or different colors depending on the properties of the unit they are attached to.

Adding some comments to your triggers is definitely a step in the right direction.

That comparision to 0 thing I showed you would not break multi-unit-instanciability. That's the most common recycling trick and all the well-written vJass resources are using it (including the built-in vJass structs).

And what I was suggesting was to remove this:

  • For each (Integer A) from 1 to CEMax, do (Actions)
    • Loop - Actions
      • Custom script: set udg_CEDummyGroup[GetForLoopIndexA()] = CreateGroup()
      • Custom script: set udg_CEDebuffGroup[GetForLoopIndexA()] = CreateGroup()
Because it's really not needed when you include that indexing change I suggested.

That's high for me. How can I add 4 effects, to only one unit, with different sizes, colors and rotation angle?

That CEHas[CELastRecycled] Equal to True part is increasing the maximum number of loops. When I used that CELastRecycled Equal to 0 thing, the trigger was able to overwrite an already running instance.

What indexing change?
 
Level 4
Joined
Mar 21, 2014
Messages
79
works ok, but not with fortress/strongholds - i could get stuck within the fortress if that last point was exactly in the middle of the fortress. So I combined it with CheckWalkability (creating an item at move position, basically) and with that it works better
 
Top