• 🏆 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!

[GUI] Spell

Status
Not open for further replies.
Level 6
Joined
Jan 8, 2010
Messages
155
This is my first spell as well as first thread here :p Please excuse any indecencies I may commit ^^

Chaos Laser: Opens a portal over the course of 2 seconds, which unleashes a devastating laser that scars the land, as well as those in it's vicinity.

As this is my first spell, I'm having issues making it MUI. I understand that I've got leaks and such, and I intend on fixing those later, but the main issue is that the spell does not work.

If I cast the spell 3 times simultaneously, it breaks and will not deal damage. The effect still works, but no damage is dealt (neither DOT or instant). I am having issues identifying which parts are non-MUI, and would like some professional help :)

PS. I didn't know that 'Point with polar opposite' was an option :p So I used cosine and sine to recreate it unknowingly xD

  • Chaos Laser
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chaos Laser
    • Actions
      • -------- Config --------
      • -------- Pretend that there is config here. I removed it to save space --------
      • -------- ---------------------------- --------
      • -------- Trigger starts here --------
      • -------- ---------------------------- --------
      • Set chaosMaxIndex = (chaosMaxIndex + 1)
      • Set comboUnit[chaosMaxIndex] = (Casting unit)
      • Set comboTarget[chaosMaxIndex] = (Target unit of ability being cast)
      • -------- Is it targeting a unit or the ground? --------
      • If ((Unit-type of comboTarget[chaosMaxIndex]) Not equal to No unit-type) then do (Set castPoint[chaosMaxIndex] = (Position of comboTarget[chaosMaxIndex])) else do (Set castPoint[chaosMaxIndex] = (Target point of ability being cast))
      • Set tempPoint[chaosMaxIndex] = (Point(((X of castPoint[chaosMaxIndex]) + (600.00 x (Cos((180.00 + (Facing of comboUnit[chaosMaxIndex])))))), ((Y of castPoint[chaosMaxIndex]) + (600.00 x (Sin((180.00 + (Facing of comboUnit[chaosMaxIndex]))))))))
      • -------- !! DO THIS AT THE END !! --------
      • Unit Group - Remove all units from chaosDmgGroup[chaosMaxIndex]
      • If (chaosStun Equal to True) then do (Unit - Pause comboTarget[chaosMaxIndex]) else do (Do nothing)
      • Unit - Create 1 chaosDummy for (Owner of comboUnit[chaosMaxIndex]) at tempPoint[chaosMaxIndex] facing (Facing of comboUnit[chaosMaxIndex]) degrees
      • Unit Group - Add (Last created unit) to tempGroup[chaosMaxIndex]
      • -------- Effects --------
      • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 100.00%, 0.00%) with 0.00% transparency
      • Animation - Change (Last created unit)'s animation speed to 300.00% of its original speed
      • Animation - Play (Last created unit)'s birth animation
      • Trigger - Turn on loop <gen>
  • loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer chaosCurrentIndex) from 1 to chaosMaxIndex, do (Actions)
        • Loop - Actions
          • -------- Effects --------
          • Set timeKeeper[chaosCurrentIndex] = (timeKeeper[chaosCurrentIndex] + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • timeKeeper[chaosCurrentIndex] Equal to 67
            • Then - Actions
              • Unit - Create 1 laserDummy for (Owner of comboUnit[chaosCurrentIndex]) at tempPoint[chaosCurrentIndex] facing (Facing of comboUnit[chaosCurrentIndex]) degrees
              • Unit Group - Add (Last created unit) to tempGroup[chaosCurrentIndex]
              • Animation - Change (Last created unit)'s size to (150.00%, 0.00%, 0.00%) of its original size
              • For each (Integer A) from 1 to 10, do (Actions)
                • Loop - Actions
                  • Unit - Create 1 laserDummy for (Owner of comboUnit[chaosCurrentIndex]) at tempPoint[chaosCurrentIndex] facing (Facing of comboUnit[chaosCurrentIndex]) degrees
                  • Unit Group - Add (Last created unit) to tempGroup[chaosCurrentIndex]
                  • Animation - Change (Last created unit)'s size to (75.00%, 0.00%, 0.00%) of its original size
              • -------- Pick units and deal damage --------
              • For each (Integer A) from 1 to 100, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • chaosLaserDamage[(Integer A)] Not equal to 0.00
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • And - All (Conditions) are true
                            • Conditions
                              • (Level of Chaos Laser for comboUnit[chaosCurrentIndex]) Equal to (Integer A)
                              • FriendlyFire Equal to False
                        • Then - Actions
                          • Unit Group - Add all units of (Units within 50.00 of castPoint[chaosCurrentIndex] matching (((Matching unit) belongs to an ally of (Owner of comboUnit[chaosCurrentIndex])) Not equal to True)) to chaosDmgGroup[chaosCurrentIndex]
                          • Custom script: exitwhen true
                        • Else - Actions
                          • Unit Group - Add all units of (Units within 50.00 of castPoint[chaosCurrentIndex]) to chaosDmgGroup[chaosCurrentIndex]
                      • Unit Group - Pick every unit in chaosDmgGroup[chaosCurrentIndex] and do (Actions)
                        • Loop - Actions
                          • Unit - Cause comboUnit[chaosCurrentIndex] to damage (Picked unit), dealing chaosLaserDamage[(Integer A)] damage of attack type Spells and damage type Magic
                    • Else - Actions
                      • Custom script: exitwhen true
              • Unit - Unpause comboTarget[chaosCurrentIndex]
              • -------- More effects --------
              • For each (Integer A) from 1 to 3, do (Actions)
                • Loop - Actions
                  • Special Effect - Create a special effect at castPoint[chaosMaxIndex] using Abilities\Spells\Human\FlameStrike\FlameStrike1.mdl
                  • Set tempSpecEffGroup[(Integer A)] = (Last created special effect)
              • Trigger - Turn on Chaos Laser DOT <gen>
              • -------- Setup the next index --------
              • Set timeKeeper[chaosCurrentIndex] = 0
              • Set comboUnit[chaosCurrentIndex] = comboUnit[chaosMaxIndex]
              • Set comboTarget[chaosCurrentIndex] = comboTarget[chaosMaxIndex]
              • Set castPoint[chaosCurrentIndex] = castPoint[chaosMaxIndex]
              • Set tempPoint[chaosCurrentIndex] = tempPoint[chaosMaxIndex]
              • Set chaosDmgGroup[chaosCurrentIndex] = chaosDmgGroup[chaosMaxIndex]
              • Set tempGroup[chaosCurrentIndex] = tempGroup[chaosMaxIndex]
              • Set timeKeeper[chaosCurrentIndex] = timeKeeper[chaosMaxIndex]
              • Set chaosMaxIndex = (chaosMaxIndex - 1)
              • Set chaosCurrentIndex = (chaosCurrentIndex - 1)
              • -------- Turn off the periodic event if unneeded --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • chaosMaxIndex Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
  • Chaos Laser DOT
    • Events
      • Time - Every 0.25 seconds of game time
    • Conditions
    • Actions
      • Set chaosCounter[chaosCurrentIndex] = (chaosCounter[chaosCurrentIndex] + 1)
      • Unit Group - Remove all units from chaosDmgGroup[chaosCurrentIndex]
      • -------- Pick units and deal damage --------
      • For each (Integer A) from 1 to 100, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • chaosLaserDPT[(Integer A)] Not equal to 0.00
            • Then - Actions
              • -------- If the ability level has a damage value --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • And - All (Conditions) are true
                    • Conditions
                      • (Level of Chaos Laser for comboUnit[chaosCurrentIndex]) Equal to (Integer A)
                      • FriendlyFire Equal to False
                • Then - Actions
                  • Unit Group - Add all units of (Units within chaosRange[(Integer A)] of castPoint[chaosCurrentIndex] matching (((Matching unit) belongs to an ally of (Owner of comboUnit[chaosCurrentIndex])) Not equal to True)) to chaosDmgGroup[chaosCurrentIndex]
                  • -------- Break --------
                  • Custom script: exitwhen true
                • Else - Actions
                  • Unit Group - Add all units of (Units within chaosRange[(Integer A)] of castPoint[chaosCurrentIndex]) to chaosDmgGroup[chaosCurrentIndex]
              • -------- Deal Damage to units that match --------
              • Unit Group - Pick every unit in chaosDmgGroup[chaosCurrentIndex] and do (Actions)
                • Loop - Actions
                  • Unit - Cause comboUnit[chaosCurrentIndex] to damage (Picked unit), dealing chaosLaserDPT[(Integer A)] damage of attack type Spells and damage type Magic
            • Else - Actions
              • -------- Break --------
              • Custom script: exitwhen true
      • -------- Cleanup & Reset after delay --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • chaosCounter[chaosCurrentIndex] Equal to 12
        • Then - Actions
          • -------- !! FIX AND REMOVE OTHER LEAKS !! --------
          • Unit Group - Pick every unit in tempGroup[chaosCurrentIndex] and do (Unit - Explode (Picked unit))
          • For each (Integer A) from 1 to 3, do (Actions)
            • Loop - Actions
              • Special Effect - Destroy tempSpecEffGroup[(Integer A)]
          • Set chaosCounter[chaosCurrentIndex] = 0
          • -------- If all instances are finished, stop trigger --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • chaosMaxIndex Equal to 0
            • Then - Actions
              • Trigger - Turn off (This trigger)
            • Else - Actions
        • Else - Actions
 

Attachments

  • chaoslaser.w3x
    31.6 KB · Views: 88
Last edited:

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
This is pretty good if it is your first spell. Now, I hate your kind of indexing so I am not able to help you. However I can give you a few tips to improve the trigger.

1. casting unit > triggering unit
2. there should be some kind of condition for turning loop on. I guess if index = 0 or something, I don't know how it works with indexing. Loop should not be "Initally On" uncheck that box.
vryqvm.gif
3. you're using way too big loops. It will cause lag if you put it in a big map with a lot of triggers. There should be a way to make them smaller. For example make the dummy units bigger but use less of them.
4. using pause unit is bad, there are a few issues that makes it buggy. If a paused unit dies it looks fucked up for example. You better find a workaround, like using a dummy version of stormbolt.
5. instead of using
JASS:
if 1 == true
    if 2 == true
        if 3 == true

use

JASS:
if 1 == true and 2 == true and 3 == true

trust me, it makes the code way easier to read.
 
Level 6
Joined
Jan 8, 2010
Messages
155
Haven't had a lot of free time recently to work on it, but when I do:

1. I'm sorry, I don't understand what you mean on #1

2. Yup! It is initially off, and turns on at the end of Chaos laser

3. I use a system which should end the loops early when they are no longer needed. Ie. if there is no damage for a certain level of a spell, it skips all spells afterwards by breaking the loop :) That should fix the lag right?

4. Tbh, I had no idea on what to do for the stun :p

5. Thanks for the recommendation :) It will be implemented!

+Rep sir :D

EDIT: Oooh for the loop you mean the one that times the 2 seconds out... Right.. I've been having trouble making the spell MUI, as stated. I've followed a guide partially, but it turned out pretty messy (the indexing system) as you can tell. Basically I read that MUI spells use loops that use the periodic event of 0.03, and instinctively thought to just take my timing and divide it by the 0.03. Is there a better way of doing this and can you give me an example? :p Thanks if you can and no biggie if you dont, you've helped a lot already haha.

Also how would you recommend making the spell MUI if not for indexing? I'm not set in my ways yet, so I'm open to changing ^.^
 
Last edited:
Level 6
Joined
Jan 8, 2010
Messages
155
1. Aha. I guess for whatever reason I thought that casting unit would be quicker.
2. What does the editor do if the trigger is already on? It doesn't restart it, but it takes from performance? Interesting... and unfortunate :(

Also, I planned on making the stun of variable length. Using pause unit (which has been working fine, but possibly wouldnt in another environment?) I could change the length of the stun. If I used a dummy spell, how might I make it of variable length?
 
Level 6
Joined
Jan 8, 2010
Messages
155
Yo, it's pretty nice...
Thanks but it could be a whole lot nicer if it was MUI :p I dont need it to be for my map per-say, but kind of want to submit it :)

Anyone got any ideas on how to do just that? Make it MUI that is? I realize that the indexing system is super messy and at some point has an issue. In the map attached to the main post, there is a sample. When hitting escape, 3 units simultaneously cast the spell, which ultimately breaks it - making all following casts deal 0 damage :(
 
Level 6
Joined
Jan 8, 2010
Messages
155
Quick question: Are functions executed immediately if they do not have delays? Ie. if I turn function B on in function A, and later in function A change a variable that is used in function B, will B use the old value or new value of the variable?

^ That is way more complicated sounding than I intend, so if you don't understand what I'm asking it's fine haha
 
Functions are executed immediately.

Let's say you have some code:
JASS:
function A takes nothing returns nothing
    set SomeValue = 5 // sets SomeValue to 5
    call B() // calls function B
    call BJDebugMsg(I2S(SomeValue)) // prints out the value of SomeValue
endfunction
And somewhere above that function, you have function B:
JASS:
function B takes nothing returns nothing
    set SomeValue = 20
endfunction
SomeValue will end up being printed out as 20. Why? When A is called, it first sets the value of SomeValue to 5. Then it calls B and executes all the lines of code in B. So SomeValue is set to 20. After that is done, it returns back to A and executes the BJDebugMsg code, which prints out the value of the variable.

In GUI you don't really use functions much. But there are still areas where this can become a big issue. For example, let's say you have this code:
  • Trigger 1
    • Events
      • Unit - A unit starts the effect of an ability
    • Conditions
    • Actions
      • Set Value = 100
      • Unit - Cause Footman 001 <gen> to damage Footman 001 <gen>, dealing 200.0 damage of attack type Spells and damage type Normal
      • Game - Display String(Value) to (All players) for 60.00 seconds
  • Damage Event
    • Events
      • Unit - Footman 001 <gen> is damaged
    • Conditions
    • Actions
      • Set Value = 500
What do you think the game message will display? Will it display 100 or 500? It turns out that it will display 500. The "Unit - Cause ... to damage.." function fires the damage event, which executes completely before Trigger 1 moves on to the next function. These bugs are very difficult to find, which is why we tend to use unique variables for each trigger and for each loop.
 
Level 6
Joined
Jan 8, 2010
Messages
155
It seems in the example below that it ALWAYS kills the peasant and never the caster, is this always true? Does it have to do with the 0.03 delay or the fact that it's not calling the function but rather running it side by side? Is this a sign that I need to move into jass? It's intimidating!!:eekani:

  • trigger 1
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Set tempUnit = (Triggering unit)
      • Trigger - Turn on trigger 2 <gen>
      • Set tempUnit = Peasant 0004 <gen>
  • trigger 2
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit - Kill tempUnit
      • Trigger - Turn off (This trigger)
Note: Trigger #2 is off initally.
 
Trigger is run below 0.01 timeframe, I recall 1 second = 10^5 executions, which means 0.01 = 10^3. I'm sure I highly wrong here though.

You need to execute the function instantly, not turning it on (use Run Trigger). This will change the execution to this order :
Temp Unit = Caster
Kill Caster
Temp Unit = Peasant
 
Level 6
Joined
Jan 8, 2010
Messages
155
Aha, so calling Run Trigger is basically the same as calling it as a function? As in it will finish executing the code after the trigger has been run at least?

That's good to know, but unfortunately - in my case - I have to turn it on as it runs multiple times (periodic event cycling through the different iterations of the spell) :( Hmm hmm..

Tbh I've kinda given up on this project :p Would like the issue to be solved, but the spell already works for my use of it. But as it stands, it's not MUI (though very close) so I guess I wont be uploading it *cry*
 
Status
Not open for further replies.
Top