News | Forum | People | FAQ | Links | Search | Register | Log in
Teaching Old Progs.dat New Tricks.
You know about the info_notnull explosion hack. You know about making monsters drop weapons or alternate ammo using the .weapon and .ammo_whatever hacks. You know about making items float in the air by spawning them on a temporary platform. Let's have a thread where we talk about new ways to use existing behavior and get novel gameplay. If you're a "retired" mapper, this is a great time to do some armchair level design and suggest ideas you'll never have a chance to use yourself.
First | Previous | Next | Last
I'll Start. 
Here's one i thought of a while ago. You all know that only the first 4 info_intermissions can get used in a level. You could set it up so that if a player meets some requirements (like finding some special secret, killing all the monsters, or something) you killtarget all 4 "regular" info_intermissions, so that the 5th one gets used instead -- and the 5th one would point to some cool secret vista. 
...I've got the weapon drop hack to work in level before (see the first ogre in dis_cr8z, but I've never been able to get the ammo drop hack to work. Would someone care to explain in detail?

Good thread BTW! 
Dynamic Lights 
Add an effects field with a value of 1,4 or 8 to an entity to make it emit light. If the entity is mobile (like a door or a monster) the light will travel with it.

Possible use? Light a maze using mostly glowing monsters, so as the kill-count rises, the map gets harder to navigate.

This is a great thread because tips like this aren't as easy to come by as they used to be. 
Respawning Items Without QC 
Ok, just figured this one out, it follows on from the stuff I posted in the mapping help thread, but that isn't required reading to understand how to do it. Take any item that respawns in deathmatch(I've only tested ammo but see no reason why anything else should fail). Give it the following fields

targetname shells01
target shells01respawn
use SUB_regen

Then make a trigger relay with these fields

targetname shells01respawn
target shells01respawn
delay 20

Here's the flow of action. You pick up the shells(or whatever) and so the shells fires it's target. The target is the trigger relay, which begins counting to 20. When it reaches 20, it fires it's target, which is back to the shells. Here's the cunning hack, the use function of the shells is SUB_regen, the function called in dm to respawn items. So the shells are respawned! If you have multiple items you'll get odd behaviour if you don't give them all unique names.

Of course, you aren't constrained to items respawning on a timer. You could have an arena with items, two waves of monsters, and then have all the items respawn once the second wave comes in. Assuming killing all the monsters sets off a trigger_counter with target "secondwave", give the items you want respawned the following keys:

use SUB_regen
targetname secondwave

Et voila! Loads more ammo just in time for the next attack. And for once you're probably saving entities, handy for those maps which are pushing the limits in that direction. Luckily calling SUB_regen is perfectly safe on items that are already spawned. You get the respawn noise even if it's already there, but the item isn't affected at all.

Ok, I think that's enough for tonight. Tomorrow I might do a few reposts, the triggerable trigger and the heal trigger and those, along with further experiments into unusual ammo supplies and perhaps something very old and special... 
That is uber cool. Hello healing pool! 
I didn't even really know all these hacks existed, must not have been paying attention when people started using them.
What's the info_notnull explosion hack mentioned in the initial post?

Thanks for the good thread. ;) 
Info_notnull Explosion 
The info_notnull explosion is a classic, and it uses just one field on one entity to work. The trick is to take an info_notnull, and add a key:

use barrel_explode

Then give it a targetname and a trigger that targets it. When the trigger is fired, the info_notnull will explode. When an entity is targetted by a trigger, the QC calls whatever function is in the use field of an entity. Most entities like doors and triggers set this field when they are spawned, overwriting what you might want to add. But an info_notnull has no code in it's spawn function, so you can add any function to use, and it will be called.

barrel_explode is quite a powerful explosion, liable to injure or kill the player. A nicer, less damaging alternative is OgreGrenadeExplode which does the damage of, you guessed it, an ogre grenade. tbaby_die2 is fun for a wierd effect, it's the purple explosion of a tarbaby.

Unfortunately all these functions end up removing the entity after the animation has completed, so the only way to get multiple explosions out of one of these is to trigger it more frequently than one every 0.5 seconds. As soon as you let it fully animate once then it's gone. There may yet be a way to get repeated explosions from one entity, but I've yet to hear it.

If you root around the quake source, you can find other functions that do things besides explosion effects, and many of them can be performed from the use field of an info_notnull. In addition, any other entity that doesn't have anything in it's use field by default(eg ammo) can do this same trick and explode on a trigger. Exploding ammo probably isn't the best example, but I'm sure there's some useful example of the idea. 
About Time Such A Thread Is Started... 
nice one. i wasn't aware of some of the things mentioned here, either, like the respawning items and the other kinds of explosions... so thanks, indeed. :)

re #3: dynamic lights
"effects" "1" - particle field (yellow? - i don't know if one can change the color), "2" - bright light. "3" - dim light

play (different) sounds
trigger an info_notnull which contains

"use" "train_wait"
"noise" "player/gib.wav"
"wait" "-1"


this works with doors (noise1 and noise2), trains (noise and noise1) and other func_s. the sound has to be precached!
*some people also used "nextthink" "0" - i'm not sure what this is good for. maybe someone can clarify...

nonsolid models
create an func_illusionary entity (=no brush!) which contains

"model" "progs/player.mdl"
"frame" "1"

the model has to be precached and its angle appears to be fixed with worldspawn. 
is there a way to use the teleport glitter, lavasplash, lightning (without chton) and possibly gravity (without naming the map e1m8)? probably not, eh? 
Nice Thread 
how about using some marker like "->" or "Code:" in the post title to mark ready code? it would make the thread even more useful i think 
Code: Lightning And Monster Triggers 
Teleport glitter, such a nice name for it. I thought it was possible to do this like the explosions, but that's not the case, spawn_tfog will always put them at the origin. This is because spawn_tfog is a function with a parameter in the QC, it's defined as
void(vector org) spawn_tfog. Use will always pass a null parameter to this, the value '0 0 0' for a vector.

However, this same thing actually allows us to get lightning beams working! I'll detail the trick first, then explain how it works. You need something to trigger the lightning, lets say a trigger_once with target l1 for simplicity's sake.

Make an info_notnull with these keys, doesn't matter where it is

targetname l1
use FireBullets
v_angle 'x y z'

where x y z is the angle you want to fire the lightning at.

Then make an info_notnull in the place you want the lightning to start with these keys.

targetname l1
use W_FireLightning
ammo_cells 9999999

This fires the player lightning attack, so it does damage, and has a 600 unit range. Each time the lightning is fired it uses one cell from the ammo_cells count, and it won't fire with none, so set it nice and high if you don't want a limit. The most important thing is that the FireBullets entity is one entity higher up in the maps entity list than the W_FireLightning.

How does this unlikely thing work? Well, W_FireLightning fires a bolt along the vector v_forward. The firing thing pretty much works like any other info_notnull does, the only problem is this v_forward vector. v_forward is usually set to the player's facing duing player functions, so we need to find a function that sets it for use.

This is where the other entity comes in. It calls FireBullets. How is this safe? If you look at the FireBullets code you might notice it has parameters (float shotcount, vector dir, vector spread). Luckily, all these values are null, so the shotcount is 0 and it fires nothing. Luckily before it fires it aims the v_forward vector along it's v_angle. The order in which the entities are spawned is vital, becuase that's the order they will run their 'use' functions when they are triggered.

Wooo, that took a while. Ok, for a little bit of fun, how to make a trigger that will be triggered by anything that touches it, not just players. This includes everything from rockets up. I know somebody wanted this in mapping help a while back, but I only figured out how to do this today. Make a brush with class info_notnull and keys

think InitTrigger
nextthink 0.1
touch multitrigger

and any of the trigger_once/trigger_multiple fields you like. Two caveats. One of them is about sounds. The "sounds" field won't work, but if you set the noise field to a sound precached already then that will play. The second one is this trigger is a bit dangerous. Don't give it a message or you'll end up crashing the game if a non player triggers it, I expect. Also, the activator will always be world, so it may not trigger everything right. Of course, activator would be player otherwise, so anything that relies on that probably would be inappropriate for a trigger activated by anything.

Ok, done for now. Have fun 
Thanks for posting the respawning items hack. I wanted to ask you about this yesterday but I didn't want to impose.

I now have two ways to build a functional healing pool, and one way to build an ammo generator. Thanks again. 
Enableable Trigger_changelevel: 
Make an info_notnull brush entity and give it values like this:
"map" <mapname>
"use" "trigger_changelevel"
"touch" "SUB_null"
"solid" "0"
"targetname" <name>

The trigger does nothing until it is triggered, upon which it becomes a trigger_changelevel.
Works by calling the actual trigger_changelevel spawnfunction in the use field, which normally crashes with most classes because they usually precache stuff there, but trigger_changelevel doesn't. 
Firing Stuff 
Premise: Set a monster's firing function as an info_notnull's use function to make it fire monster missiles of your choice.

Problem: All the monster missile functions require the self.enemy field to be set to the entity for which to aim towards.

Solution: Entity references in quake is really just a number indexing the entity in edict list. The player will always be entity 1. If you set the info_notnull's "enemy" field to "1", you'll get a entity that fires a missile towards the player when triggered. I'm sure you can, by looking through the edict list when you have completed the map for release, figure out what the entity index for any entity will be in your map, and so make it aim towards any entity.
For example, in the map I uploaded below, all the info_notnulls have "enemy" "7", which I found out through the edicts list is the info_player_start in this particular map. I think that your results may vary on this, as it could be that editors like to save the entity order in not exactly the same way every time, and also other uncertain factors.

"use" "OgreFireGrenade"
Fires an ogre grenade towards self.enemy.

"use" "CastLightning"
Shoots a shambler lighting bolt towards self.enemy.

"use" "hknight_shot"
Fires a single (just one) hellknight magic missile towards self.enemy.
Requires a hellknight to already be present in the level for the precaches to work.

"use" "ShalMissile"
Deploys a voreball that starts seeking towards self.enemy. I had some problems with this when it collides with un-alive things. Looked like it just disappeared without a trace.
Requires a vore to already be present in the level for the precaches to work.

"use" "Wiz_StartFast"
"health" "1"
Fires two wizard slimewotsits towards self.enemy. The health field is required because the actual function that fires the missiles checks if the scrag is alive first. (See below.)
Requires a scrag to already be present in the level for the precaches to work.

"use" "Wiz_FastFire"
"owner" <entity-ref>
Fires a wizard slimewotsit towards self.enemy. The owner field is required because this function checks that whatever spawned the missile (usually a scrag) still is alive first. Thus the owner field here must refer to an entity that is "alive". That is, it must have a "health" field set to anything non-zero. "owner" "1" should work, as that refers to the player, which usually is alive.
Requires a scrag to already be present in the level for the precaches to work.

"use" "boss_missile"
Fires a Chthon fireball towards self.enemy. This requires that self.enemy is alive (has health), or else it will start seeking after the player no matter what you intended. I tested this with a info_player_start as the target, and it worked once I gave it "health" "1".
Requires a monster_boss to already be present in the level for the precaches to work.

The result:
(Sadly didn't manage to capture the shambler bolt)
Map file: 
Third-Hand Information 
Kindly provided by John Payson and Fat Controller. 
Monster Weapon Firing 
That is genius czg, I'd triedsomething like this before, but that's much neater than my method was. One especially useless thing you can do with monster functions is add them to creatures that don't have that kind of attack. So you can have a knight with missile attacks by adding the function to the th_missile of the knight. Wiz_StartFast and ShalMissile work alright, CastLightning is a tad unfair, sham_magic1 is a bit better but causes wild animation frames after the attack until it goes into pain or melee attack.

You could combine this with additional hitpoints and possibly quad to make a boss monster type thing out of a knight. For those who've never seen it, adding a key of "armortype 1" and of "armorvalue x" gives a monster x additional hitpoints. Quad is accomplished by setting a key of super_damage_finished to something overly large, like 9999999. However, without some kind of visual cue your boss monster is different to a regular knight, it's not really fair on the player. Maybe you could get away with it if you used some of the effect flags, but I'd still think of this mostly as something to mess about with for fun, rather than something you'd want to include in a released map.

I've still got a few of these things I've not written up, I'm gonna look to making an example map for one, then I'll see about posting the details. 
Somethings I Forgot 
About the "use" "Wiz_FastFire" bit, there's a remove(self); call at the end of that, so the info_notnull will be gone when it fires once. It can't be fired multiple times.

About the setting "enemy" "1" thing to make them target the player, this obviously won't work with coop, as they'll only target the FIRST player. Also I guess when other players connect they'll be added to the end of the entity list (?) and thus be impossible to find the index for. (Might join at different times, before/after certain events that create/remove edicts.)

CastLightning is a tad unfair
The shambler lightning bolt could be used for traps, like having it fire across a hallway once every second so the player has to time a jump across. And also just for decorative purposes, as and alternative to the event_lighting setup. 
So. Hellspawn 
that fire off Shambler bolts? I am in evil mapper heaven. 
"classname" "monster_dog"
"armortype" "1"
"armorvalue" "999999"
"super_damage_finished" "999999"

/me imagines a monster_dog chasing the player around a level until the player finds a weapon and ammo cache 
A Few Quick Ones On Fatty's Site 
Logic Gates... 
In case some people haven't heard of this, there's an old trick discovered independently by various mappers to get more complicated logic into your entity triggering.

The basic concept is to create some box room off in the void, and put a spikeshooter, a func_door, and a shootable button in it. When the door is open, the spikeshooter will shoot the button, so if this "logic gate" will pass the message on to whatever the button targets. If the door is closed, the spike will hit the door instead of the button and the event gets blocked.

Use this the way you'd use an "if" statement in a scripting language. 
CastLightning Is A Tad Unfair 
I probably wasn't clear on this when I said it, but I just meant CastLightning is a tad unfair when you give it as an attack to a knight. It fires instantly without any warning or charge up so it's impossible to avoid. As it's own entity I'm sure it's fine. 
Great Thread 
All good stuff so far...there's one I'm wondering about though, maybe someone could explain it.

Remember zippie's 100b map 'stamppot' ? There was a teleporter you go through and you end up disoriented and your movement is all weird. I could be wrong, but I think it was more than just clever brush work/player placement. 
Sounds Like Your 
clipping into a HOM there (<--spelt it right that time) 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.