• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[Spell] Ranged attack with auto spell?

Set up both of the unit's attacks, with Attack 1 being the melee attack and Attack 2 being ranged. Then you just need two triggers to monitor for Autocast Turn On/Off orders, which then set the unit's weapon state. You can see and set the Autocast order strings in Object Editor (see screenshot).
screencap_orderstring.jpg

For setting unit weapon fields, Index 0 is Attack 1, Index 1 is Attack 2.
  • AttackTurnOn
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(flamingarrows))
    • Actions
      • Unit - Set Unit: (Triggering unit)'s Weapon Boolean Field: Attacks Enabled ('uaen')at Index:1 to Value: True
      • Unit - Set Unit: (Triggering unit)'s Weapon Boolean Field: Attacks Enabled ('uaen')at Index:0 to Value: False
  • AttackTurnOff
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(unflamingarrows))
    • Actions
      • Unit - Set Unit: (Triggering unit)'s Weapon Boolean Field: Attacks Enabled ('uaen')at Index:0 to Value: True
      • Unit - Set Unit: (Triggering unit)'s Weapon Boolean Field: Attacks Enabled ('uaen')at Index:1 to Value: False
Note that this works in the current live version (2.0.3) and I have confirmed it does NOT work in 1.31, as the new weapon field natives were not fully working yet in that version.

If you want to do this on an earlier game version and need an alternate method, you could silently replace the unit with a type that is identical except for its attack types.
  • ReplaceUnit
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(flamingarrows))
      • (Unit-type of (Triggering unit)) Equal to Footman
    • Actions
      • Unit - Replace (Triggering unit) with a Rifleman using The old unit's relative life and mana
      • Selection - Add (Last replaced unit) to selection for Player 1 (Red)
This will interrupt the unit's ongoing orders, which can theoretically be worked around by creating a system to monitor and remember targets of orders, but of course that's a large amount of added complexity. You could more easily turn the order interruption into a feature (like the unit has to stop what they're doing for a moment in order to prepare their ranged weapon.)
 
Thank you for the help and articulation of the triggers, 'though it's a pity because I'm working on WE 6059, of v1.28.
I was honestly expecting for something already hardcoded within the game, something that could be turned on and off like a switch, something I was hoping I did miss. The trigger for the earlier version seems a hard workaround: replacing units mid-fight(especially heroes) is not what I'm aiming at. Too bad. Thank you again. :/ I guess this is it.
 
Replacing a Hero actually works more gracefully than you might think. The game will transfer the hero's level, XP, carried items. You will have to make the trigger force re-learning the spells, which is a little finnicky due to GUI limitations but a few custom script lines make it work nicely. (This example will only work for a specific hero type. You need to have the ability ID codes and in this game version we can't dynamically read them from the unit.)
  • TurnOn
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(flamingarrows))
      • (Unit-type of (Triggering unit)) Equal to Melee Hero
    • Actions
      • Set HeroSelected = ((Triggering unit) is selected by Player 1 (Red))
      • -------- you will need rawcode of each Ability your hero has --------
      • -------- this should be an Integer Array variable type --------
      • -------- yes we are putting letters into an integer value --------
      • Custom script: set udg_HeroAbilityID[1] = 'AHfa'
      • Custom script: set udg_HeroAbilityID[2] = 'AHds'
      • Custom script: set udg_HeroAbilityID[3] = 'AHre'
      • Custom script: set udg_HeroAbilityID[4] = 'AHad'
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • Custom script: set udg_HeroAbilLevel[GetForLoopIndexA()] = GetUnitAbilityLevelSwapped(udg_HeroAbilityID[GetForLoopIndexA()], GetTriggerUnit())
      • Unit - Replace (Triggering unit) with a Ranged Hero using The old unit's relative life and mana
      • -------- Select Hero if they were already selected --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • HeroSelected Equal to True
        • Then - Actions
          • Selection - Add (Last replaced unit) to selection for Player 1 (Red)
        • Else - Actions
      • -------- Relearn Hero spells --------
      • -------- Since skill points are already refunded by Replace action, this method works nicely --------
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • For each (Integer B) from 1 to HeroAbilLevel[(Integer A)], do (Actions)
            • Loop - Actions
              • Custom script: call SelectHeroSkill(bj_lastReplacedUnit,udg_HeroAbilityID[GetForLoopIndexA()])
There are more limitations to work around that I haven't done in this example. For things where I'm not offering a solution, that's because I can't think of a good solution:
  • Ability cooldowns. Since I imagine you only have a small handful of heroes for whom this system will be used, you could use Timers to monitor cooldowns, and then Disable the ability on the replaced unit, re-enabling it when the timer expires. The cooldown visual on the icon won't look quite right, but it will remain unavailable for the correct duration.
  • Enemy units have to re-acquire target.
  • Item slots get resorted. If you have manually moved items within the inventory to different slots, that will be undone.
  • Attack 2 is not visible in a Hero info card; it will be buried beneath the Attributes. Solution: Only use Attack 1 for both unit types, just change the attack properties.
There might be more limitations, but depending on the type of map you're making, I think there might be some real potential to make this work. Maybe not perfectly, but perhaps good enough.

EDIT: note: I tested the above on game ver. 1.27 (I don't have 1.28 installed) and it works.
 
Replacing a Hero actually works more gracefully than you might think. The game will transfer the hero's level, XP, carried items. You will have to make the trigger force re-learning the spells, which is a little finnicky due to GUI limitations but a few custom script lines make it work nicely. (This example will only work for a specific hero type. You need to have the ability ID codes and in this game version we can't dynamically read them from the unit.)
  • TurnOn
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(flamingarrows))
      • (Unit-type of (Triggering unit)) Equal to Melee Hero
    • Actions
      • Set HeroSelected = ((Triggering unit) is selected by Player 1 (Red))
      • -------- you will need rawcode of each Ability your hero has --------
      • -------- this should be an Integer Array variable type --------
      • -------- yes we are putting letters into an integer value --------
      • Custom script: set udg_HeroAbilityID[1] = 'AHfa'
      • Custom script: set udg_HeroAbilityID[2] = 'AHds'
      • Custom script: set udg_HeroAbilityID[3] = 'AHre'
      • Custom script: set udg_HeroAbilityID[4] = 'AHad'
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • Custom script: set udg_HeroAbilLevel[GetForLoopIndexA()] = GetUnitAbilityLevelSwapped(udg_HeroAbilityID[GetForLoopIndexA()], GetTriggerUnit())
      • Unit - Replace (Triggering unit) with a Ranged Hero using The old unit's relative life and mana
      • -------- Select Hero if they were already selected --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • HeroSelected Equal to True
        • Then - Actions
          • Selection - Add (Last replaced unit) to selection for Player 1 (Red)
        • Else - Actions
      • -------- Relearn Hero spells --------
      • -------- Since skill points are already refunded by Replace action, this method works nicely --------
      • For each (Integer A) from 1 to 4, do (Actions)
        • Loop - Actions
          • For each (Integer B) from 1 to HeroAbilLevel[(Integer A)], do (Actions)
            • Loop - Actions
              • Custom script: call SelectHeroSkill(bj_lastReplacedUnit,udg_HeroAbilityID[GetForLoopIndexA()])
There are more limitations to work around that I haven't done in this example. For things where I'm not offering a solution, that's because I can't think of a good solution:
  • Ability cooldowns. Since I imagine you only have a small handful of heroes for whom this system will be used, you could use Timers to monitor cooldowns, and then Disable the ability on the replaced unit, re-enabling it when the timer expires. The cooldown visual on the icon won't look quite right, but it will remain unavailable for the correct duration.
  • Enemy units have to re-acquire target.
  • Item slots get resorted. If you have manually moved items within the inventory to different slots, that will be undone.
  • Attack 2 is not visible in a Hero info card; it will be buried beneath the Attributes. Solution: Only use Attack 1 for both unit types, just change the attack properties.
There might be more limitations, but depending on the type of map you're making, I think there might be some real potential to make this work. Maybe not perfectly, but perhaps good enough.

EDIT: note: I tested the above on game ver. 1.27 (I don't have 1.28 installed) and it works.
My man, you did so much for me and I could never appreciate it enough, but I'm afraid I've already made up my mind previously, opting for something different. I hope anyone pursuing the same goal may find this solution otherwise useful.
 
@LordPerenolde II do let us know if this worked, I'm curious!
Thanks for your interest. :) It's still tricky to conceive: How does the "Up/Root" ability turns off if there isn't enough mana? I mean, it's supposed to not attack at distance if there isn't mana, but what if I turn on the ability when there's no mana and the script would still trigger it as "turned on" and enable the ranged attack? Do you get what I mean?
It is all centered around this model, by the way, the one involved in this topic:

There is a "spell throw" animation where he throws his spear, rather than using it as a blunt weapon. If it is "spell throw", how can it be used as a secondary attack? I guess there has to be a whole "Alternate" set of animations for that to occur, right? I wouldn't know of how to move from this point.
<thinks>
Or maybe I can set the "Animation Names" tag, in the Ability tab, as "Spell, Throw", together with a "Cast Range" string for the "Searing Arrow"-like ability, so that the hero might attack at distance. If that works out correctly, I'm a genius(once more).
 
Back
Top