I/O Conundrum

Hey guys, been a while since I’ve visited but I’m getting back into mapping and ran into an interesting problem on one of the projects I’m working on, and I was hoping I could get some second opinions on it.

I’m playing around with an idea for a map that uses a system of func_movelinears and logic entities to create a smallish level whose layout randomly shifts throughout the round. The idea being that the sudden and unpredictable appearance/disappearance/modification of hallways, crawlspaces, walls, defendable areas, etc will keep players on their toes and ensure that no two rounds are identical.

I’ve been doing some playing around with small scale tests using only a few… lets call them pillars in lieu of a better term. I wanted to optimize things a fair bit (as opposed to having to work out the I/O chains for 100+ entities) and my original idea was to break up the map into zones and subzones and pillars selected randomly from a small hierarchy of logic_cases. A logic_timer would trigger the selection process, the end of the hierarchy would trigger a FireUser## output from the selected pillar and another logic_case would use a pickrandom and a !caller tag to output one of several possible SetPosition commands to the pillar.

The idea was that the selector hierarchy would optimize the process of randomly selecting pillars or groups of pillars and the use of the !caller tag with the logic_case determining the SetPosition value would mean I could use just one instance of the entity to output to any/all of the pillars.

Unfortunately the logic seems to be getting confused. Using the !caller tag causes the SetPosition output to go to the logic_case itself (like a !self tag) rather than the pillar which called it.

I realize it’s a rather unusual and specific problem, but if anyone has some ideas to solve the issue or suggestions to work around it, I’d love to discuss them with you.

Try running the process through a filter_activator_class with func_movelinear being the class you are filtering. This will prevent any calls to SetPosition not used on the pillars to be ignored.

Thought about that but since the logic_timer is technically the start of the I/O chain, using !activator instead of !caller sends the SetPosition output all the way back to the timer.

The problem seems to be that, for whatever reason, running the pickrandom process seems to make the logic_case its own caller.

I had thought about trying to work around the issue using relays but I run into the same problem - triggering the relay sets the !caller to the relay itself.

Well pickrandom is called from logic_case. The entities might be external but the place they are chosen from are stored inside the logic_case.

Hmm, is there any way then to call back to a previous entity in an I/O chain without going all the way back to the activator?

!caller should work but as far as I know logic_case calls itself so it technically functions correctly.

You could use a Math_counter entity and have the logic_case PickRandom and if the value is equal to the Math_count max then it can fire SetMaxValueNoFire (or SetMaxValue) and run SetPosition through Math_counter’s OnHitMax.

The problem I’m seeing with all these methods (if I’m understanding correctly) is that inevitably I end up having to have all of the pillars have an individual output regardless of whether I’m just using the logic_case or incorporating other entities on top of that, which defeats the purpose of what I was hoping to do.

My hope was to come up with a more optimized solution that would allow the SetPosition output to go back to whichever pillar happened to be selected at the time, cutting down on the number of entities needed and the number of inputs and outputs that need to be set up.

Oh ok, I think I see the problem. I’m not sure if you are able to do this and this logic is pretty hard to comprehend without visual aides so I’ll see about drawing something up.

This might help. I threw together an image of the I/O chain I was trying to build. This might give you a better idea of what I was trying to do.

  1. The timer periodically sends a pickrandom output to the selector.
  2. The selector has a list of possible pillars and outputs a fireuser to whichever one is picked
  3. On the fireuser input, the selected pillar outputs a pickrandom to the positioner
  4. The positioner has a list of possible SetPos heights (0 thru 1) and outputs a SetPos back to whichever pillar called it.

Unfortunately (4) is where we run into a problem.

Edit: Actually, here’s a thought - can you use the parameter output to reference a variable parameter besides things like !caller, !activator, etc… like say the value of a math_counter? If so, I could rig the math_counter with random float values and have the output from the selecter call the float when it sends the SetPos output to the pillar.

So I figured out a solution that works (almost).

So using a !caller output with the logic_cases wasn’t an option since it calls to itself, but using !caller with the math_counter does call back to the previous entity in the chain as it’s supposed to.

So the logic now looks something like this:

timer1 -> output ‘PickRandom’ -> positioner
timer2 -> output ‘PickRandom’ -> selector
positioner -> output ‘SetValueNoFire’ -> math
selector -> output ‘FireUser1’ -> pillar#
pillar# -> output ‘GetValue’ -> math
math -> output ‘SetPosition’ -> !caller

And the end result looks a little like this

… now if I can just get math_counter to work with float values I’ll be in business. Thanks for all the help guys.

Funny, I’ve been working on a map similar to this for a while. I’ve got a map of func_movelinears that randomly move to different heights.
The way I’ve done it is using trigger_multiple with a filter for my movelinears.

The timer enables (then disables) the trigger. The trigger, OnStartTouch, fires a logic_case to PickRandom a selection of setposition: values, directed at !activator. Because the movelinears tripped the trigger, they are the activators.

You don’t get total control, ie, it’s possible for every movelinear to move to the same position - though in my case its very unlikely. Dunno if its what your after, but it saved me a hell of a lot of time since I have 91 of the damn things.