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

Floating Text on Orb of Slowness %chance

Status
Not open for further replies.
Level 2
Joined
Feb 13, 2020
Messages
19
Hello everyone,

First of all, I wish I could change the title of the post, as it has grown since awaiting moderator's approval.

A couple of questions from a noobie at mapmaking like myself. I started making maps 4 days ago, but I am loving it however!

Edit:
Since initially creating the post, awaiting Moderator's approval, I have been able to figure out the answers to some of my own questions myself. A few questions remains...

Who will be the first to answer?
____________________________________________________________________________________________

Question 1 (Hard): (Answered)
Can anyone of you help me figure out how, if possible, to make a Floating Text appear, when a spell is procced from the %-based chance from Orb of Slow?

I have made this Trigger, with the intent to show a Floating Text once a hero casts a spell:
upload_2020-2-15_2-44-57.png


However, this doesn't work, and I'll explain why.

All my heroes are using the Orb of Slow to proc their abilities. The ability that Orb of Slow procs is not a spellcast as of such, it's just an effect of an item proc. Changing how my heroes casts spells is not an option, so if that's a must, then I have to just give up.

Answer:
???

Note:
The Orb of Slow I'm using is the "Item Attack Slow Bonus" ability. Which I've then remade to a Hero ability and decided upon which spell it should use its chance to proc on. This is probably not news to most of you.

____________________________________________________________________________________________

Question 2 (Easy): (Answered)
Is it possible to create a Floating Text that appears when a hero learns a skill?

Answer:
Yes, yes it is. I found out the answer myself. I'm not worried about leaks for this one.
upload_2020-2-15_4-18-42.png


Note:
I had to name my custom spells with a prefix "Spell Learned:". It isn't the prettiest, but it's still a prefix pattern that I can easily get used to. So "Chain Lightning" was changed to "Spell Learned: Chain Lightning".

____________________________________________________________________________________________

Question 3 (Medium):
Is it possible to create a Floating Text that appears when a hero is trained for the first time and/or revives?

Answer:
???

____________________________________________________________________________________________

Question 4 (Hard): (Answered)

Can I make a Hero learn the Storm Hammers and/or Moon Glaives upgrade as an ability?

Answer:
Yes, yes you can. Storm Hammers and Moon Glaives are upgrades. The upgrades themselves carry the effect, the stats that define Storm Hammers/Moon Glaives. The abilities themselves are mostly just visual indicators that this unit has or can learn Storm Hammers/Moon Glaives when upgraded.

Below is how to make this work:

Storm Hammers:
  • Make Storm Hammers a Hero Ability and make a Hero able to learn that ability.
  • On the Hero set "Techtree - Upgrades Used" to "Storm Hammers (the upgrade)".
Now, from this point on, the hero knows that it's supposed to do spill damage with a small radius. But there's a check list that needs to happen first for it to even work:

  • "Combat - Attack 1 - Weapon Type" must be set to "Missile (Line)".
  • "Combat - Attack 1 - Damage Spill Radius" set to a value, I suggest "50".
Make this trigger or a better one:
upload_2020-2-16_3-37-12.png


Your hero now attacks with a spill range of 200 with a touch radius of 50. Just like a Gryphon. Except not a bird.

Moon Glaives:
  • Make Moon Glaives a Hero Ability and make a Hero able to learn that ability.
  • On the Hero set "Techtree - Upgrades Used" to "Moon Glaives (the upgrade)".

Now, from this point on, the hero knows that it's supposed to do a bouncing attack, but not how far it should bounce. So there's a check list that needs to happen first for it to even work:

  • "Combat - Attack 1 - Weapon Type" must be set to "Missile (Bounce)".
  • "Combat - Attack 1 - Area of Effect (Full Damage)" set to a value, I suggest "250".
Make this trigger or a better one:
upload_2020-2-16_3-43-35.png


____________________________________________________________________________________________

Cookies for the person who can answer any of these questions.

Final note:
If your suggestion includes custom scripts, damage engines or similar, I am unfortunately not interested. My map making level is far away from understanding those concepts. Thanks!
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,539
Here's the Answer to #3 for the Hero revive stuff:
  • Hero Floating Text First Trained
    • Events
      • Unit - A unit Finishes training a unit
    • Conditions
      • ((Trained unit) is A Hero) Equal to True
    • Actions
      • Set Variable TempPoint = (Position of (Trained unit))
      • Floating Text - Create floating text that reads Hello at TempPoint with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Floating Text - Change (Last created floating text): Disable permanence
      • Floating Text - Change the lifespan of (Last created floating text) to 5.00 seconds
      • Custom script: call RemoveLocation (udg_TempPoint)
^ Note that Trained unit is the Hero/Unit that was trained and Triggering Unit is the Altar/Structure that Trained it.
  • Hero Floating Text Revive
    • Events
      • Unit - A unit Finishes reviving
    • Conditions
    • Actions
      • Set Variable TempPoint = (Position of (Triggering unit))
      • Floating Text - Create floating text that reads Hello at TempPoint with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Floating Text - Change (Last created floating text): Disable permanence
      • Floating Text - Change the lifespan of (Last created floating text) to 5.00 seconds
      • Custom script: call RemoveLocation (udg_TempPoint)
Another thing, you can add a Suffix to most names in the Editor. I use the Suffixes to organize which ability goes to which hero. For example: Blizzard (Archmage). (Archmage) is the Suffix.
------------------------------------------------------------------------------------------------------------------------------------------------------

And I read your Final Note but I figured I'd leave this information for when the time comes that you do become interested in it.

On the Floating Text Memory leaks.

How to NOT create floating text:
  • Leak Example
    • Events
    • Conditions
    • Actions
      • Floating Text - Create floating text that reads Hello at (Position of (Triggering unit)) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • -------- ^^^ Position of Triggering Unit leaks a Point --------
How to create floating text:
  • Non-Leak Example
    • Events
    • Conditions
    • Actions
      • Set Variable TempPoint = (Position of (Triggering unit))
      • Floating Text - Create floating text that reads Hello at TempPoint with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • -------- ^^^We're now referencing TempPoint, which we set to the Position of the Triggering Unit --------
      • -------- --------
      • -------- Since we created the Point ourselves using a global variable this enables us to have access to it since we know TempPoint is referencing it --------
      • -------- So this one line of code will fix the Memory Leak. It Removes the Location (Point), and all you have to do is plug in the variable name with the "udg_" prefix --------
      • Custom script: call RemoveLocation (udg_TempPoint)
Voila, your Point leak is now gone and the game no longer needs to remember where you created that Floating Text.

I know this is confusing but it's pretty much required if you want your map to perform well.

So let's break it down. Let's look at a basic Action and see what it really does "behind the scenes".
  • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
This is what that Action looks like converted to code, now we can see what Blizzard is really doing when we use it. Note: I actually tweaked it a bit and removed some code from it to try and keep it simple.
Code:
function CreateNUnitsAtLoc takes integer count, integer unitId, player whichPlayer, location loc, real face returns group
    loop
        set count = count - 1
        exitwhen count < 0
        call CreateUnitAtLocSaveLast(whichPlayer, unitId, loc, face)
    endloop
endfunction
It looks intimidating at first, I know. But a lot of these words are recognizable, right? I mean I see "whichPlayer" so that's clearly where you would put "Player 1", I see unitID, so that's clearly referring to the Id or Identification of the Unit (Footman, Paladin, Ghoul, etc...). I see "loc" which is short for Location. Now this is where the terminology can confuse you, but know that a "loc" is the same exact thing as a "Point". So "loc" is where you are creating the Unit. Also, "face" is just the angle that the unit is facing.

Then you see this "loop" and "count" stuff, what does that mean?
Well that's fairly simple once you grasp the concept of a Loop. What if you wanted to do the something, let's say 10 times? You could do this:
  • Actions
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
    • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
^That'll create 10 Footman at your Point.

Or you can use a Loop:
  • Actions
    • For each (Integer A) from 1 to 10, do (Actions)
      • Loop - Actions
        • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing Default building facing degrees
^This will create 10 Footman at your Point as well.

The Loop runs the Actions 10 times.
So it's like if you were to count to 10 using your fingers. When you raise your 1st finger the Actions go off. When you raise your 2nd finger the Actions go off, again. 3rd finger -> again, 4th finger -> again, etc... all the way to 10.
The (Integer A) stuff can be ignored for now but that is an Integer variable that keeps track of which Finger you're currently on.

So we've now broken down what this simple looking Action really does:
  • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
Blizzard has hidden the code behind an easy to use/understand interface which is the Trigger Editor (we like to call it GUI). This is similar to when you press the Home button on your Smartphone, as you don't actually see the code running behind the scenes figuring out what apps to minimize/what needs to happen to successfully return you to your Home screen.

So what the hell does this have to do with Leaks? Well, Blizzard failed to address the Point leak in that CreateUnit code I showed you. It's an oversight on their part and we have to pay the price for it.

First, let's break down a Point:
Whenever you reference some place in the game world such as Position of Triggering Unit, or Center of Playable Map Area, or even Center of Region, the game stores that place as a Point (aka loc/location). However, there's more to it than that. What a Point really does is store the X and Y coordinates of that place. To better understand this, look at the bottom left corner of your World Editor and you'll see Point: (#, #, #). That's the X,Y, and Z of your current mouse position in the game world.

Therefore, when you tell the game to create 1 Footman at center of playable map area, you're really telling it to create a Footman at 0,0, since X:0 and Y:0 is the very center of the map.

So why is this such a big issue? The problem is that the game's memory never throws away that Point, it just sits there in the game's memory taking up unnecessary space. This is sort of similar to how the files in your Recycle Bin on your computer take up storage space until you properly empty it. So until you click "Empty Recycle Bin", those files still exist and take up space. In other words, until you get rid of them they will remain there taking up space.

So what we're doing to fix this leak is doing what Blizzard should've done themselves. We store the Point ourselves, instead of letting Blizzard do it the wrong way, and when we're done using it (which is when we no longer need the Point) we then run this code:
  • Custom script: call RemoveLocation (udg_TempPoint)
This code Removes the Location (Point) from the game's memory. Again, Point = Location/Loc.
If you try to create a unit at TempPoint after removing it, the unit won't be created because TempPoint has been removed. It has unassigned the value of the TempPoint Variable.

But why does it say udg_TempPoint instead of just TempPoint? Well, "udg_" is a prefix that just let's the game know that you're talking about a User Declared Global variable. It's required to make the code work and is basically there to separate Variables created in Code (Jass/Lua) from Variables created in the Trigger Editor using the Variable Editor (Control + B).

And that's pretty much it. So when you want to access some place in the game world and you don't want to leak Points:
Set a Point variable referencing that place and then when you're doing using it remove it from the game's memory using the "RemoveLocation (udg_VariableNameHere)" custom script.
Remember, always Remove the Point before setting it again. The moment TempPoint's value (the place you set it as) is replaced, you've created a memory leak, an inaccessible and permanent Point that will never leave the game's memory.

Anyway, Point Leaks are just one leak to worry about. There are Unit Group leaks, Player Group leaks, and Special Effect leaks (these are the easiest to deal with as all you have to do is "Destroy last created special effect", no custom script required). I would say to focus on Point Leaks/Special Effect leaks for now, as these are the most common ones that will really hurt your map's performance. You can worry about the rest later.

Some related info:
Memory Leaks
Things That Leak
 
Last edited:
Question 3 (Medium):
Is it possible to create a Floating Text that appears when a hero is trained for the first time and/or revives?

Answer:
???

You can detect when a hero is revived and trained.
  • Untitled Trigger 001
    • Events
      • Unit - A unit Finishes training a unit
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
    • Actions
      • Floating Text - Create floating text that reads X above (Trained unit) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
  • Untitled Trigger 002
    • Events
      • Unit - A unit Finishes reviving
    • Conditions
    • Actions
      • Floating Text - Create floating text that reads X above (Reviving Hero) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
 
Level 2
Joined
Feb 13, 2020
Messages
19
First of all, Uncle, thanks a lot for the thorough explanation. You should make it a sticky post somewhere. Although I'm not too worried about leaks as it stands right now, there's a case to be made about fixing leaks sooner rather than later. I will look into that eventually.

You can detect when a hero is revived and trained.
  • Untitled Trigger 001
    • Events
      • Unit - A unit Finishes training a unit
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
    • Actions
      • Floating Text - Create floating text that reads X above (Trained unit) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
  • Untitled Trigger 002
    • Events
      • Unit - A unit Finishes reviving
    • Conditions
    • Actions
      • Floating Text - Create floating text that reads X above (Reviving Hero) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency

Thanks for your response as well. These are my triggers, I believe they're similar to yours:

upload_2020-2-16_17-26-50.png

upload_2020-2-16_17-27-16.png


Yet, these triggers don't actually work. Bear in mind, that the revival happens automatically via this trigger (not that it should influence it at all):

upload_2020-2-16_17-28-11.png


The first training of the unit is manual selection as it's not revivable before it's died once. Future revivals are automated.

I cannot for the life of me understand why it doesn't work. And the worst part about it, is that I saw it work once in a game. And then I haven't seen it since. Food for thought. Thanks for your input.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,539
@Ravecharmer
In your second trigger your text reads "Proper name of Trained Unit". You want to reference Triggering Unit in this case, as the Event is unrelated to Training and doesn't know what unit you're referring to. This should be one of the first things you look for when your triggers don't work.

In some cases the Event will revolve around 2 units, like "A unit finishes training a unit". In these cases you want to be sure that you reference the correct units. For example, if a Barracks were to train a Footman, Training Unit = Barracks, Trained Unit = Footman. Triggering Unit = One of the two, most likely the Barracks.

Edit:
Misread your Hero revival trigger. I thought you were saying that it didn't work.
 
Last edited:
Level 2
Joined
Feb 13, 2020
Messages
19
Let me get it right, is your hero purchased or trained? These two has different events from what I remember. For revive, is it using Altar or Tavern (instant or not)?

I'm guessing he's trained. It's a standard Altar training. The Revive is explained in this trigger:
upload_2020-2-16_17-28-11-png.347279


This trigger works fine, no matter what happens in the game. There was never any issue making a hero revive. There's just the issue of making the hero's Proper Name appear on top of him (or at a TempLoc) when he is both trained and when he's revived.

In short, every time the hero appears, make his name appear as a Floating Text.


@Ravecharmer
In your second trigger your text reads "Proper name of Trained Unit". You want to reference Triggering Unit in this case, as the Event is unrelated to Training and doesn't know what unit you're referring to. This should be one of the first things you look for when your triggers don't work.

In some cases the Event will revolve around 2 units, like "A unit finishes training a unit". In these cases you want to be sure that you reference the correct units. For example, if a Barracks were to train a Footman, Training Unit = Barracks, Trained Unit = Footman. Triggering Unit = One of the two, most likely the Barracks.

About the Hero revival:
I think the issue here is that you're using a Wait. Waits will often lose information and references in regards to the Event. So in this case the Trigger no longer knows who the Revivable Hero is. I may be wrong though, try referencing Triggering Unit instead as I believe that is not lost after a Wait.

That being said, it sounds like you want an automatic revival system like you'd see in mobas like DotA or League of Legends. In that case, there's better ways of going about it. If you explain your revival system in greater detail I can help you more.

I'll try and swap it around, and see if it makes a difference. The triggers I showed were actually a copy/paste basically of the triggers you showed me, I believe. I'll try to mix-match the references.
 
Status
Not open for further replies.
Top