• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Spell] Multi-units casting spell

Status
Not open for further replies.
Level 3
Joined
Mar 15, 2015
Messages
53
I want to create a spell that summon a golem, when the hero cast spell, he cast the similar spell.
What i have done is:
-The spell that summon golem is Infernal
-The hero got Decay (base on Thunder Clap) and Limbo (base on Impale) so i've create the similar spells for the golem.
-I set variable for hero caster and summoned unit, then set a variable for duration to remove it:
  • Follow Infernal Caster
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Inferno (Keeper)
    • Actions
      • Set Caster_unit = (Casting unit)
      • Set Summoned_unit = (Last created unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IF_duration Equal to 0.00
        • Then - Actions
          • Trigger - Turn on Follow Infernal Caster 2 <gen>
        • Else - Actions
      • Set IF_duration = 110.00
  • Follow Infernal Caster 2
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
      • (Ability being cast) Equal to Inferno (Keeper)
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IF_duration Greater than 0.00
        • Then - Actions
          • Set IF_duration = (IF_duration - 0.30)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • IF_duration Less than or equal to 0.00
                  • (Caster_unit is alive) Equal to False
                  • (Summoned_unit is alive) Equal to False
            • Then - Actions
              • Set IF_duration = 0.00
              • Set Caster_unit = No unit
              • Set Summoned_unit = No unit
              • Trigger - Turn off (This trigger)
            • Else - Actions
        • Else - Actions
And thennn i got stuck XD DX. Can any one show me what to do next? i can only think so simple like...yeah it's not working :vw_unimpressed:
  • Follow Decay
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Decay
      • (Casting unit) Equal to Caster_unit
    • Actions
      • Unit - Order Summoned_unit to Human Mountain King - Thunder Clap
 
Level 26
Joined
Sep 26, 2009
Messages
2,416
Ok, this will require some rework.

The first trigger
When unit finishes casting an ability it does not necessarily mean that the golem has been summoned in that exact same time or earlier. That means that (Last Created Unit) may point at a completely different unit (or no unit at all).
I would change this - In the current trigger I would just leave the part where you set caster into variable. Then just make another trigger that checks when a unit enters playable map area and check if that is the golem unit. In this second trigger start the timer (the loop trigger).

Also, can the caster cast this spell again when the golem is still in game? (As in the golem's duration is 110 seconds, but spell's cooldown is for example just 60 seconds). If that is not the case (cooldown is longer than duration of the spell) you can remove the If/Then/Else block and simply set the duration to desired amount and turn loop trigger on.

So change it like this:
Old trigger:
  • Follow Infernal Caster
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Inferno (Keeper)
    • Actions
      • Set Caster_unit = (Casting unit)
      • Set Summoned_unit = (Last created unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IF_duration Equal to 0.00
        • Then - Actions
          • Trigger - Turn on Follow Infernal Caster 2 <gen>
        • Else - Actions
      • Set IF_duration = 110.00
New triggers:
  • Cast Spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Inferno (Keeper)
    • Actions
      • Set Caster_unit = (Triggering unit)
      • -------- //Golem will be definitely created later than when the caster STARTS the spell, so we turn the second trigger on --------
      • Trigger - Turn on Created Golem <gen>
Note: This second trigger is INITIALLY OFF.
  • Created Golem
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Golem
    • Actions
      • -------- //No need to make this trigger run the condition check when ANY unit enters map unless we await the golem --------
      • Trigger - Turn off (This trigger)
      • Set Summoned_unit = (Triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IF_Duration Less than or equal to 0.00
        • Then - Actions
          • Trigger - Turn on Loop <gen>
        • Else - Actions
      • Set IF_Duration = 110.00

Now to the second trigger
The condition "Ability being cast == *some ability*" Is a response to any cast event (begins/starts/finishes casting/channeling an ability). You have no such event there, so the condition always returns false.
Also, the outer-most If/Then/Else block (the first one) is completely unnecessary there, because you do the same check (and react to the check) in an indented If/Then/Else. So you can change your loop trigger into this:
  • Loop
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Set IF_Duration = (IF_Duration - 0.30)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • IF_Duration Less than or equal to 0.00
              • (Caster_unit is alive) Equal to False
              • (Summoned_unit is alive) Equal to False
        • Then - Actions
          • Trigger - Turn off (This trigger)
          • Set IF_Duration = 0.00
          • Set Caster_unit = No unit
          • Set Summoned_unit = No unit
        • Else - Actions
The third trigger
So if your golem is casting same types of spells as its owner, it can be like this:
  • Casting
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Triggering unit) Equal to Caster_unit
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Decay
          • (Ability being cast) Equal to Limbo
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Limbo
        • Then - Actions
          • -------- Casts impale --------
          • -------- Needs to save the targeted point into POINT variable to prevent memory leaks --------
          • Set loc = (Target point of ability being cast)
          • Unit - Order Summoned_unit to Undead Crypt Lord - Impale loc
          • Custom script: call RemoveLocation(udg_loc)
          • Custom script: set udg_loc = null
        • Else - Actions
          • -------- If the spell is not impale, then out of the two it logically must be Thunder Clap --------
          • Unit - Order Summoned_unit to Human Mountain King - Thunder Clap
 
Level 3
Joined
Mar 15, 2015
Messages
53
Ok, this will require some rework.

The first trigger
When unit finishes casting an ability it does not necessarily mean that the golem has been summoned in that exact same time or earlier. That means that (Last Created Unit) may point at a completely different unit (or no unit at all).
I would change this - In the current trigger I would just leave the part where you set caster into variable. Then just make another trigger that checks when a unit enters playable map area and check if that is the golem unit. In this second trigger start the timer (the loop trigger).

Also, can the caster cast this spell again when the golem is still in game? (As in the golem's duration is 110 seconds, but spell's cooldown is for example just 60 seconds). If that is not the case (cooldown is longer than duration of the spell) you can remove the If/Then/Else block and simply set the duration to desired amount and turn loop trigger on.

So change it like this:
Old trigger:
  • Follow Infernal Caster
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Inferno (Keeper)
    • Actions
      • Set Caster_unit = (Casting unit)
      • Set Summoned_unit = (Last created unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IF_duration Equal to 0.00
        • Then - Actions
          • Trigger - Turn on Follow Infernal Caster 2 <gen>
        • Else - Actions
      • Set IF_duration = 110.00
New triggers:
  • Cast Spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Inferno (Keeper)
    • Actions
      • Set Caster_unit = (Triggering unit)
      • -------- //Golem will be definitely created later than when the caster STARTS the spell, so we turn the second trigger on --------
      • Trigger - Turn on Created Golem <gen>
Note: This second trigger is INITIALLY OFF.
  • Created Golem
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Golem
    • Actions
      • -------- //No need to make this trigger run the condition check when ANY unit enters map unless we await the golem --------
      • Trigger - Turn off (This trigger)
      • Set Summoned_unit = (Triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IF_Duration Less than or equal to 0.00
        • Then - Actions
          • Trigger - Turn on Loop <gen>
        • Else - Actions
      • Set IF_Duration = 110.00

Now to the second trigger
The condition "Ability being cast == *some ability*" Is a response to any cast event (begins/starts/finishes casting/channeling an ability). You have no such event there, so the condition always returns false.
Also, the outer-most If/Then/Else block (the first one) is completely unnecessary there, because you do the same check (and react to the check) in an indented If/Then/Else. So you can change your loop trigger into this:
  • Loop
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Set IF_Duration = (IF_Duration - 0.30)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • IF_Duration Less than or equal to 0.00
              • (Caster_unit is alive) Equal to False
              • (Summoned_unit is alive) Equal to False
        • Then - Actions
          • Trigger - Turn off (This trigger)
          • Set IF_Duration = 0.00
          • Set Caster_unit = No unit
          • Set Summoned_unit = No unit
        • Else - Actions
The third trigger
So if your golem is casting same types of spells as its owner, it can be like this:
  • Casting
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Triggering unit) Equal to Caster_unit
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Decay
          • (Ability being cast) Equal to Limbo
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Limbo
        • Then - Actions
          • -------- Casts impale --------
          • -------- Needs to save the targeted point into POINT variable to prevent memory leaks --------
          • Set loc = (Target point of ability being cast)
          • Unit - Order Summoned_unit to Undead Crypt Lord - Impale loc
          • Custom script: call RemoveLocation(udg_loc)
          • Custom script: set udg_loc = null
        • Else - Actions
          • -------- If the spell is not impale, then out of the two it logically must be Thunder Clap --------
          • Unit - Order Summoned_unit to Human Mountain King - Thunder Clap

:eekani: oh my god thank you so much, MAGIC!!
Hmm the spell cooldown is 120 and i want each time the spell casted, the old golem dies and new one appear (prevent cooldown reset stuffs). So that mean i have to add Unit - Kill Summoned_unit on the first trigger?
And if i don't kill the 1st golem, when the hero cast spell do they both (1st and 2nd golem) cast spell?
 
Level 26
Joined
Sep 26, 2009
Messages
2,416
No, both will not cast spells - only the newest one will. The reason is because variables can hold only one data (= only one unit/integer/string/etc.).
In WCIII, variables are pointers (there are some exceptions to this) - that means they point at things in game. For example a unit variable points at unit.

Because variables can point at only one thing at a time, when you assign new unit into the variable, it will point only at that unit and will no longer point at any other unit it pointed at previously.
  • Set unit_var = Footman 0000 <gen> //Assigns Footman unit into unit_var variable
  • Unit - Change color of unit_var to Blue //Changes color of Footman unit
  • Set unit_var = Priest 0001 <gen> //Assigns Priest unit into unit_var variable
  • Unit - Change color of unit_var to Blue //Changes color of Priest unit only, this will no longer affect Footman unit


---
About golem death:
As I see it, your golem lasts for 110 seconds, but the spell's cooldown is 120 seconds. That means that the golem dies 10 seconds before your caster can use the spell again. Hence there is no need to kill the golem when the caster casts the spell again (because there's no golem at that time).

However you should kill the golem in the loop trigger, because what happens when IF_duration gets below 0.00? You just make variables point at nothing, but that does not mean the golem will die.
Also, what should happen if caster dies while the golem is active? I guess golem should die as well?


There is also another thing: How many units can cast this Inferno (Keeper) spell in your map? Can there be more than 1? Because then your spell will not work correctly.
 
Level 3
Joined
Mar 15, 2015
Messages
53
But if the ability cooldown reset? that will summon 2 golems.
I will only allow 1 unit can cast this spell, but can i check the summoned_unit owned by the caster owner player, so i can have the hero on both team? and because there are golem units on the map but not belong to the main (owner of the caster) player.
And i want when the caster die, the golem die too.
Brb, gotta go to sleep heheh
 
Level 3
Joined
Mar 15, 2015
Messages
53
A Little Changes:

Cast Spell
  • Cast Spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Inferno (Keeper)
    • Actions
      • Unit - Kill Summoned_unit
      • Set Summoned_unit = No unit
      • Set Caster_unit = (Triggering unit)
      • Trigger - Turn on Created Golem <gen>
Created Golem
  • Created Golem
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Infernal
      • (Owner of (Triggering unit)) Equal to (Owner of Caster_unit)
    • Actions
      • Set Summoned_unit = (Triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • IF_duration Less than or equal to 0.00
        • Then - Actions
          • Trigger - Turn on Looper <gen>
        • Else - Actions
      • Set IF_duration = 110.00
      • Trigger - Turn off (This trigger)
Loop
  • Looper
    • Events
      • Time - Every 0.30 seconds of game time
    • Conditions
    • Actions
      • Set IF_duration = (IF_duration - 0.30)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • IF_duration Less than or equal to 0.00
              • (Caster_unit is alive) Equal to False
              • (Summoned_unit is alive) Equal to False
        • Then - Actions
          • Set IF_duration = 0.00
          • Unit - Kill Summoned_unit
          • Set Caster_unit = No unit
          • Set Summoned_unit = No unit
          • Trigger - Turn off (This trigger)
        • Else - Actions
Everything works very well :p
Heyyy can i have 1 more question :grin: well what if i want the golem cast the spell on the same angle of the caster? sorry if i bother you :D i just got alittle bit curious :p
 
Level 9
Joined
Apr 23, 2011
Messages
527
set the position of the caster to a point, the facing of the caster to a real variable and use this action:
  • Unit - Order Summoned_unit to Undead Dreadlord - Inferno (caster_point offset by 25.00 facing caster_facing degrees)
change the spell order and offset real to whatever you want.
 
Level 26
Joined
Sep 26, 2009
Messages
2,416
Heyyy can i have 1 more question :grin: well what if i want the golem cast the spell on the same angle of the caster? sorry if i bother you :D i just got alittle bit curious :p

It is just like Light wrote, however keep in mind that you need to destroy locations else they cause memory leak (memory leaks slow down your game when too many pile up).

That means changing this:
  • Unit - Order Summoned_unit to Undead Dreadlord - Inferno (caster_point offset by 25.00 facing caster_facing degrees)
Into this:
  • Set loc = (caster_point offset by 25.00 facing caster_facing degrees)
  • Unit - Order Summoned_unit to Undead Dreadlord - Inferno loc
  • Custom script: call RemoveLocation(udg_loc)
loc is a POINT variable.
 
Level 15
Joined
Aug 14, 2007
Messages
936
OK FIRSTLY

TRIGGER1

Event = when a unit is summoned

Condition = Unit type is infernal

Action = set summonunit, set summoning unit

ANd the rest should be straight forward.

Problem with your every 0.3 second trigger, the condition will not take ability cast, that condition only works with event such as a unit cast an ability, straight forward eh?
 
Status
Not open for further replies.
Top