The quest continues to create a trigger_multiple which can be activated and deactivated at will. The previous post described how to make a trigger_once which can be triggered active, but cannot be deactivated again. Can it be adapted to help our quest?
Although modifying the specific entity-hack from last time will be vital later, the most important idea to take from the last article is how a standard
trigger_multiple enforces a waiting period between activations (the
wait key). Rather than updating the entity to remove collisions, the QuakeC code allows all the collisions to occur as normal, but just chooses to ignores them. The decision to ignore a collision is made by checking whether the
nextthink time of the entity is later than the current time.
What I think is interesting is how closely this resembles the current “best attempt” at creating the goal of an activating/deactivating trigger. What you might expect to create is a trigger that you can enable and disable collision on. The best attempt I know of is just an unmodified
trigger_multiple providing the collision all the time, but targetting a logic gate which is the part that actually switches on and off.
This is far from perfect. One objection is that it needs 4 entities per trigger (1 trigger plus 3 to make the logic gate), but I expect all solutions will require more than one entity, so an overhead of 2 more isn’t the worst case imaginable. One more subtle concern is the interaction with
wait. Imagine we apply
wait 10 to the trigger. If we touch the trigger now and the logic gate is inactive, this starts a 10 second waiting period in which all touches are ignored. If the logic gate is activated 5 seconds into the period, the remainder of the waiting period must still pass before our trigger “notices” the gate has change. But nobody would expect that contact with an inactive trigger would have any effect on the trigger after it activates. It should detect touches as soon as the gate is toggled!
Returning now to the entity hack we performed last time, part of the trick was to set
wait extremely high, to get in essence a
trigger_once which doesn’t get automatically deleted. What kind of entity would we get if we set
wait 10 instead? It would almost be the same as a normal
use function that resets the entity isn’t so exciting if it resets anyway after 10 seconds. Being able to override the waiting period on demand seems like a pretty niche feature…
Except that’s exactly what the first half of the article was setting us up to need! It allow the creation of an effectively seamless trigger we can activate and deactivate at will. All that is left to do is demonstrate it. Grab a copy of the test map cadmium and load it up. The source .map file is included if you want to import an working example into your map.
The test map contains two wall-mounted laser shooters. The purple squares on the floor mark out the trigger which fires these lasers on a 4 second
wait (intentionally long to illustrate the features of the hack), but this trigger is deactivated at the start of the level and must be active to function. The blue shootable button on the left activates the trigger (by both opening the logic gate AND resetting the trigger’s waiting period), and the red button deactivates again.
You can test the following: the trigger responds to activation and deactivation accordingly; while within the trigger, activating it causes the lasers to fire immediately; entering the trigger while it is deactivates never causes a subsequent waiting period if you reactivate it. You may find it illustrative to add a
message key to the floor trigger and recompile, so that you can track when it attempts to activate the lasers, especially when testing the zero-waiting-on-activation feature.
There is a bonus feature in this map I really ought to write up properly in future. The logic gate has been refined back down to 3 entities (last year I discovered that my original design was flawed and fixed it by adding a 4th entity). Moreover, the new design removes the requirement that two of the entities appear in a particular order in the map file – all 3 entities are independent in that sense, making the design much more portable.
I’ll close with a bit of a challenge. We used 4 entities today between the trigger in question and the logic gate that governs it. There is a (frankly horrendous) way of saving an entity, which involves setting an
origin key on the trigger, shifting the brushes of the trigger to compensate, and then exploiting the fact that we aren’t using
think1 on the trigger but we could be. If you can fill in the gaps of how that lets you replace one of the entities in the logic gate, and actually get it to work, post a link to the map in the comments and earn my undying respect!