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) 
you didn't spell 'your' right :p 
The World Clearly Needs... 
... a 'crazy progs tricks' themed speedmapping session! 
"angles" key on the info_teleport_destination IIRC.
Either "angles" or "viewangles" or something like that. 
One Homonym At A Time 
my friend, and years from now I'll be a spelling God! 
CZG: Multiple Player Entities 
The first n entites are always reserved for players, where n is the maxplayers of the current server. So if you're running a 2 player coop server, an entity with "enemy 2" would target the second player. Not much use though, as in a single player game an entity targetting entity 2 is gonna be shooting at the origin - as the next entities after the players are bodyques, used to mark corpses when players die. As far as I know, there's no way to hack in any co-op only behavior, and even if you could, you certainly would have difficulty customising the map for the number of players.

That said, I'm looking at one tiny prospect in a function in items.qc for causing events to occur only in coop, but don't hold your breath. 
Double Post - But Coop Solution 
This is one big hack, it combines quite a lot of stuff towards one end, and one of the steps is extremely unlikely. It uses the player lightning hack, the logic gates and the use function. But what it does is creates a trigger that will be fired at the start of the map if it's single player, but will not be fired if the game mode is coop(or deathmatch). It's not as good as having a coop only flag, but it would let you alter the gameplay if it's being played as coop.

Ok, so, an overview of what's gonna happen first. We will build a logic gate to test for coop. The logic gate will not use any actual gates, it will just be a shooter and a shootable button. However, rather than use a regular spikeshooter, we instead use an info_notnull based on the player lightning shooter that will only fire if the game is not coop.

Ok, so, the stuff. Build a room away from the main map with a shootable button at the end. Give it a low amount of health, no more than 30hp. Give it a target of notcoop, this is the trigger that will be fired if the game is not coop : - )

Now for the more complicated bit. Make an info_notnull with these fields

targetname cooptest
v_angle x y z
use FireBullets

Then make another info_notnull straight after that with these fields

targetname cooptest
use W_FireLightning
nextthink 0.3
think CheatCommand

The second info_notnull should be in sight of the button, and the v_angle of the first entity should be the angle the second one needs to fire at to hit that button.

Ok, one more entity is needed to trigger cooptest, but it's important that this doesn't happen until the lightning info_notnull has had time to run cheatcommand. So the easiest way to do this is with another info_notnull, with the following keys

target cooptest
nextthink 2
think DelayThink

And that's it, not bad for four entities by my reckoning. Oh, you wanna know how it works? Ah, that's a good trick. CheatCommand is none other than that family favourite "impulse 9". Which happens to give the entity 200 cells, when before it had none. W_FireLightning requires the entity to have cells before it will fire. And in coop, impulse 9 doesn't work, so the lightning remains without any cells and doesn't fire. Seems I was a bit pessimistic earlier... 
A tried adding "effects" "1" to a func_door to what I thought was no avail. Instead, all I got was a glowing swarm-of-bees around the map origin. What was REALLY strange was that this "swarm" seemed to be responding differently to the various sounds ocurring on the map, i.e. shotgun blasts, rocket explosions, etc. O_o

P.S. Only in Fitzquake though :) 
Brush Models And Effects 
A brush based model such as a func_door will always have it's origin at the centre of the map when it's in it's natural position - ie the position it was in when you built the map. If it then moved down 64 units when it opened, then the centre of the swarm would also move down 64 units. So I'm guessing the effect was just being applied to the origin of the entity, which happens to not be anywhere near the door.

What you could do is move the door so that it's over the origin, then use an entity editor to move the door back to where it should be, by giving it a key of origin x y z, where x y z is the displacement to move it back into position. You may have to perform further editing to make everything work right. For example, when I just tested this I needed to add a trigger_multiple to set the door off, as the automatically generated trigger still lay at the origin. Things like not linking multiple doors may also help.

As to the weird reaction of the particles, I also saw this in fitquake080. I suspect that the swarm is reacting to other things that create particles, like gunshots/explosions, rather than the sounds, but something odd is happening. 
the particles are coming FROM INSIDE THE LEVEL!!!111 
Re: Double Post - But Coop Solution 
woah, rockage! ^_^ 
Dynamic Mapmodels And Overwriting Paths 
This thread's almost fallen off the page, so I thought I'd put a couple more things on here. The first is how to make a non static entity with a model. This is like the func_illusionary trick, but because the entity remains dynamic you can remove the entity later. You can also set angles on it, something neg!ke said wasn't possible with a func_illusionary.

The downside is that you have to mess about with modelindex to make the model display correctly. Make an info_notnull with these properties:

mdl progs/player.mdl
modelindex n
think SUB_regen
nextthink .3

Where n is the modelindex of the model you want to load. How does modelindex work? As the quake engine precaches models for the game, it places them into a numbered list. The modelindex of a particular model is it's number on this list. Index 0 is the null model, index 1 is the world itself. The next models will always be the brush models from the bsp, then the models precaches by the QC in the order that the models are first precached by the spawn functions.

This all makes it a big pain to work out which model has which modelindex. I'd recommend running the map through darkplaces or aguires engine, as these have commands that will display the list of models along with their modelindex. Be warned, the order in which models are precached may change if you alter the entities in your map. Also, different skill settings may have a different modelindex, so be careful.

On the plus side you can set all the things like frame number and angles without a problem, and even give the same entity a use function if you desire.

Ok, now for overwriting paths. What this does is allows a one time alteration of the path of a func_train. You can't toggle it back, and you can't switch it again to another path. But someone might be able to find a use for it.

Ok, here goes. To make the explanation simpler, we are going to alter just one point on the path, you can expand this to replacing multiple points and doing more complex things quite easily, it just takes more fiddling with triggers. Make a path of path_corners with targetnames p1 -> p2 -> p3 -> p4 -> p1. Then make the replacement p1 path_corner, making sure it is further down the entity list than the original p1. Give the replacement p1 the same targetname and target.

At this stage what should happen if you run the map is that the train goes between the first four points, the second p1 path_corner will be ignored. Now for the trick, add a key to the original p1 of

use s_explode6

Now, when you want to change the tracks, just fire a trigger that targets p1. This will run s_explode6 on the original point, which removes it in 0.1 seconds. The new p1 has no use function, so it remains. Why use s_explode6 instead of SUB_Remove? Well, just for neatness really, it's possible that you'll be triggering p1 from a touch function, and removing entities during a touch function can be dangerous.

That's the basic idea, anyhow, but you can do quite a bit with it, it's mostly how you set up the new p1. For example, there's no reason the new p1 has to target the same entity as the original p1, it could go p1->p1a->p1b->p2 and then back through the original path. You could choose never to return to the original path, do something like p1 -> q1 -> q2 -> q3 -> q4 -> q1. And then you could pull the same trick again with q2, switching onto yet another path...

You might be tempted to try this with monsters following paths as well. In theory this should work, but there is one problem. If you remove the point the monster is currently heading for, it'll start heading for the world origin and won't ever resume it's path. This doesn't happen for func_trains as they calculate exactly how far they have to move as soon as they start moving. Monsters have to hit the trigger of the path_corner, and constantly correct their course using the navigation AI. Bit of a shame, but there's not as much use for changing monster paths as func_trains offer anyway. 
How many of these tricks will become invalid when loading the map in a custom progs.dat, such as Nehahra or Zer? That's perhaps the only thing that might stop me from using some of these. 
Teaching New Progs New Tricks 
It's hard to say exactly how many would still work with a new progs. Potentially all of these could be broken by a new mod, if it was written correctly. But I'd say in the vast majority of mods, the vast majority of tricks will work. Like the use trick would stop working in only two circumstances; the mod completely rewrites the entity triggering system(which would mean you'd have to map differently for it anyway), or the mod adds a use function to the entity you're trying to use. The former would really only occur if it was some total conversion thing, and the latter is unlikely to affect info_notnulls.

I'd say that probably all of these tricks would still work in zer, and quite a lot of them in nehahra. As a rule of thumb, a mod that just adds content without changing the base stuff should accept these tricks. The more it alters what went before, the greater the chance something will fail, which is why zer should run them but nehahra may not. 
Just An Aside 
I know QdQStats will break the coop detection stuff, because it allows some of the 'cheats' in coop (for route planning purposes). 
You Know, 
having mapped for this game for a few years and all that, i thought it was really cool that there were so many tricks i never knew about. thanks for these-- i already found a use for the respawning items trick. ^_^ 
What do you mean by 'create an func_illusionary entity (=no brush!)'?

In BspEditor, there is no choice but to have a func_illusionary attached to a brush. This is where you can walk through what appears to be a solid wall.

If I use "model" and "frame" anyway, the model does not appear, just the brush. 
The idea is to make a regular point entity, and give it the classname func_illusionary, as though func_illusionary were a custom mod entity. In worldcraft, this causes problems as the fgd file says func_illusionary is a brush class. One way to get round that is to remove the definition of func_illusionary completely, as it has no parameters, and name both brush and point func_illusionary entities manually. I don't know how much of that extends to BSPEditor, but you may want to look at doing something similar. 
OK, so I remove the func_illusionary from the ents.qc and now I can't see it in the editor.

I then create a light entity and rename it to func_illusionary and add 'model' and 'frame'.

I have Qbsp on -verbose and see that a texture is not being found, and when I look at the map file, a texture has been added to the func_illusionary:-

"frame" "1"
"model" "progs\player.mdl"
"classname" "func_illusionary"
"origin" "0 0 0"
//"0000" "0"
( -8 8 8 ) ( -8 -8 8 ) ( -8 -8 -8 ) NONE 0 0 0 1.000000 1.000000
( 8 8 8 ) ( -8 8 8 ) ( -8 8 -8 ) NONE 0 0 0 1.000000 1.000000
( 8 -8 8 ) ( 8 8 8 ) ( 8 8 -8 ) NONE 0 0 0 1.000000 1.000000
( -8 -8 8 ) ( 8 -8 8 ) ( 8 -8 -8 ) NONE 0 0 0 1.000000 1.000000
( -8 -8 8 ) ( -8 8 8 ) ( 8 8 8 ) NONE 0 0 0 1.000000 1.000000
( 8 8 -8 ) ( -8 8 -8 ) ( -8 -8 -8 ) NONE 0 0 0 1.000000 1.000000

The actual origin of the entity is not '0 0 0' but I can now see the player model in-game where I set it in the map (not 0 0 0).

If I now try it again with "model" "progs/ogre.mdl", the engine gives an error of 'no precache' of the model for the func_illusionary even though I have ogres in the map.

Does this mean that the engine is seeing the func_illusionary before the ogre is precached, and if so, can I do anything about it without resorting to messing with the progs.dat? 
in the map file a monster_ogre entity must be placed before (are rather above) the func_illusionary.

i don't know about texture thing you said, but there must not be a brush assigned to the illusionary. try to delete the brush and set the { and } accordingly. 
I cut'n'pasted the func_illusionary to the end of the file and then ran Qbsp from outside of the editor (because the editor seems to change the order of things arbitrarily), but still no show :-( 
First off, I don't think that the brush info at the bottom should be there, but I can't say why it appears. Perhaps try deleting all those brush info lines from the map file to make it look like the other point entities then try a recompile. Then again, if it's working with a player model maybe that's what BSPEditor expects.

The precache thing I suspect is fixable. Precaches occur in the spawn functions of entities, and the spawn functions are called in the order that the entities are listed in the map files. So if your func_illusionary entity is higher up the list of entities than the ogres in your map are, then the ogre.mdl won't have been precached yet, even though one would be before the map loads.

So just make sure there's at least one ogre higher up the entity list, and that error should go away. 
Too Sloooow 
I took twice as long as neg!ke to say the same thing, never mind that post 
Ogres At War 
I'm not sure that this is interesting enough, but I'll post it anyway.

If you have a monster_ogre_marksman next to a monster_ogre, the end result will be 2 ogres that can get mad at each other. I don't know if any map uses this yet (or wants to use it) but someone might find a use for it...

This bug only works, because in the code, the classname isn't changed when it tells it to just put in a normal ogre. 
Didn't you play PuLSaRs Hellbridge recently? :)I think that on this map you can see some ogres fighting on skill 3. 
is it possible to make shootable doors? basically, you shoot the door, and it opens. then after a bit, it closes. ideally, whenever you shot the door, it would open up again -- even if it was in the process of closing.

i want to do something like the doors in q3's tourney4 map (pro-t4). 
You just have to set a health value (5 is in general ideal, i.e you can open the door with axe), and set wait at a positive value (-1 never return)... I think I did this for a secret area door hidden in a wall in my last map... I think other people here could confirm... 
Inertia (bis) 
I guess you understood I was talking about func_door fields there... ;P 
thanks! and yes obviously they are teh doors ;) 
What JPL described will work; however, shooting the door while it closes will not have an effect--you can only shoot it while it's closed. You could minimize this problem by giving it a very fast "speed" field, though. 
i just might do that, thanks 
about the trigger that can me touched by anything in #11:

i did it exactly like you said (btw it's multi_trigger), but i couldn't get it to work. in the test map i made it was supposed to just fire a trigger_relay with a message.
there were also some unknown bboxes with that shouldn't have been there and they disappeared when shooting them. they seemed to be related to the touch-trigger. 
As For Messages 
If anything that prints a message has an activator other than the player, the message won't be printed to the player.

You can see this at the end of terra5 where a trigger_counter counts the deaths of the fiends and wakes up chtohohothothton and prints some messages when they're all gone. However if you trick the fiends into jumping in the lava, there's a trigger_hurt there that kills them, and then the messages aren't displayed because the activator was the trigger_hurt.
Same thing with the logic gates you can build with trap_spikeshooter and doors in front of a button. You can't have the button print a message because it's activator is the trap_spikeshooter, not the player.

So I dunno if I'm quite following you up there, but if you are trying to prove a trigger was fired by something else than the player by printing a message, you should try something else. (Perhaps a light switching on of a door opening or something.) 
Yes, You're Right 
i thought it would be fine if not the trigger itself had the message but some other entity that is fired by it.
i tried it with a light then and it worked.

to have a message displayed, i guess i would have to let it activate another trigger which spans over the entire room the player is in at that moment, or something like that... 
gibs don't trigger it, either.
there goes my idea... :/ 
Monsters That Stick To A Defined Area 
I am not 100% sure this really does work or not, but I THINK that if you create a func_wall entity that surrounds a monster, and kill the func_wall when the level has loaded, the monster will stay in the same place as if the func_wall was still there, yet be able to see and shoot the player. If the monster has a jumping attack, then if it jumps toward the player, it will come out of the box and act as normal.

I am about 50% sure this works, as I remember doing this when I made apsp1, trapping some enforcers on a ledge. The func_wall may have been made from clips.

I've seen some other strange func_wall tricks used in other levels. RPG used some funny trick in one of his mini Ep1 maps, where there were some nights trapped apparently within func_wall brushes. that acted like statues, but came alive later in the level. I would be interested in how that works, RPG. 
holy fuck, does that work? :o can anyone check? i would, but, alas, no quake. :S

regarding the rpg trick, i think you could do it by using the func_wall with the model set, the killtargetting the func_wall and just teleporting in the real monster. 
Func_wall Trick 
restrincting a monster to one are are does not work like that. also, having a func_wall with the clip textures let's qbsp stop with an error message.

the rpg trick is achived through func_walls with skip textures, and then killing them when the monsters are supposed to become active. 
oh, of course you can making monsters stay in a certain area by sealing it with trigger_monsterjumps (that should have height and speed set to "1", so it's less obvious), for example. 
Posting Drunk 
the rpg trick is achived through func_walls with skip textures, and then killing them when the monsters are supposed to become active.

Exactly. Monsters behind func_wall made from skip (so it appears invisible), and then killtarget the func_walls when you want the monsters to activate. They suddenly "see" the player and come alive. 
As Demonstrated In Neg!ke's Recent Doggy Map 
As Demonstrated In Neg!ke's Recent Doggy Speedmap 
when are we going to see the speedmap session based on tricks from this thread? 
Are you using tyrann's skip tool, or as aguire built it into his compilers. I think I have the skip tool, but I remember Tyrann saying it had some issues so I have steered clear.

This thread is awesome by the way. 
I used Tyrann's skip tool. I've never had any problems with it. 
Bump For MW 
Been A While, Time For A Hack 
There've been a few hacks posted in the mapping help thread since this thread last saw light of day, so if anybody saved them it'd be nice to have them here too. Today we're going to see how you can safely remove weapons and ammo from the player.

I discovered this trick looking for something quite different. Doors that require keys compare their items field to the player's items, and subtract off what they find if it matches. So I was experimenting by changing the .items field manually, rather than setting the gold/silver key flags. You can make a door that only opens if you have quad for instance, but the problem is the quad items flag gets subtracted once you open the door. This doesn't affect the powerup, you'll still do quad damage for 30 seconds, but it removes the icon from your screen. And once the 30 seconds is over the flag is subtracted again, which causes an overflow of the items field and all the icons start lighting up - it's bad.

However, the nice thing about the door is that it safely removes weapons, as these are just stored in the items field. So the simple way to remove a weapon from the player would be just to have a door with an item set to that weapon's item number. You can also sum weapon numbers, and if the player has all of those weapons, it removes them all. Two problems exist for this niave approach:

One: Just removing the weapon from the player's item doesn't force the player to change weapons, so if they are currently using a weapon you want to remove they will still be able to use it until they switch away from it.

Two: If you're removing weapons later in a map, you may not know if a player found the grenade launcher or not. The removal is all or nothing, if the player doesn't have all the weapons you want to remove then none of them get removed and the door remains locked (also it sends the message "you need the gold key"...)

We can solve both these problems at once, whilst at the same time removing ammo from the player. The trick here is to use BackpackTouch to give the player all the weapons they need to open the door, then instantly take them away. At the same time, we give the player full ammo, then take it away with another BackpackTouch, this time with negative ammo counts. And when the ammo count is updated, quake checks which weapon the player should be using, so you won't end up using a weapon you don't have.

So, here's the entities you need to add. I'm assuming you want to remove every weapon except the axe(see below), which gives an items field of 128.
First, a brush based info_notnull with the following fields

touch BackpackTouch
think InitTrigger
nextthink 0.2
ammo_shells 100
ammo_nails 200
ammo_rockets 100
ammo_cells 100
items 127

Then another info_notnull with

touch BackpackTouch
think InitTrigger
nextthink 0.2
ammo_shells -100
ammo_nails -200
ammo_rockets -100
ammo_cells -100

Finally, add a regular func_door with

items 127

You want to ensure that the player hits all of these entities in this order, in as quick sucession as possible, and don't let them avoid any of them. So dropping the player onto the func_door through the other triggers is probably best. Putting the two info_notnulls on exactly the same region of the map is wise, as long as the one with positive ammo counts is higher on the entity list. If you still have problems, the following extra entity can help - an info_notnull with

touch teleport_use
think InitTrigger
nextthink 0.2

This trigger sets force_retouch to 2, which means all objects retouch everything next frame. Presumably this means you retouch it, which resets force_retouch again and over again while you stand in it. Oh well.

So, why is the axe exempted from this? Well, it's quite annoying really. There are sections of the code dedicated to what to do if the player doesn't even have an axe, and these all work well and good, but then there's one lazy line in client.qc that always switches you to the axe if you have no ammo, without checking if you have an axe first. Grrr. So you can't completely disarm the player, but you can get fairly close.

A few other things. One is the annoying messages saying "you recieved -100 shells etc.." that you can see in the console. Add an extra info_notnull in the same spot, with the following fields

touch powerup_touch
think InitTrigger
nextthink 0.2
noise misc/null.wav
netname \n\n\n\n\n

This spams some newlines so the messages are only visible in the console. Creative types might include a message here explaining where all your weapons went. 
And A Final Word Or Two 
I split up this post, since it was getting quite long. The trick relies on just the function door_touch, so you might feel using a full blown door is overkill. Couldn't we just make a further info_notnull with touch set to door_touch? Well, yes and no. You can do it, and it's obviously nicer in terms of level design to remove weapons with a hidden trigger, but it's more work than you'd think. The code for linking doors means that you'd need to set the info_notnull's owner field to point to itself, which requires mucking around with entity numbers. Just using a door simplifies the explanation, and keeps the focus on the trick to remove the weapons, rather than the fiddly details of faking a door trigger.

My final comment is, after all that, it is possible to make a door that opens based on having certain items, by adapting some of the tricks here. For the purposes of this example we will use a red armour(items bit 32768), but it should work for powerups too.

The important thing here is that you know exactly what flag is being removed by the door, so you can add it straight back on with another
call to BackpackTouch. The difference here is that we don't spawn the trigger until after the door opens, and we use the teleport_use function to force the player to retouch the newly spawned trigger. I guess iD didn't see Init_trigger being used outside the spawning sequence, as it would make a lot of sense just to put force_retouch 2 into that piece of code. Still, we make do, here's the deal:

Add a func_door with

items 32768
target restore

Surround that with a larger brush info_notnull with

touch teleport_use
think InitTrigger
nextthink 0.2

Finally add an info_notnull again larger than the door with

touch BackpackTouch
items 32768
use InitTrigger
targetname restore
netname \n\n\n\n\n

Notice that we call InitTrigger with use, not with think. The netname is for neatness once you open the door.

The door will always give the message "You need the gold key", this is hardcoded and unavoidable, plus quite misleading for the player. So you'll also want a trigger_multiple spamming out "You must have red armour to proceed..." on the door. Remember to remove it once the door opens.

A final word of caution, be careful how you impliment these into a map. The player cannot lose a key, so it's always possible to progress. The same is not true of armour, or even less so a quad. So what do you do if the player takes the armour, but doesn't get back to the door with any left? Should that be game over? And if so, can you at least automatically tell the player they've failed (perhaps an exercise for the enthusiastic reader, how to use this hack for a general armour detection trigger rather than a point check at a door. The corresponding check for a powerup is much easier :-) )Perhaps the best thing a door like this could be used for is not allowing them forward until they have a certain weapon...
And that brings us full circle I guess. Have fun! 
am i right in guessing that would work for runes? they have bitflags, iirc, so you could use those for extra keys..? 
Not Exactly 
The runes don't actually set anything on the player, they set the bits of a global float called serverflags. So this can't be caught directly by a door. There is a roundabout way of using runes to trigger things, but it involves a system of "logic gates". You have a trigger_multiple at the door that targets the following info_notnull:

use func_episodegate
spawnflags [1-15]

This info_notnull is positioned as a blocker in the first logic gate. This is then inputted into a NOT gate that will target the door open. Kinda round the houses though, as you could basically do the same thing by using a spawnable trigger for the door (using the info_notnull hack) that is spawned when you pick up the rune.

However, it is still possible to make extra keys, they just won't have an indicator on the HUD. Simply use item flags that don't indicate any weapons. 128 represents IT_EXTRA_WEAPON, so it's unused. You can also go a few powers of 2 higher than 4194304(IT_QUAD). So just making a BackpackTouch that gives you one of these dummy items will give you a new key.

The main edge this method has over the two ways of doing runes is that it'll work properly in coop, ie. only players who have taken the key will be able to open the door. The downside is that if they die, the key may be lost forever, as the BackpackTouch works only once.

The way round this is, strangely enough, to use the actual key_touch function instead of BackpackTouch. Just set the items, netname and noise as you desire, and it'll just work.

You'll probably need to have a seperate entity to represent the key visually, that gets removed when the key_touch info_notnull is fired, but not in coop mode. So that's a combination of the coop trigger hack, and one of those dynamic func_illusionary things from the mapping help thread. Phew, and all that to get things working in coop.

If you don't care about coop, you might as well just go down the route of spawning the door's trigger when you "pick up" the key, it's easier and fewer entities for the same result. 
Quick New One 
For those of you who want to emulate Half-Life, here's how to make monsters mad at one another. You really need to script fights carefully though, you aren't creating alliances between groups of monsters, you're just selectively annoying them as if they shot one another. So after they kill their one target, they'll just stand around unless attacked again, even if others are fighting.

Perhaps a good way to choreograph a bigger brawl would be something like
ogre 1 gets mad at fiend 1
fiend 1 gets mad at ogre 2
ogre 2 gets mad at fiend 2
fiend 2 gets mad at ogre 3
fiend n gets mad at ogre 1
that loop should make sure everyone fights.

Anyway, getting ahead of myself, what you do:
Set up your monsters, run the map, type edicts in the console and note down the entity numbers of the monsters you want to fight.

Add a brush over each monster, and convert to info_notnull with the following settings

owner n
use InitTrigger
targetname que1
touch spike_touch

where n is the edict number of the monster you want it to get mad at.

Then two more triggers to set the thing going, a trigger_once with target que1, and an info_notnull with

use teleport_use
targetname que1

In fact, this is such a minor thing, you could even tag it onto the info_player_start you use and save an entity.

Of course, the way it works is that the triggers behave like a nail fired from the monster in the owner field into the target monster, so it gets mad according to the infighting code. You don't have to use trigger brushes, spike_touch and teleport_use if you don't want - voreball and ogre grenade explosions set off from point info_notnulls with owner set have the same effect, if more dramatic in execution. Be warned, this will fail on monsters of the same type - for a minute there I used two knights to test it and thought the hack wasn't gonna work! 
New Style Trigger? 
I want a trigger_once that is not 'switched on' for use until some other pre-defined action has taken place; perhaps by a monster dying or a button being activated. This trigger will be in an oft' used area and may be 'touched' many times before I want it to become a trigger_once. The player must remain unaware of the trigger.

I don't want to use doors or buttons, or add any extra brush work, so no 'logic-gate' scenarios.

Is this achievable through some clever use of the trigger_once fields or spawnflags. Or will I need to resort to QC? 
hmm, on a second thought i always used
"use" "trigger_once"
"touch" "SUB_Null"

probably just another way (without apparent downsides). 
Thanks for the speedy reply, I'll get on to it. 
Great stuff! 
Surely logic gates are a better choice than creating a new progs.dat for this one thing.

But I am curious to know if there is a simply one-entity hack to do this; that would be useful. 
I must have had this page open for like an hour before commenting :P 
Metlslime, Maybe... 
...I can open a .qc file, fiddle with it and recompile in less time than it takes me to build brushwork. My editor compile GUI can then re-run the map in one click with -onlyents selected to run the map with the new progs.dat in about three seconds. So, apart from the fact that I'm not too good with QC, I would find it easier.

My map will have to have my progs.dat to play as it has a mixture of monsters, so again, it is easier for me.

But I am not a 'wheel inventor' so the notnull thing suits me fine.

Having no professional interests in gaming, programming, IT, web-design etc, all of this mapping lark is just a bit of fun that takes an hour or so of my time every other day when I'm at home. And I enjoy poking around in Quake's inards even if I get lost every now and then:-) 
Killable Cthon By FrikaC 
FrikaC posted a killable Chthon on I3D: 
Invisible Monster Only Barrier 
Ok, this DOES work. He's how to make an invisible barrier that stops monsters but not players. This only works for monsters that don't swim or fly, and if the monster jumps or is pushed, they may pass the barrier.

First build a 32unit high step where you want the barrier to be. Apply a regular solid texture to the brushes. Now make a clone of this brush and position it above the existing brush. Make it 64 units high - it can actually be as high as you like, but lets use 64 units for now. Apply the clip texture to this. Select both brushes and make them into a func_wall entity. Now move the whole thing down into the floor slightly so that the solid brushes are 16 units below the floor (if this doesn't work, try 8).

Compile the map and run it in Quake... hey presto! The monsters should be stuck behind the barrier. Hopefully, you should be able to walk through the barrier without problems.

Turns out I used this weird trick in apsp1 after all. It was reused twice in dm3rmx when I rediscovered how it was done, though I killed the barriers in that to allow the monsters to pass after a certain time. 
Here is an example map of stupid test things which happens to also contain the trick I mentioned in the above post:

Ignore all the stupid shit I put in there, and just watch how the enforcer won't come out of his little box. Try the same thing with a fiend... you'll be in for a shock. 
You are simply a one-man repository of l33tness. This'll come in big use with my base map =D 
Monster Barriers... 
A trick I use is even simpler -- players can cross any gap in the floor that is 32 units or less across, becuase they have a 32x32 bounding box and use hull1 to do their collision.

Monsters, on the other hand, use hull1 or hull2 for collision, BUT they use hull0 to do their pathfinding. Since there's a gap in hull0, they think they can't cross it. So just like cattle guards at the entrances to pastures, you can simply put grates or other gaps where you want the monsters to be blocked.

Gratuitous cattle guard picture:

And an example in antediluvian: 
Nice Metl 
That's pretty nifty. They will come at you one the floor is "filled" like with a func_door, right? 
Killable Chthon With Map Ents

FrikaC explains how to make a Chthon that can be killed by the players weapons rather than electrodes, without doing any qc coding or using another progs.dat 
very well written, too. Helped me understand certain aspects of the coding process more intimately (though we're still 'just friends' at this point).
But since I can't test it, I'd like to clarify one thing... he won't pop out and start going? almost immediately after starting the map he'll begin tossing his loud fireballs around? or am I confused? 
is there a way to make a monster invulnerable until a certain point, at which he'll become vulnerable to weapons/lighting/smooshing? 
Temporarily Invincible Monsters 
this is possible. simply add a "invincible_finished" "#" field.
the awkward thing is that the # seconds start counting down when the map starts, so events involving such monsters have to be carefully planned. 
Hay Guys 
i hear that FrikaC has a way to make a killable Chton without quake-c? or was it marcus sklar. . . 
No No... 
you're thinking of that level from 1997, called "THEFLY" or something... I think it was by this guy Marcus Klar... 
no way to trigger it huh? that takes alot of the fun out of it... 
I know this is probably getting annoying, but how do you get monsters to drop weapons/ammo? when making a floating weapon, do you simply place it on a func_wall and then kill it upon starting the map? Any other "widely known" hacks? 
as far as i know, you trigger this cthon the normal way. I'd have to re-read the tutorial to be sure, though.

And yes, you kill the func_wall immediately after map load, using a trigger on the start point or something. At least that's the traditional way to do it. I wonder if this would work instead:

"classname" "func_wall"
"nextthink" "0.1"
"think" "sub_remove"

or would that not work because func_walls already have a think function? 
A func_wall has no think function, so that would almost work as it stands. The problem is that the items will not have been dropped to the floor by 0.1 seconds in, so you'd remove the func_wall too soon. Setting nextthink to 0.5 would be safe(items drop at 0.2 seconds in), and probably won't be seen by the player anyway. 
Cool, so that would work.

I much prefer a clean hack to a messy hack. 
...hiya, I'm at the stage where the only thing left to do in this map before release is to enable a switchable ambient sound (ambient_drone). Is this doable via an info_notnull hack? It only needs to go from 'on' to 'off' once. I can't really afford to use brush entities as I'm a bee's thingy from the markedgesurfaces vanilla limit.

Thanks in advance. 
First | Previous | Next | Last
Post A Reply:
Website copyright © 2002-2017 John Fitzgibbons. All posts are copyright their respective authors.