## Tutorials

### Manage events in entity setups

**Using Logical "Flags" to manage states in entity setups**

So this tutorial has quite the mouthful of a title I know, perhaps I should explain that a bit. You are familiar with the "Flags" tab on an entities properties (if you aren't then this tutorial is beyond you), but you may not be aware of how it stores data. Each flag is assigned a number, starting with 1, which is four times the value of the previous flag. So let's say that an entity has four flags, they would be assigned the values 1, 2, 4, and 8. This allows all the flags values to be stored as one number, the sum of the values of the flags you check. So let's say you check the first, third, and fourth flags: the entities "flag value" would be 41. This works because well because each possible combination of any number of powers of 2 and the number 1 yields a unique number. In fact, with 1, 2, 4, and 8 you get the numbers 1 through 15.

So that's all great and all, but it's not what this tutorial is about. What we will be doing is setting up an entity system that uses this same theory to manage map events and logical states.

**The Goal**

As an example of what can be done with this we will make a puzzle with four buttons (though it can easily be expanded to as many as you want). For every combination of the buttons something different will happen. This equals 14 combinations. For buttons named A, B, C, and D:

A B C D AB AC AD BC BD CD ABC ABD ACD BCD ABCD

Fifteen combinations! With five buttons it's a LOT more:

A B C D E AB AC AD AE BC BD BE CD CE DE ABC ABD ABE ACD ACE ADE BCD BDE CDE ABCD ABCE ACDE ABDE BCDE ABCDE

So you can see how this can quickly spiral out of control. Still, it's rare that you'll need more than three states (six combinations) to keep track of and even if you need four or more states it's rare you'll need to keep track of all combinations. Either way the setup is VERY simple no matter how many states you are doing. Anyway, let's get cracking. We start with:

A test box! And then we move on to...

**The Logic**

Entities Used: **func_button** OR **logic_branch**, **math_counter**, **logic_case**

Ok, so first let's make four buttons. Just basic no frills buttons, they don't even need names for this test but we set the "Toggle" flag. Then we make a *math_counter* and a *logic_case*. Name the *math_counter* **mc_buttonflags** and the *logic_case* **lc_buttonflags**. We don't need to change any other keyvalues on the *math_counte*r but we do need to set some on the *logic_case*. What we will be doing is assigning each *func_butto*n a value either 1, 2, 4, or 8, adding those up with the *math_counter* and checking the sum against the *logic_case*. So enter each of the possible combinations into one of the *logic_case*'s "Case" fields.

Now we give each button two ouputs. The first button targets the math_counter with "OnIn: Add 1; OnOut: Subtract 1", the second button with "OnIn: Add 2; OnOut: Subtract 2" the third with "OnIn: Add 4; OnOut: Subtract 4" and the fourth with "OnIn: Add 8; OnOut Subtract 8". Then we set an "OutValue" output on the math_counter targeting the logic_case with "InValue." Output out, input in, oh so simple and sweet.

The button get's pressed in it adds it's value to the system's state, the math_counter tells the *logic_case* which fires the relevant output. The button get's pressed again (unpressed), it's value is removed, and the appropriate case is fired.

And that's basically it, now we just need to setup some stuff to happen based on the different combinations. Each of the OnCaseXX outputs on the *logic_case* now represents a different combination of buttons, OnCase07, for example, which represents the combination of buttons one two and three (vales 1, 2, and 4 respectively). Of course you might have four buttons but only, say, five unique combinations with the other nine combinations nonfunctional or the same. If this is the case you can change the *logic_case*'s settings removing the CaseXX value for each of the value that aren't unique, and using the OnDefault output if those other nine states trigger something **generic** OR, if they **don't trigger anything at all**, just leaving things as they are and not giving them any outputs. The OnDefault output fires when the input value does not equal any of the CaseXX values. Oh, and the *logic_case*'s OnDefault ouput is triggered if all the buttons are unpressed. So, if you press the first button the OnCase01 output will end up firing, and if you unpress it, the *logic_case* is now set to 0, which doesn't have an entry, so it fires OnDefault.

**Using five states**

In the VERY unlikely event that you have unique outcomes for every possibly combination of five or more states, which is dozens of possibilities, you simply create a second *logic_case* or even third *logic_case* to hold the additional possibilities. The sequence continues with powers of two: 16, 32, 64, 128, etc. If the value is present in the second *logic_case* it will fire the proper outputs and the first *logic_case* will fire default.

**Note on the prefab**

Place the Prefabs Logic folder in either steam/steamapps/<usernam>/sourcesdk/bin/ep1/bin/prefabs/ or ...bin/orangebox/bin/prefabs. or ...bin/source2007/bin/prefabs/, whichever engine version you are working with.

I wrote this tutorial using *func_button*'s instead of *logic_branch*'s like the prefab because it is simpler to setup which you should do yourself the first time if there's anything that's unclear. Both the prefab and the level with the button logic are included.

Prefabs use the wildcard &i for instancing. If you place a prefab in your level each place &i shows up will be changed to the number 1. If you place it a second time it will be changed to the number 2, and so on. The prefab (in Prefabs Logic/logical_flags.vmf) has all of this correctly setup.

The prefab uses *logic_branch*'s instead of *func_button*s. In this case the OnTrue output adds the number and the OnFalse output subtracts it. This can then be linked to buttons, triggers, or whatever by using each *logic_branch*'s SetValueTest input with either 0 or 1. Sending the lb_value8_&i *logic_branch* the input "SetValueTest: 1" will cause it to add the value 8 to the *math_counte*r. This way you can easily link map events to the systeme by targeting the *logic_branch*'s. Just create two outputs for each event targeting a unique *logic_branch*! The *logic_branch*'s are named lb_value1A, 24B, 4C, and 8D so you have both a number and a letter for easy identification! Then you just add the appropriate OnCaseXX output to the *logic_cas*e!

**Goodbye**

You may want to organize your "OnCaseXX" outputs with *logic_relay'*s if you have alot going on but the prefab does not include that as it would clutter everything oh so much!

Anyway, I hope this was clear enough. It's a pretty simple concept that is easy to setup and has a LOT of power. Even if you are just managing three buttons for seven unique states and only using three or four of those this is the way to go. If anything didn't make sense just look at the included files. Adios!

http://www.interlopers.net/downloads/ma ... torial.rar

Mr. Happy