One of the features added quietly to Quoth 2.2 was an entity class called info_logic_random – in fact it was so quiet I forgot to link this class from the main tutorial after writing the tutorial entry. Our challenge today is to create a hack for vanilla quake which does something similar.
The basic plan is to create a entity which fires like a shotgun at a pair of shootable triggers. The random pattern of the shotgun pellets will be the seed of our random choice. It will be important to make sure the health of each trigger will be set up so that a single shotgun blast cannot do enough damage to kill both triggers. We also need to make sure that the triggers get reset each time.
First we’ll set up the shotgun entity – in fact it takes two entities, one to aim and one to fire. Create an entity as follows:
"classname" "info_notnull" "use" "W_Attack" "angle" "90" "targetname" "fire" "currentammo" "2"
Then clone it and change the
use function to
W_FireSuperShotgun on the copy. Test your map with a trigger_multiple triggering the shotgun setup repeatedly, and see if the angles of the shotgun attacks are following your view angles or not. If they are, swap round which of your entities is the
W_Attack and which is the
W_FireSuperShotgun – it’s important that one is triggered before the other and this is the easiest way to ensure that.
At this point, you should be able to see the direction that the shotgun is firing, and how large a spread it fires with. Create a brush for the shotgun to aim for, large enough that the blast will never miss this brush, at a range of 112 units from the
W_FireSuperShotgun entity (this range will be important later). Now split this target brush in two, along the exact line the shotgun entity fires on. Turn the left half of the brush into a trigger with the following keys:
"classname" "InitTrigger" "takedamage" "1" "target" "choice_a" "targetname" "fire" "health" "29" "max_health" "29" "th_die" "multi_trigger" "nextthink" "0.01" "think" "SUB_CalcMoveDone" "use" "SUB_CalcMoveDone" "think1" "multi_wait" "wait" "1"
You may recognise this entity hack as the instant-restore-on-demand shootable trigger from the restorable trigger_counter posts – so I won’t repeat much detail of how they work here. What I will observe is that we’re resetting the entity with the same “fire” event which triggers the shotgun, so each shot they are restored to normal. Change the right half of the target brush into an entity with identical keys except for the following modifications:
"target" "choice_b" "health" "28" "max_health" "28"
Time for a bit of damage calculation. The super shotgun we are simulating here fires 14 pellets each doing 4 damage each, or 56 damage in total. By ensuring that our shootable triggers have 57 health in total we are sure that they cannot both be killed in a single blast, so at most 1 event will fire. Also, if the random spread causes 8 or more pellets to hit one side, that trigger will take 32 hp damage and trigger its event. This should happen to either side with equal probability.
However, we haven’t accounted for the case where each side takes 7 pellets. In this case, the tie breaker is that the right hand trigger has only 28 hp. This ensures that one event fires every time, but it biases the selection towards choice B. How strongly? Well, in theory the pellets split 7 and 7 about 20% of the time.
If want to favour one choice over another 60:40, then the setup is ready to use. But what if you don’t? Well, one idea is to adjust the sizes of the triggers, but be careful. The centre of the target is the point that pellets are most likely to strike, so even a very small adjustment to the balance of the left and right trigger can have a large effect on the odds. I found experimentally that just making the left hand trigger 1 unit wider (and shrinking the right hand trigger to match) was enough to make the chance of A or B roughly 50:50.
It’s also worth noting that this also depends on the trigger being 112 units away from the shotgun entity. Moving it further away decreases the odds of A again, while moving it closer begins to make A more likely to occur than B. Adjusting the range the shotgun fires from makes for a pretty flexible way of tuning the probabilities, so have a go with it. An example map is available to support this post.