The Input named AddOutput

EmNudge

L4: Comfortable Member
Sep 23, 2015
184
60
AddOutput is an input in Hammer. If you aren't familiar with the IO system, this tutorial may be a bit confusing, so I'd advise you brush up on it before coming here. AddOutput is an output that does some funky stuff with outputs, so it would be really confusing if you don't know the basics.

Well, for starters, AddOutput is an input that can do one of two things:
  • Add an output to another entity (as its name implies)
  • Change the value of a property of another entity
Although the first may seem a bit confusing, it's arguably better to know and is actually what the name describes, so I'll go over that one before the latter.

For a video tutorial, for all those visual learners (which I highly recommend checking out since I show you it working in game), watch this guy over here:
View: https://www.youtube.com/watch?v=sUgOWOpjkhc


ADDING AN OUTPUT
64c699385c29e0e15642362be8b60a09.png


It's pretty basic in concept (as well as in practice, don't let the syntax scare you) - all you do is add an output to another entity. Now before I explain how, let's ask - why?
Why would you want to add an output to another entity? Why not just have it there? Well, I'm glad you asked, Me, since that's what I'm gonna explain!

For this output in general, you can probably accomplish what you'd like to accomplish with multiple logic_relays, math_counters, and logic_cases. It's just a waste and unnecessarily complicated is all. There are also some cases that can't be solved with all those other entities, but you'll know when you get to them - I'm gonna discuss some other cases.

Now, when would you use this? Well, let's say you had a button that did one thing, but you wanted it to do an additional thing when a certain condition was met. Let's say you wanted to control the number of times an output was allowed to be fire, like only 13 times or something (without using a math_counter and logic_relay). Let's also say that you wanted to give the player a choice between a few buttons, but only display the result of the button the player picked when they hit a different button. All of those can be accomplished using AddOutput.

Now for the format. As described on the valve wiki page, the format goes like this:
Code:
<output name> <targetname>:<inputname>:<parameter>:<delay>:<max times to fire, -1 means infinite>

You can use the image above for reference, but let's give a typed example:
Code:
OnStartTouch my_sound:PlaySound:0:0:-1
That basically means that when a player touches this trigger, play the sound called my_sound with no additional parameters (since PlaySound doesn't accept any parameters), with no delay, and make it fire infinitely (meaning not fire once).
Remember that this is all in the Parameter section of the output and that there is a space instead of a colon between the output name and the target name.

Now that you're somewhat familiar with the format, let's move on to the cool cases. I won't be explaining each one in too much detail. I'll instead be posting pics of the output and giving short descriptions.

bfb2c044a6c84cdf78bdaffb9fd5e1e9.png

this one above is a button that makes another button play a sound upon being damaged. It is also set to only fire once, as that last number indicates

5707265233a837c3592edcaab12ec88a.png

This one above is the same as the one before it, it just applies it to itself. The !self target is whatever the entity you're typing this on. This button will do nothing on the first hit but play a sound every time after.

ae1f1755cc26bc4ed1d500e5a88bfc69.png

I had to take a pic of the viewport here since this one's a bit interesting. Each button adds a different output to the trigger that fires once. The trigger is blank and disabled by default, but the green button enables it and then disables it directly after. With this method over here, we can have buttons add different outputs to a trigger and only having the trigger's output be applied upon the player hitting another button. Basically, we have a custom trigger that can be enabled whenever!

b3371ee11ead21aed6f09ae1bcd05653.png

This one was pasted above before, but the thing that makes this special is the last number in the parameter.
This is a logic_auto that adds a normal output to a button, but the 5 there makes it fire 5 times and then stop. As opposed to having fire once or fire forever, you can add a custom amount!

Well, that's all for this part. Of course there are many other cases, but get creative, ya dingus! Let's move on to changing an entity's property's value:

CHANGING PROPERTY VALUES
25cd2844432ccf15185e6e92592ba30f.png


Now this guy's got less syntax, but you have to keep a few things in mind. Before we get to that, like before, let's discuss why you'd use this guy in the first place.

Some examples of its use are changing properties of a filter. You can also change which filter a trigger/button accepts. You can change the targetname of an entity to give it a whole nother set of inputs! On top of all that (and much more) you can change certain properties of the player! Yup! The player is considered an entity and has got a few properties you can mess with which makes for some rather interesting uses.

Now for the syntax. It's super simple. As before it's gonna be in the Parameter section, but an important thing to note is that the name HAS to be the actual property name, not the Smart Edit name. You'll have to turn it off to see the actual name you'll be using. You just have to put
Code:
<property to change> <value to change to>
W let's look at a few examples:

b141d740f34b529942a0b69ce17eb3f8.png

needed to include the viewport for reference. This guy here has 9 buttons which each change a filter named filter_various_class to a different tfclass. The classes are in numbers from 1 to 9. Each button corresponds to its class. The filter affects the trigger which plays a sound OnStartTouch.

f94d6a267a0d36f625ed2ee9533c4637.png

Now, this isn't a super functional thing to do. This is a button that changes the speed of a func_door_rotating. There's one problem though - the speed doesn't change! Not unless it gets fully closed or collides with an object. If this button is hit while the brush is rotating, nothing will happen. Not until it closes or collides with something (can be the player).
That's just to show that many times the property that's value was changed won't necessarily update. It may wait for an event such as OnMapLoad or OnCollide or something else. Test things! TEST THEM!

bfe8fb1f1950b16f94177343bf0f80b5.png

Now this one is pretty interesting. This time it changes a property of the player, the one who pressed it, the !activator. This specific property it's changing is the origin. In this way you can set the coordinates to teleport to without the player getting into a trigger_teleport! This means it doesn't matter where the player is, as long as the player presses the button, he'll get teleported!
An important thing to note is that you have to use OnPressed instead of OnDamaged. You can tick damage activates so that it's essentially the same thing, but the reason why is that there is no !activator for OnDamaged, only Onpressed.

Now, I'll leave you with a list of things that can be applied to the player. Some things here are not an AddOutput, but that should be fine for most purposes. They're all outputs which means you can use them with buttons.

Output | Target | Input | Parameter | What it does
OnSomething|!activator|AddOutput|targetname [string]|Changes player name to be used with filter_activator_name
OnSomething|!activator|AddOutput|SetDamageFilter [damage filter name]|Changes what source can damage player.
OnSomething|!activator|AddOutput|origin [X, Y, Z]|Teleport Player to coordinates
OnSomething|!activator|AddOutput|basevelocity [X, Y, Z]|Shoots player in desired direction. Acts like trigger_impulse
OnSomething|!activator|AddOutput|gravity [? - ?]|Acts like trigger_gravity. negative values only work once player is in air. 0 does nothing.
OnSomething|!activator|AddOutput|health [integer]|Sets health to a certain value. Over max health will result in overheal, negative is glitched
OnSomething|!activator|SetHealth|[integer]|same as above, but no overheal. max health and 0 are limits.
OnSomething|!activator|AddOutput|renderColor [R, G, B]|Adds tint to player.
OnSomething|!activator|Color|[R, G, B]|Does same thing as above.
OnSomething|!activator|SetTeam|[0/1/2/3]|Changes player's team. 1=spectate 2=red 3=blue 0=none. Acts like team glitch, can only join team through console
OnSomething|!activator|AddOutput|rendermode [integer]|Changes rendermode. Not too well versed in the effects.
OnSomething|!activator|Alpha|0|Values other than 1 make player invisible. Only works if rendermode is set to 1
OnSomething|!activator|SetModelScale|[? - ?]|Changes player model. negative values may crash TF2

The maps I've used in the video, where these examples come from, are attached to the thread. Download them and mess around to get a feel for how AddOutput works. The video may also prove as a great resource as it acts as a visual demonstration as well.

Hapyy Mapping!
 

Attachments

  • addingAnOutput.vmf
    46.8 KB · Views: 339
  • changeValueOfProperty.vmf
    58 KB · Views: 286
Last edited:

B!scuit

L4: Comfortable Member
Aug 12, 2016
195
266
I've been trying to figure out how to make Frontline landmines spawn without trapping players inside them.
This might just be the key to the solution, thanks!
 

Izotope

Sourcerer
aa
May 13, 2013
698
764
What if I have a button and I want to add an output to a trigger like this:

9ceae95052.JPG

This doesn't work for me.
You're using spaces, but you have to use : without spaces.
Your added output is also invalid, it would have to look like this:
Code:
OnStartTouch !activator:AddOutput:targetname X:0:-1
Note that the last value is number of times to fire, if this is only supposed to fire once, change it to 1 instead of -1

Hope this helps!
 

BenjaminsMaps

L1: Registered
May 1, 2012
4
1
Thanks for the quick answer.

It works fine now! I tried the same with the colons and parameters at the end, but I didn't have the space between the name and the inputname. Thank you so much!
 

MrGazdag

L1: Registered
Jul 12, 2017
2
0
uhh, SetHealth isn't working..., i tried:

Via this input: AddOutput
With a parameter override of: sethealth <number>

Via this input: SetHealth
With a parameter override of: <number>
 

EmNudge

L4: Comfortable Member
Sep 23, 2015
184
60
uhh, SetHealth isn't working..., i tried:

Via this input: AddOutput
With a parameter override of: sethealth <number>

Via this input: SetHealth
With a parameter override of: <number>
I'm not at my computer now, so I'll get back to you when I'm home, but according to my list I think I know where you messed up.

If the input is addoutput then the parameters should be health <number>
Not sethealth <number>
 

MrGazdag

L1: Registered
Jul 12, 2017
2
0
[BEFORE TEST] Okay, im gonna try it....

[AFTER TEST] Thanks bro, you're the best!
 

EmNudge

L4: Comfortable Member
Sep 23, 2015
184
60
A bit of an update on the list at the end. I missed something since after testing I've found there actually IS a difference between using the input AddOutput and changing the health AND using the input SetHealth and the number as a parameter.

The difference is that using AddOutput, the actual health value gets changed and therefore maxhealth and minhealth are NOT cap values. meaning anything above the player's max health will be added, but decrease at the rate overheal decreases. You can use that for, say, a saxton hale boss mod. Negative values/0 will glitch the health hud icon and set it as if you have 1 health. Any dmg will kill you.

using SetHealth, on the other hand, will have cap values. That means that 0 or anything below it will kill you. Anything above your max health will go straight to your max health. That means if you set heavy's health to 1047343, it will just be 300. I use this guy here for keeping players' health at the max in a certain area. This way I don't have to have a separate trigger for every class, using 300 will work for every class without overheal.

The table has been updated, but this post provides a lot more info.