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
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. 
Not So Loud 
Yeah, it's fairly doable. You won't get the same sound attenuation as with a normal ambient sound, it'll just be like a door or platform, but other than that it works well. These fields on an info_notnull:

noise1 ambience/drone6.wav
noise3 misc/null.wav
think plat_hit_bottom
nextthink 2
targetname noisebegone
use fd_secret_done

plat_hit_bottom and fd_secret_done are functions that play noise1 and noise3 respectively and not a lot else. The usual notes about making sure something precaches these sounds apply - ambience/drone6.wav is precached by an ambient_drone and misc/null.wav is precached by a platform or door with sounds set to 0.

If you don't have a door like that already and can't include one because you're close to the limits, then you can terminate the looping sound with any other non looping sound. So if this represents the power going out, you might want to have an explosion to punctuate it. enforcer/enfstop.wav and one of the lightning gun sounds would also probably work nicely here. Otherwise just try and find a short, quiet sound like a ricochet so it's not noticable. 
Many Thanks Preach... are the bomb. Now, are we going to progress that Mechanised Enforcer Weapons Platform any further? Asaki is finishing up the code, I just need to know if you are going to make the wish list of skin and model mods. 
Found By Accident 
while searching for a way to let Shallrat breach some vorebabes I thought it might be good to look for the multigrenades qc
They have the same second subroutine I need.

I saw the earthquake.qc and wondered if it wasn't possible to fit it in Quake1 without the DOE pak.
And to my surprise it worked.
There may be a strange target t2 in the map but for I can see it works. 
nice work, but this thread is about NOT changing qc code, but instead using the bsp file to create ususual features. 
out of toppic, sorry my enthousiasm.
I'll try to relate to the general abuse.

Maybe better then creating a new toppic.
Sometimes it harder to find the wrong toppic with a right idea then,

Objects That Selectivly Clip 
We're going to learn a new field we can add to almost any entity to change how it blocks other entities in the game. And that field is

owner n

Where n is the number of the entity that you want to "own" this entity. What does this mean? Well, it's easiest to understand by example. When an monster/player fires a projectile, the owner field of the projectile is set to the firing entity. This means that the two object will no longer clip or touch, they ignore each other for all collision purposes. The purpose is so that your own rockets don't explode on you as soon as you fire. Side effects include that you can't use a vore's own voreballs against it(directly).

So, what can we do with this? Well, you can set it on almost anything(doors being the big exception that already have owner specified in their own code). If you set, say, a monster's owner to 1, then it'll be noclip to the player. Kinda stupid, but cute, especially if you do it to a knight as it leaves them incapable of attacking you. You can't hit them with hitscan weapons, but you can get them with nails. This is because a traceline is in some ways a collision between yourself and the target entity.

So that's neat but not all that useful. A better use would be to have monsterclip that only clips selected monsters, like I suggested in mapping help. But surely you can only set the monsterclip to have one entity as it's owner? Yes, but that's the wrong way round to do it. What you do is make it so that all of the monsters you don't want to clip against it have the monster's owner set to the monsterclip. It's a symmetric relationship, so now all those monsters will disregard that one entity. Of course, they'll still hit all the other monsterclips in the map equally. You'll have to place them so that all the monsterclip they are likely to encounter that you want them to ignore is grouped as one entity.

The owner field might suggest that there's some kind of hierarchy going on here, but it's not the case. If the ogre has the player as an owner, and it's grenades have the ogre as their owner, the grenades still clip against the player. So you're basically limited to one link per object, it can be noclip to one entity of it's choice, and as many entities as you like can be noclip to it. The trick is to use the limited resource as creatively as possible.

What else could you do with this? Well, probably some good(evil) traps, shame this wasn't about for the speedmap pack last week. You could add HL2 style combine force fields that the player can't move through but the monsters can. I'm sure other people can think of things I can't. Maybe you could do something really clever for a coop only map, where player 1 and player 2 (entity 1 and entity 2 on the map) aren't treated symmetrically? It'd be cool to hear people's ideas. 
Sounds Awesome 
Preacher, you are the don of hacks. That one sounds particularly prime though, and it will get used. 
Levitating Enemies 
how about a shalrath (or shambler?) stood on an invisible func_train that only it can touch - either flying around a room and landing now and again to use its normal walking movement or else with a series of func trains causing it to jump around like in nehahra or the end of azure agony. 
Here's something I just came up with.

Don't you hate not getting 100% kills due to the infamous monster_fish error? Well this doesn't stop the fish being counted twice, but you can manually increase the killed monsters count. Create an entity with these properties:

classname info_notnull
use boss_death10

Trigger it and the killed monster count will magically go up by one. BTW this method also kills the info_notnull, so you'll need one for every fish in your level. I suggest making each fish target one so they automatically call it on death. 
Fish Frag Count Fix 
Awesome hack Omus. I've always waited for something like this, and it works like a charm. 
Nice Find 
though on the other hand, it will screw up the monster count if playing with a fixed progs.dat 
A Very Basic Trick 
It's very likely that most of you already know that...

You can manually set the skin field for any regular Quake monster. This, combined with the armorvalue/armortype and super_damage_finished tricks can lead to some new mini bosses (like a super shambler, for instance). 
It's Very Simple, Actually 
Assuming you have a soldier.mdl with 2 skins (0 is regular grunt and 1 is your boss grunt):
"classname" "monster_army"
"armorvalue" "1000"
"armortype" "1"
"skin" "1"
"super_damage_finished" "9999"
His shotgun will deliver 4x the normal damage, but without the quad damage sound. And this sucker can take more than 1000 hit points.

The idea can be extended to any regular monster. 
Useful, But... 
If you have new skins you to include external files for the custom model right? In that case you might as well create a custom progs and run it as a mod. 
Not Necessarily 
A lot of modern engines support replacement model textures, and these can be used to add skins to a model that doesn't have them. 
can you replace skins that don't exist in the original mdl? 
Odd Occurance, I Noticed 
some months ago I was dicking around with Air Quake source and Dark Places with the intention of making some high(er) poly md3 models for it. I added a func_model type entity to the Air Quake source, designed a bouy type model and texture to test it with, and I added it to a map.

The md3 model showed up, but the texture didn't. I tried the various recommendations in the vast DP literature, and none of them worked to bring the skin in.

So I then converted the model to a Quake mdl, and indexed the colors of the skin texture to the Quake pallette. It showed up in game perfectly, not the mdl model, but the md3 and the md3 skin! So, apparently you need to have an mdl version for DP to recognize an external
I'm not sure, but I think you can from QC request skins/frames from ext texes that don't exist in the 8-bit mdl/spr.

Of course, it won't work so well then if you disable ext texes or don't support them. 
I see about the engines allowing external skins, and metlslime, I imagine you would use some sort of naming convention (eg: wizard_skin00.tga, wizard_skin01.tga) to support multiple additional skins in these engines.
Still, you have to include these new files somehow. I have always imagined these map hacks were useful mainly for maps that you don't want to bother zipping up properly or include a readme (speedmaps) or maps you want to run on vanilla Quake with no extra assets.

HeadThump - I know that with md2 models and some engines, you have to preserve the original paths of a model (where to look for the skin is hard-coded in the model). So if Quake 2 installs a model at: models/monsters/gladiator/tris.md2 (model) models/monsters/gladiator/gladiator.pcx (skin)

... you have to rename the files (the skin at least) and preserve these paths under a Q1 mod directory. The same may be true of Q3. 
Oh Yeah.. 
.. sounds like when you converted your md3 to mdl, it was able to find the skin (treating it as an external skin) because mdl models aren't as fussy about paths. 
Thanks Omus 
It's been a while since I visited my little project, but I think I'll see if that possibilaty is the case.

I checked the paths at the time to see if they matched up, but I may have only done so relative to the mod path and not the models internal structure, thus missing a crucial subdirectory. 
I Guess... 
the thing I'm worried about is that "replacing a texture that exists in the mdl" might be a feature of a number of engines, but it seems completely up to chance whether each implementation happens to work even when the texture isn't in the mdl file.

So you could try it, and it could work in some engines, but who knows which ones. 
If you have new skins you to include external files for the custom model right? In that case you might as well create a custom progs and run it as a mod.

Yeah, but the thread theme is about making new stuff without new progs.dat, so I believe it's still on-topic :). 
Player Weapon Damage 
Can I increase it with superdamagefinished as for monsters? If so how - because it'll need to be set for coop as well. I'm guessing this will be more difficult than a standard monster hack . . .

The idea is to boost the players close combat attack to make it a viable alternative to the SSG and not just the SG. And make it a choice against tougher creatures, since I've omitted knights from my pack.

I reckon about the same damage as a rocket, so two hits would kill and ogre, four a shalrath - though I'd have to playtest alot so as not to unbalence the game. 
Not Without Modifying The QC 
Also, quad wwould affect all weapons, not just the axe. 
Ah Well 
It was just a thought, maybe for the next time. It�d also affect alot of things, eg. it�d be easy to lose ammo backpack pickups by gibbing too many monsters. 
Any way to use stuffcmd in a map ent?? 
it is possible in Quoth Pack. Just use info_command or trigger_command, and and your command in the message field. Maybe you should ask Kell or necros for further details. 
Which Brings Me 
to a bug in info_command in Quoth; there should always be a newline "\n" at the end of the string, otherwise the engine might not execute the command properly.

The Quoth doc doesn't include this information. 
I want to do a coop map. It would be nice if there was a way to broadcast a message to all players (like "the gate is open"). The closest thing I could find is ClientDisconnect(), but that still bprints "left the game." after the message that I put in .netname. Is there some way to hide that 2nd message? I tried flooding it off the screen but it didn't work. It just moves my message up on the console. 
Sorry. I Meant ClientConnect() 
sprint() ? 
Umm... bprint(), sorry 
Not Sure What You're Asking, Lardarse 
Bprint is broadcast print, no? 
Not An Easy One 
I don't know that this one is possible. What you'd really want is a function that has the .netname bit printed *after* the rest of the text, so then you can newline all the previous lines away. However, assuming there are none in the monster files, the only such examples are in the clientobituaries, and only in the messages for client vs client deaths(for example: telefragging). So I don't think there's a way to hack those in. 
Thanks, Preach 
That's about what I figured. Just wanted to check with an expert. 
Map is a group of some of the tricks found here and other places. I use it as a way to remember those info_notnull tricks. Please give it a look
and email if I missed something good. 
Sounds Cool - Will Check Out L8R 
Maybe it is my winrar, but I get a corrupted file. 
Zip Format 
That download seems unbelievably slow, can you put it on shub-hub or something? It stalls at 1% here repeatedly. 
Last Try 
Thats Mad!! 
I dont know how usefull it will be, the toggleble trigger_multiple could be a usefull reference. Also the pentegram of lightning - I had a look at the map file in notepad, and it didnt really make sense to me how you managed to get all of the correct angles for each lightning bolt, but I'll have a look at it later again!!

Good idea. Comments:

- can you make all doors wait -1 or remove them?
- can you use a uniform texture theme?
- func_train message is misplaced
- could you make the messages more descriptive?
- perhaps use floor switches, those posts are a bit in the way.
- perhaps add breakables?
- add Than's moving floor gun turrets?
- add glass?
- make trigger_multiple and triggered lights more obvious?
- add monsters dropping guns, or alternate ammo

Quoth demystifies many of those things, luckily, like respawning items, custom traps, and hordespawn. Plus more nice things. No moving water or statues though. 
Fiends And Low Ceilings 
I've just thought of a trick that might not work, as I haven't been able to test it. It also requires Quake 1.07 (I think all custom engines these days are derived from 1.08)

If you set the "gravity" field on an entity, the effects of gravity on it change. 1 means normal, 2 means doubled, etc... 0 is taken to mean 1, otherwise everything would not be affected by gravity by default.

So what can be done with this? Well, in theory, any monster that jumps can be made to jump further (or not as far). Unless you're using trigger_monsterjump, which is configureable by the mapper already, then the use is really limited to fiends. Giving them a gravity setting of about 1.2 may help to make them more effective in indoor areas, by making them hit the ceiling less.

I'd be interested to know if this actually works... 
Semi-random Monster Placement 
You can set multiple teleport triggers on each monster entity, and randomize by using Fitzgibbon's patented shooter trigger randomizer, or make the teleporters trigger at different locations depending upon the route the player decides to take. (HeadThump replying to Ankh in another thread)

Can anyone explain this one for me? 
Hey Lardarse 
Give me a few minutes and I'll construct a simple map that illustrates
the second method, the first method with the logic gates is a bit more complicated and I wanted to make a fairly playable map to illustrate it. 
Here You Go,

This example shows how to place teleporters for a creature to have alternative routes depending on the route a player takes. The creature here is hidden inside the center block, and all the relevant entities are close by that area. 
Oh, And Here Is The Second Version

I added a crude logic gate to the original map that will give one of four results, two telefraged creatures, one telefrag and one creature, or two more creatures in addition to mr tough stuff from the first demonstration.

It isn't difficult to refine this technique to suit your needs. Look in the extra box room to see how it is done. 
Re: #11 And Monster Triggers 
Is this safe to use as a door opening trigger? I know that doors will create their own triggers, but it's too large for my purposes... 
Re: #148 And Fiends In Low Ceilings 
While this trick does work, it's not really that necessary. Using one of the equations of motion:

v*v = u*u + 2*a*s

and rearranging for s (distance)

s = (v*v - u*u) / (2*a)

then plugging in the relevant numbers: u (start velocity) = 250 (we are only concerned with the vertical here); v (end velocity) = 0 (when you reach the peak of the jump); a (acceleration) = 800 (due to gravity); and you get

s = -39.0625

Now add the height of a fiend (88), and see that it will miss a 128-high ceiling by just less than 1 unit. Except for 2 small problems. Firstly, the qc adds 1 to the z component of the fiend's origin juszt before it jumps (so it will brush the ceiling very slightly), and secondly, it's possible for v_forward (the direction that fiend will jump in) to have a z component (if the player jumps at the right moment).

Still, it's something more to play wih... 
Monster Triggers 
It should work as long as you don't want a message for the player on that trigger. Just remember that firing nails through the trigger will also op - not just monsters. 
Good To Know 
But I decided that it's not worth spending the brushes on in this map, so I'll save it for next time... 
Mind The Gap 
Probably obvious from Preach's post but just as a reminder:
Monsters don't cross gaps in the floor and more often than not this is a disadvantage. Apart from monsterjump triggers, this can be fixed by filling the gaps with skip-textured func_walls which have their "owner" fields set to "1" (player), so they're invisible and don't block the player's projectiles but allow monsters to walk on them.
The downsides are that they block monster attacks (unless the monsters' owner fields are set to the entity number of the func_wall - however, then they won't be able to walk across the gap, I think) and also coop players' projectiles. 
More Doors Stuff 
Is it possible to make a door not open until it's touched? I imagine the obvious way is to make a trigger brush 1 unit wider than the door, but I was wondering if there's a method that doesn't use any additional brushes apart from the doors. 
I Think So 
"touch" "door_use"
and give it a targetname so it doesn't spawn a trigger

that's a good idea to save models, actually. does it work? :) 
Hm, No 
the triggers automatically spawned by doors don't have models, just bounds.

and door_use will only work if you set the door's owner to itself. I think. Shit, I don't know, I'm posting from work and browsing the progs src on inside3d, don't listen to me. 
The trick here is to start with a func_wall, not a func_door. Add the following keys:

touch door_fire
state 1
speed 100
pos2 'x y z'
owner *edictnumber*

where pos2 a vector describing the offset that you want the door to move by, '0 0 128' makes it open upwards by 128 units. You need to set sounds using the noise1 and noise2 fields, and precache those sounds elsewhere. The wait and speed fields work as before.

One weird trick you can do with this set-up is to set pos1 to a different vector. Then when your door closes, it will go to a position offset from it's original location by the value of pos1. There might be one other nice thing you can do, but I haven't quite worked out the details yet, will post later if anything comes of it... 
While you're at it, how does one make a secret door that moves up first, then in the specified direction? 
I should have added to the above post that *edictnumber* needs to be replaced with the actual edict number of the func_wall - in other words you need to make the func_wall its own "owner".

To make a secret door move up first, and then in the direction specified, I think that setting the SECRET_1ST_DOWN flag and then setting the third component of the angles vector to 180. Remember that map editors only give you y axis control(apart from the up/down hack) in the angles field so you'll need to put this angle in with a text edit.

The aim of this is to set the angle such that when you perform makevectors on the angle, the V_UP vector points downwards. Since the first two components specify the V_FORWARD vector, I'm pretty sure the last one then just rotates the V_RIGHT and V_UP pair about that vector. If the angle has no pitch(x component) then V_UP is straight up when the roll(z component) is 0. It makes sense that changing that to 180 would invert it. 
Owner And DP 
It seems the owner hack doesn't work in DP - at least with my button-gugattack setup. 
Are you use that you've specified the correct entity number? It's not a hack per se to make something the owner of itself, that's what a regular door does as long as it's not linked to any other doors. The only hack is specifying a number in an entity field. 
My Bad 
I guess the way I used it doesn't work in any engine. I had the edict number of a shootable button assigned to a Gug in order to prevent him from accidentally fire it with his bile attack. It seemed to work in BJP but I just tested it again and in fact it doesn't. 
That's because the gug's bilebomb will have a different entity number than the gug itself, and so the number in the button won't make any difference. There's no hierarchy of ownership in quake, if A owns B and B owns C, then A and C can still collide. In addition, blast radius attacks still hurt the owning entity, the main idea behind the ownership is so that the projectile can be spawned inside it's owner without it blowing up from the contact. It's actually quite a neat way of preventing out of bound glitches with the projectiles. 
How To Do #101 In Reverse? 
And by that, I mean an ambient_drone from off to on. Any ideas? 
You obviously tried swapping the sounds around from that same solution? 
Let's just blame that one on lack of sleep, shall we? 
Turning On Ambient Sounds 
Works with the standard sound hack.
A trigger with "use" "train_wait" and "noise" "ambience/drone6.wav". It will start looping the sound after being fired (the sound has to be precached). Afaik, turning it off again is not possible, though. 
Don't Forget 
once the player moves out of range of the new sound, it will no longer be looping if the player goes back into range.

it's unfortunate, but afaik, there is no way to have a true ambient sound be customizable. it can only be hard-coded. :( 
Surely you can use trigger_relays to force the ambient to start every 5 seconds (or at some multiple of it's length). Sounds a little bad if you hear it suddenly start, but it will keep it playing... 
you get clipping artifacts when the sound restarts, since even if you made the sound loop perfectly, quakec is not going to reliably time the cut at exactly 5000ms or whatever. 
It does keep looping infinitely regardless of where the player goes. 
#16 - How does that work exactly; could you post an example entity? Is it also possible to override a monsters existing th_missle function, e.g. to let scrags shoot voreballs and hellknights shoot Chthon etc? 
because the th_ functions are set in the monster spawn functions. you'd have to 'build' the monster you want from scratch and then modify from there. 
"build" in quakec or in a .map hack? 
Is It 
similar to how does one build a killable Chthon with info_notnull hackery? 
i was referring to the post a little while ago about building a monster with an info_notnull 
Megahealth - More Than A Short-lived Pleasure 
As we all know, having large amounts of health can never be wrong, but unfortunately the Megahealth item doesn't like us to be enjoy our surplus very long. Time to change it:

"classname" "info_notnull"
"origin" "# # #"
"think" "PlaceItem"
"nextthink" "0.2"
"touch" "health_touch"
"healtype" "2"
"healamount" "100"
// up to 250
"maxs" "32 32 56"
"model" "maps/b_bh100.bsp"
"modelindex" "#"
"noise" "items/r_item2.wav"
"targetname" "mh"
"killtarget" "mh"
"delay" "0.1"

Now, what's so special about this? The killtarget actually prevents the item from rotting down to 100 like normal Megahealth packs do. This way, nothing will be wasted if one doesn't engage in battle immediately.

You could also do this at map start, for example, by creating an info_notnull brush entity with the same fields except "maxs", "model" and "modelindex", and changing "think" to "InitTrigger" 
Doom-style Backpack Full Of Ammo 
A neater way (for some situations, e.g. secrets) of using the BackpackTouch hack mentioned earlier in this thread:

"classname" "info_notnull"
"origin" "# # #"
"think" "PlaceItem"
"nextthink" "0.2"
"touch" "BackpackTouch"
"model" "progs/backpack.mdl"
"modelindex" "#"
"ammo_shells" "20"
"ammo_nails" "50"
"ammo_rockets" "10"
"ammo_cells" "25"

This will create a backpack that looks and behaves exactly like those the monsters (or players in DM) drop. Of course you can also put some weapons in, with "items" "#" and "netname" "Weapon name". Just don't squish the sandwiches, though. 
Ooh, love the backpack idea! Neat stuff, negke! 
couldn't you just killtarget/target a regular MH pack? why does it have to be a notnull for the trick to work? 
Indeed you could.
The info_notnull just lets you set custom heal values. 
For reasons that you will probably not understand even when explained to you, you should make the nextthinks in the above two hacks 1.2 and not 0.2 
Well, Try It Anyway 
I thought items are spawned/drop after 0.2 seconds. I've never encountered problems with this value anyway. 
I thought it was 0.1 so, yeah, this should work... 
0.2 After The Spawning Frame 
But time starts at 1, not 0 
Scripting Languages Besides QuakeC 
Has any work been done to incorporate, say, Lua into a progs? 
The Horror, The Horror 
I wouldn't recommend it.

AFAIK it wouldn't be difficult, but Lua gets messy over time and, to me at least, is harder to debug than qc. 
Other Langs In Quake 
The reason I ask is because I love programming in highly-expressive languages, specifically Scheme and Haskell. I know Lua isn't "all that", but something nicer than QC would make me happy. After all it's a hobby, and hobbies should be f.u.n.! 
Haskell is pretty fun. Studied it in the first year of Uni up in Edinburgh. Phil Wadler, the designer of Haskell was the lecturer, and I'll never forget the first lecture, when he tore off the shirt he was wearing to reveal a t-shirt with a giant lambda symbol on it.

He also shouted LAAAMBAAAA!!!. Dude really loved lambda calculus. Think I laughed at that for a solid week. For reference he also looks like this: 
That is awesome. I've noticed that a lot of people worship the lambda. Have you heard the story about how Feynman, for his intro physics class, hung a bowling ball from the ceiling? He stood up against the wall, pulled the ball up to touch his nose -- and let it go. Of course, on the return swing, it did not touch smash into his face. His point was that physics works, and you have to get an intuitive feel for it to be good at it.

There's a nice thread here about 'why did Church pick lambda?': 
Triggering From A Monster 
is it possible to trigger a target with a monster as the activator?

i've tried spawning the monster on top of a trigger_teleport, having the monster walk onto the trigger_teleport (with path corners) and lowering a monster into a trigger_teleport with a func_door.

the trigger_teleport had a target, but somehow i was still the activator when the monster would go through the teleporter.

all i can think of would be to make a dummy monster that targets the entity, and make the spike_touch hack kill the dummy with the owner pointing to the activator monster, but that's convoluted as hell and really ugly. 
Yes, It Can Happen 
For example, if a monster kills another through infighting, and the dead monster had a target, then the killer will be the activator of the target. This caused a very tricky to identify bug in a recent map whose author will remain nameless here...
So it can happen.

Making it happen on demand is a bit trickier. I think I've come up with a hack that will do it though. Add an info_notnull and set its enemy field to the entity number of the monster in question. Then set its use field to trigger_multiple. Then if you use the info_notnull, it will fire its targets with its enemy as the activator.

How it works: originally I was going to try doing it with the "naked trigger_multiple" hack, where you make a trigger that monsters can touch, and have the teleporting monster touch it. That trick relies on short-circuiting the multi_touch function which usually guards against non-player touches.

Unfortunately, skipping that function also skips the line which sets the trigger's enemy to the touching monster/player/fireball. This enemy is then used as the activator - so you still wouldn't get the monster as the activating entity. Instead you get whatever was in the enemy field to being with - world being the default. I got half way through typing up a solution involving the spike_touch hack setting off a trigger_multiple with health, before I saw the short cut that would save an entity...

Not properly tested it btw, but I'm pretty sure that will work as intended! 
that sounds like a much better solution. this brings me to another question i should have asked: how *do* you find the edict numbers?

typing edicts in the console outputs ALL the edicts, and even with condumping, it only actually prints the last 80-100 or so. (the map has over 600 edicts).

all i can think of is to maybe make a progs, but can you even bprint() the edict number? 
this always happens, i figure out how to do it after i ask. :P 
it works. thanks!

btw, it's 'use' 'multi_trigger', not 'trigger_multiple' 
Edict Hunting 
This is actually reminds me of something I've had in the back of my mind as a desirable feature for a "development" quake engine. Better searching of the entity list with the edict command. The biggest improvement would be to be able to specify a classname, like

edicts monster_knight

would output a list of every knight in the map.

Once you have that, partial matches would be the next most handy feature, so that

edicts monster_

would return a list of all the monsters in your map. If you really needed flexability, you could extend it to match other fields instead, like

edicts targetname skulldoor

would give you all the entities targeted by "skulldoor". If anyone other than myself would be interested in that, I might take a look at hacking it together...

There are workarounds until such things are available. If you save the game instead of running the edicts command, you can open the save file in a text editor and get essentially the same information out of it - or even run -condebug and read through the output file at the same time. The only thing that the save game lacks is...entity values themselves! So the latter method is needed for those 
That Would Be Pretty Badass 
except that it's only real use would be for hacks, correct? 
That Would Rock 
It could also be useful for checking targetnames and goalentities etc. Though I would probably use it only for hacks, yeah. 
QC Application 
I'd also find it really useful when debugging mods, although not so many people are going to care about that. I'm gonna go away now and see if I can get the new version of fitz to compile... 
Half Way 
The following replacement code will perform partial matches on classname. Find the function in pr_edict.c and replace it entirely with this. I've only tested it in fitzquake085 so far, but I don't see any reason why it wouldn't work in the original source. Other engines might have changed the functions that it calls, but I'd say even that is unlikely...


For debugging, prints all the entities in the current server
PREACH: If supplied with a second argument, only reports entities whose classname initially match the argument
void ED_PrintEdicts (void)
�int i;
�edict_t *ent;
�switch (Cmd_Argc())
��case 1:
���for (i=0 ; i<sv.num_edicts ; i++)
����ED_PrintNum (i);
����Con_Printf ("returned %i entities\n", sv.num_edicts);
���int j,len;
���len = strlen(Cmd_Argv(1));
���j = 0;
���for (i=0 ; i<sv.num_edicts ; i++)
����ent = EDICT_NUM(i);
����if( !strncmp(Cmd_Argv(1),pr_strings + ent->v.classname,len) )//match initial substring
���Con_Printf ("returned %i of %i entities\n", j, sv.num_edicts);

Getting it to match against any field is a little bit more tricky, so I'm gonna keep working on that now. Once I get that, I'll post the code and a binary. 
And A Follow Up 
Phew, not too bad. You can grab the following function added to fitzquake085 from:

void ED_PrintEdicts (void)
�int i;
�edict_t *ent;
�switch (Cmd_Argc())
��case 1: //regular call
���for (i=0 ; i<sv.num_edicts ; i++)
����ED_PrintNum (i);
���Con_Printf ("returned %i entities\n", sv.num_edicts);
��case 2: //match against classname
���len = strlen(Cmd_Argv(1));
���j = 0;
���for (i=0 ; i<sv.num_edicts ; i++)
����ent = EDICT_NUM(i);
����if( !strncmp(Cmd_Argv(1),pr_strings + ent->v.classname,len) )
���Con_Printf ("returned %i of %i entities\n", j, sv.num_edicts);
��default: //match against given entity field
���int j,len;
���int *v;
���ddef_t *search_field;
���search_field = ED_FindField(Cmd_Argv(1));
����Con_Printf ("Bad field name\n");
���j = 0;
���len = strlen(Cmd_Argv(2));
���for (i=0 ; i<sv.num_edicts ; i++)
����ent = EDICT_NUM(i);
���//this is ugly as hell, WTF Carmack?
����v = (int *)((char *)&ent->v + search_field->ofs*4);
����if( !strncmp( Cmd_Argv(2),PR_UglyValueString( search_field->type, (eval_t *)v),len)) //match initial substring
���Con_Printf ("returned %i of %i entities\n", j, sv.num_edicts);

Only minor bugbear I have with it is that tab still activates autocomplete on the second parameter, but it completes commands, which is unhelpful. Otherwise, it's cool. 
//this is ugly as hell, WTF Carmack?

nice work! :) 
Nice One 
Let's see how this works out in the field. 
"//this is ugly as hell, WTF Carmack? "

Well, Carmack's reply would probably be something like, "We were trying to ship a game on new technology. This ugliness was maybe .00000001% of the workload. Unimportant." :) 
we've covered removing items from the inventory via a func_door function hack.

is it possible to co-opt sigil_touch() to remove runes from the player?

i was thinking if you gave built a trigger from scratch with a touch function of sigil_touch and gave it a spawnflags # corresponding to the appropriate rune (1, 2, 4, 8) except negative, it might be possible to subtract it out of the serverflags global variable.

except that the way they added the flag is in a form i'm not familiar with (and i don't know much about bitwise manipulation except what i've learned here).

serverflags = serverflags | (self.spawnflags & 15);

except that serverflags = serverflags | (serverflags & self.spawnflags);
would have seemed to me the correct way of adding the flag in.
what does the actual line do? will it prevent subtracting the flag off? 
serverflags = serverflags | (self.spawnflags & 15);

first, the & character is bitwise AND operator, which means that for each bit, the result is 1 only if both inputs are 1 for that same bit. 15 is 1 + 2 + 4 + 8, So self.spawnflags & 15 is going to only allow those first four bits in self.spawnflags to be used in the next step.

The next step: | is the bitwise OR operator, which means that for each bit, the result is 1 if either input has a 1 for that bit. So serverflags = serverflags | x is going to turn on any bit in serverflags that is in x, and leave on any bit that was already turned on before.

So basically, only the first four bits in serverflags can be turned on with a rune, and, you can't turn any bits off. 
damn shame, thanks though :) 
The Meta Hack 
Just in, the latest discovery in the hacking business. A trigger_command in id1! Well, sort of.

As it turns out, it's actually possible to execute console commands from within the map by simply adding a linebreak followed by a string of commands in the "map" field of a trigger_changelevel. For example:

"classname" "trigger_changelevel"
"spawnflags" "1"
�// no_intermission has to be set for this to work
"map" "\ngod; impulse 9"

The trick works because the trigger uses stuffcmd to change the level which we can exploit to run our own commands. However, there's a catch. In the engine, we have a hardcoded line that prevents the changelevel from being issued multiple times, which means this hack can only be used in this form once, and afterwards the player can't proceed to the next map after exiting the level normally. It will just stay in intermission mode forever - one might regard it as acceptable after a large map with no follow-up; or with a Shub ending.

Even in this state, the hack has a lot of potential, especially for mischief. You could, for instance, rename the player to "Asshole" and make his client connect to a server. :D Or mess with his entire config, unbind all keys etc. But since we're all nice and friendly people (right? :P), rather things like changing map-related cvars come to mind, e.g. setting r_wateralpha for the glass hack or adjusting fog values.

Luckily there's a sort of workaround for the changelevel/next map problem mentioned above. After changing cvars for map compatibility, you can add a "restart" or "map yourmap" command to the end of the string to reload the server with the exit trigger intact. Or, if you set any non-permanent stuff (e.g. cheat codes or gravity), you have to add commands to save and reload the game. ->

Following this line of thought, Preach came up with two very useful setups the hack allows us to use.

The first one is a kind of security measure to make sure all necessary commands are executed before the map is played. Set "serverflags 256" in the middle of your command string and use a func_episodegate with spawnflags 256 as a detector. If the episodegate doesn't spawn, the player (presumably) hasn't run the map yet and needs all the stuffcmd set; if it spawns, there's no need to restart.

The other one is an actual autosave option, albeit not a very transparent one. Place trigger_changelevel entities as checkpoints and set their map fields to "\nsave autosave; wait; load autosave" (you could also use "quick", or better yet, the mapname instead of "autosave"). This will save and instantly reload the game on each checkpoint - however, it's quite 'bumpy' and may even cause annoying delays in larger maps and engines with long loading times (DP). In this sense a button-controlled checkpoint system would probably be the best solution. 
Negke and I were discussing this last night for as long as steam would allow, and I think there are some exciting possibilities. However, I have just thought of a potential small wrinkle in the serverflags 256 detection code. Suppose that someone loads the map, instantly receives a string of commands including "serverflags 256;restart", and then begins playing the map on the second time round. Supposing they save the game, they might not load that saved game for a long time. If serverflags 256 has been cleared by subsequent playtime, then on trying to load their savegame they may end up back at the map start!

How did this arise? Well, when a savegame is loaded the engine does two things. Before it looks at the savegame data, the engine runs the first three frame of the lodaded map as if it had just been started from scratch, in order to get all of the precaches loaded. It then updates all of the entities and qc variables to match what was stored in the savegame file. If our hack runs during those first handful of frames, then the restart command will be sent before the savegame is loaded, and so you end up right at the start of the level.

It isn't the end of the world, because now serverflags will be set to 256, and so if you load the saved file a second time it will work correctly. It's just good to make people aware that this problem can occur though. The alternative design would be make sure that your hack trigger fires later than the first three frames, but this has two negative effects. One is that the restart will be more visible to players, as they will see frames rendered first. The other is that in the scenario outlined above, none of your essential console commands get executed when the game is loaded. If the serverflags cvar got reset, it's probable that some of the others did too. 
Renaming The Player 
That reminds me of Zelda on the gameboy, where it was possible to steal from the shop and be called THIEF for the rest of the game. 
Changing The Skybox In Quoth 
Cool trick: you can change the skybox while a map is running in most engines, via an info_command.

The command is "sky [skyname]" (works in Fitzquake, DirectQ, Quakespasm). Unfortunately Darkplaces uses a different name, "loadsky". I guess you could have a pair of info_commands with both commands, but then the player sees an "Unknown command" message for the one their engine doesn't recognize. :-/

This could be used for some neat effects. Maybe have a setting sun sky turn to night after spending some time indoors? 
This could be used for some neat effects. Maybe have a setting sun sky turn to night after spending some time indoors?
my lost map pack had this in there.

you can also string multiple console commands together like this:
sky void;loadsky void;fog 0 0 0 0\n
so there's no need to have multiple info_commands.

further, i think it's an undocumented feature, but if you set spawnflag 4, whatever commands are on that particular info_command will be run whenever the map is run or loaded from a save.
this stops the problem with fog/sky settings not being saved because they aren't in the worldspawn settings. 
This could be used for some neat effects. Maybe have a setting sun sky turn to night after spending some time indoors?

We did this in Travail too! We had to cheat a bit for people with older engines though by covering the sky with a non-solid black brush. 
Chthon Style 
Looking for a replacement teleportation effect (as spawn_tfog can't be used anywhere else than 0 0 0 - or so it seems), I came across two more things Chthon allows us to do. They are quite obvious, but I'm posting them just for the record.

Lava splash: Target an info_notnull entity with a "use" "boss_death2" field.
This might be useful for spawning a powerful monster or when lowering a platform into a lava pool. The downside is that this will increase the kill stats by 1, but it should be okay since it evens out the max count.

Meteor shower: An info_notnull with "use" "boss_missle1".
This will start an infite attack of lava balls from a fixed position aimed at the player - for an environmental hazard with a little more kick. Each missle will play Chthon's throwing sound, but that shouldn't be a problem, especially if the entity is high above or in some distance. To stop it, simply killtarget the entity.

Needless to say, a monster_boss has to be placed somewhere in the map for precaching. 
Correction About The Lava Splash 
Use "boss_death9" instead for a more immediate effect, and killtarget the entity 0.1 seconds later to keep it from raising the kills count. 
Despawning Items At Start Of Map 
Using the triggered respawn of items to repopulate arenas with items, but this is after the player has picked it up. Is there a way to despawn an item, so it only appears in the arena for a particular wave? 
Since you're using Quoth, the spawndelay feature (or however it's called) should suit your needs. 
sounds like he's asking to both add and then remove an item during play.

so you'll need to make your item spawn in and then, you should killtarget them to remove them when their time is up. 
It's not a massive problem. I can make little cages around the item, it's the problem of a fight taking some time to get going.
Feels crap to take it and lose half the time as you wait for the fight to ramp up, and I thought it would be neater to have an empty arena and just drop the powerups in as the particularly nasty monsters start flooding in :)
I guess the cage thing also has the advantage that they'd probably hear it better.

Another way round it would be increasing the duration of the powerup, so they just take it and don't have to worry about them missing the respawn. I guess that'll require code editing though :E 
Not Necessarily. 
you could create a variant of the trick i used in ne_tower with getting a quad damage after killing the two death lords.

create a number of of empty rooms with the powerup of your choice in them.
in each room, put a teleport destination on top of the powerups, but make sure the teleport destination is part way into the floor or ceiling so that the player won't fit when they teleport.

now, create a huge trigger_teleport that corresponds to each of the destinations and give them all targetnames.

what you'll do is start off a long train of teleports with delays after picking up the first powerup.

sure give each relay a delay of 30.

give all those trigger_teleports a targetname2 that is the same.

so you pick up the first powerup. that triggers a relay that will trigger the teleport trigger 30 seconds later that teleports you into the first room where you get a new powerup. the engine then pops you back to the old spot because you don't fit in the room. that new powerup starts another relay that, 30 seconds later, will teleport you into the next room. etc etc.

finally, when you kill the boss or whatever, killtarget all the trigger_teleports from the targetname2 which will remove them all and stop the chain. 
That's brilliant :D 
Negke Re 218 Above 
What determines the fixed point of the meteor shower - it is not the position of the not_null? It appears to be 0, 0, 0 
... what is the purpose of the '1' in 'boss_missile1'? 
boss_missile1 is actually chthon's animation (not the missile spawning function).
his attack animation is looped, unlike all other monsters. this is why he just starts firing and never stops.

the lavaballs SHOULD spawn relative to the origin of whatever entity you use.
specifically, one should spawn at 100 units forward, 100 units right and 200 up, relative to the origin and the other 100 units to the left. 
Oh, I didn't think about that.

However, it ignores the origin of the info_notnull and works off 0, 0, 0. Also in practice, it doesn't look right as the source of the lava balls moves i.e. they do not emanate from a fixed point as the player moves, due to the position of the boss (arms) being recalculated.

Changing "use" to "boss_missile" does have the lava balls coming from a fixed point but it is impossible to survive the onslaught.

If you could trigger it on/off and slow it down, it could be a good anti-player device. 
Try This 
make info_notnull with 'use' 'boss_missile' and 'targetname' 'meteor'

now make a trigger_relay:
'targetname' 'meteor'
'target' 'meteor'
'delay' '1'

should now loop infinitely every second and shoot.

make multiple relays and start them at different times to stagger missile launches for a more natural effect.

if you have access to multiple targetnames, you can give a 'targetname2' that's unique to the relay allowing you to turn it off again without killing all the launchers as well. 
make sure 'delay' is set in the relay otherwise the engine will crash wtih an infinite loop error. 
Just playing with it now and using a trigger_multiple with "wait" set at one second. Three problems:-

1. almost instant death (100 - 120 hit points)
2. the first lavaball does not go anywhere, it just hovers until it disappears (subsequent balls do head for the player)
3. regardless of the position of the info_notnull, the source of the lavaball definitely remains at 0, 0, 0.

So although the position of the not_null is created in the map file, the code for the boss_missile ignores it and uses 0, 0, 0.

Pity, it seemed to have potential as a boss fight - e.g. carry out some task to turn the weapon off whilst whilst avoiding the lavaballs 
you're doing something wrong then. maybe your info_notnull has brushes?
bmodels have origin of '0 0 0' at map start.

the code can't ignore the origin as it's explicitly used when spawning the missile with this line:
org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1'; 
does "ShalMissile" work? it's homing, but a lot less damage. 
So this is one of those pointsize entities eh?

I have just checked the Entity.qc file and for some reason both 'notnulls' are wrong:-

/*QUAKED info_notnull (0 0.5 0) ?
/*QUAKED info_notnull2 (0 0.5 0) ?

should be:-

/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
/*QUAKED info_notnull2 (0 0.5 0) (-4 -4 -4) (4 4 4)

Just shows how often I use the info_notnull tricks.

Thanks, I'll look at this a bit more know. 
there are times when the info_notnull requires a brush to work. maybe you changed it to do one trick? 
Yes, possibly. Fourteen years of intermittent mapping... oh my word, is it really that long? 
You were right. I used it as a special trigger where it was in a frequently used cross roads but must not be activated as a trigger until certain other events had taken place, hence the need for a brush.

It pays to keep notes even if they take days to sort through! 
I have tidied up the ents.qc so everything is now as it should be within the editor: info_notnull is the point-size entity and info_notnull2 is the brush-size one.

I have also been playing with several 'missiles' and seem to have two distinct scenarios. The boss_missile works as you would expect with the player being bombarded with the lava balls. However, ShalMissile and LaunchLaser both go from the not_null origin to 0 0 0.

What is it that allows the boss_missile do do what we want but stops the other two from doing it. It seems as though boss_missile has the player as its 'enemy' all the time as it reacts as the player moves but the others are fixed. Is this something to do with what the 'activator' is? Are we able to do anything about this from the editor?

Incidentally, the LaunchLaser gives a great effect even like this - if you have the not_null close to 0 0 0 and operate the entity via a trigger_multiple, you have a build-up of an intense orange yellow glow that fades in to maximum and then fades out to nothing when you move out of the trigger's area. Looks neat and I am sure it could be used somehow. 
LaunchLaser will not work because it requires data to be sent to the function:
LaunchLaser(vector org, vector vec);

so you'd need to send 'org' as the point to spawn the laser at and 'vec' as the direction you want it to fly to, which is why it doesn't work.

ShalMissile SHOULD work.
in the function, the line:
missile.origin = self.origin + '0 0 10';
while incorrect from a qc standpoint, should still work. (or maybe you don't need setorigin when you're spawning an entity in the same frame??).
are you sure use used a point entity when you tried ShalMissile? 
in case it's not clear, there's no way to send the required data to LaunchLaser.

when you run a function via 'think' or 'use' it's the equivalent of just typing LaunchLaser(); in code, so while it works, it sends, the engine fills in the missing variables with 0. (or '0 0 0' in the case of vectors, 'world' in the case of entity and so on). 
Not really a sophisticated hack, but a nice little trick I just came across in an old map.
It's possible to simulate a crude ice sliding effect by putting a flat shootable trigger_multiple with a high wait value on the floor (possibly target it on mapstart to avoid the bleeding) - basically the old invisible wall trick. The player will slide over it like he does when landing on top of a monster; he can change the direction but he won't come to a stop until he reaches solid ground.

There probably aren't many situations where this might come in handy, except maybe in winter-themed maps or for certain traps. 
on the idea of the killable cthon frikac made long ago, is it possible to make, for instance, an enforcer that shoots player rockets? and if not an enforcer or other monster, perhaps a monster that appears like the player model? 
Couldn't you change the skin on the grunt? I thought it had more than one skin, the other being the players. I'm not 100% sure on that though. 
Didnt A Negke Map 
have monsters shooting non-standard missiles? 
scampie: yeah, you basically build a monster out of an info_notnull, filling in th_missile and such with whatever attack function you'd like.
as nitin said, neg's map lower forecourt has things like lightning dogs.

jt: nope, only one skin on grunts. 
thanks for confirming 
Monsters With Different Attacks 
Yes, it's possible but it's really an ugly hack. One has to keep in mind that the qc monster functions are tied to the animations in the mdl, so creating custom monsters will result in "invalid frame #" warnings and, more importantly, the attacks won't be animated. 
In Particular 
Not having any animation for the attack essentially means no warning before the attack happens, which is unfair to the player. 
6 Frames Or So 
Isn't any warning anyway. It just doesn't look very good. 
It is also more of a gimmick, I prefer the stock monster. 
I'm going to release a map entitled 'Made by Spirit' and it will be nothing but spawn that shoot shambler lightning in a tiny box. 
Would it be possible, using info_notnull, to create a zombie that doesn't attack the player but just wanders around? :E

I'm assuming not because it'll just try to call an attack function and crash when it doesn't find it but asking anyway :p 
"th_missile" "plat_hit_bottom"
"noise1" "zombie/z_idle.wav"
No, That's Not Possible. 
in order to wander around, you need ai_walk (part of the th_walk sequence), unfortunately, ai_walk calls the function that searches for clients which would lead it to wake up and eventually attack you. 
well, just thought of this, but if you made the zombie mad at some monster it couldn't reach, it would just wander around and not attack you (unless you fired at it).
the qc hack to do that is a little annoying though as it relies on edict numbers that change when you're making a map. 
To Elaborate On That 
(I know this is a huge bump, I've been 10 days without internet...)

You could even get the zombie to walk in a path by
1) Making it mad at a func_plat instead of a monster
2) Giving that func_plat a health value so that the zombie stays mad at it

Keeping the platform out of sight is important so that the zombie doesn't try to attack it. Giving it a health value isn't too dangerous as long as you leave .takedamage set to 0 (TAKEDAMAGE_NO).

As necros mentions though, the hack to do this relies on entity numbers which means it lacks and resilience if the position of the relevant entities in the entity list changes for any reason (updated map, change in entity counts over skill levels, different mod).

The best mitigation is to ensure all of the entities involved in the hack are the first things loaded from the map - which usually means they should be the first ones added to the map in the editor. If it's too late for that you may want to edit the entity file by hand to achieve this. 
hmm, okay, I might be able to do something with this :)

I take it as soon as the player attacks the effect is lost? Not that that is a major issue. 
Yup (NT) 
Shootable Buttons No Bleed? 
Is it possible to make shootable funcs_ like buttons not bleed on activation (with stock progs.dat)? 
i don't think so. in order to take damage, an entity needs to have .takedamage set to a non-zero value and blood particles are spawned when .takedamage is non-zero. 
Not Entirely 
The problem is that spawning blood is a decision taken entirely on the part of the weapon firing code (since explosions spawn none, and lightning burns orange instead). In particular the shotgun and axe code will always spawn blood if they can damage the target, so any hack which prevented the blood appearing will necessarily set .takedamage to zero, and therefore make the entity shootable no more.

There are two interesting alternative though. One would be to make the button shootable only by explosions. For this you wouldn't even have a shootable button, just a func_door to give the illusion of movement. You add a point sized info_notnull next to the button and add the following fields:
"takedamage" "1"
"th_die" "button_killed"
"speed" "1"
"pos1" "self.origin"
"pos2" "self.origin"
"health" "1"
"max_health" "1"

Then make it target the "fake" button and whatever event you want it to fire.

This button can be refired after 2 frames, and you can't add .wait to extend this because the movement functions are intended for a BSP object. So you might need to add a trigger_relay between the info_notnull and the things that it is meant to trigger in order to introduce a delay.

The other alternative would be to make a button that is fired by touch. This would mean a number of compromises need to be made:
1) Anything that touches the button would activate it, like monsters.
2) The activator for the button will be set wrong, which matters if it's meant to wake up monsters or send a message to the player.
3) Hitscan attacks (shotguns, axe and lightning gun) will not activate the button.

If these are all acceptable then start by taking the existing button as a base. Read all the fields which are set in-game using the edicts command. Then change the button's classname to func_wall and add all the fields you read from the edicts command to it manually along with
"touch" "button_fire" 
Grenade Shooter 
Hopefully this should be a simple hack, but I couldn't find a clear explanation in the thread. I want to do an action similar to post #11, having lightning fire out of a point entity at a certain direction. However instead of lightning, I want it to be a grenade.

I attempted to do this using the keys and values but replacing them with rockets, but it did not work, as I expected.

So I guess to sum things up, can I have something similar to a spike shooter, that instead of spikes, fires grenades, or any other projectile I want it to?

If I can get a solution, I will post a few screenshots of my current map soon :) 
Someone tell him quick so we get screenies!!! 
How About... 
post #14? ;)

presumably you could set up another info_notnull for the shooter to target, compile the map, get the edict number and add it in as the shooter's 'enemy' field... 
Can It Be? 
Is it possible to overload the model field for torches? Perhaps re-directing it to a custom bsp model for, say, a lantern while keeping its sound and light values in tact. 
Might be easier to use a point light and point trigger for the sound along your custom light model (illusionary for static). 
External BSP models don't light properly though... but I guess that for lanterns you could just light them fairly bright and say that it's the light from the lantern that's making them bright. 
For Madfox - Crosspost From Modelling Thread 
To add the lightning sound effect to your map:

Go to the first page of this thread and read post #8 by Negke. If you want to use the sound which was included in the zip with your map, then precache it yourself in the spawn function for the info_tessla. If you want to use a sound which is already precached, then I recommend "weapons/lhit.wav". 
I will try that, I knew it was somewhere. 
I Think 
the thing with grenades has already been done:
check sm129_efdat 
Is there any way to have a monster jump start deactivated and then switch on when a trigger fires? 
Might As Well Not Jump 
The usual way of creating a trigger, detailed here among other places:

This works just fine for trigger_monsterjump. 
Wiki Page For These Tricks 
has been added here:

I'm not really very knowledgeable about these hacks as I've only really used the explosion effect before, so please add and modify what I've written.

Also, do I need to get permission to quote stuff from here or even copy it wholesale? I wanted to use Preach's explanation of the explosion, because it is better than my own, but I wasn't sure if he would mind...

Anyway, like I said, please add more stuff to that page and improve what's there. 
Just Remembered 
there is some kind of trick to get particle effects to appear on stuff. I've seen it on keys in a couple of maps, and I think I even saw it on a monster before. It could be used to signify a high health monster using the armortype hack.

Anyone know how it works? Is it as simple as adding an effects field or is there something more to it? 
Is it as simple as adding an effects field


"effects" "1" works well, a bunch of fireflys

"effects" "literally everything else" either makes a giant glowing flicker light, does nothing, or makes more fireflys and flickering light. 
Logic Gates 
I already posted this in mapping help, but I think it might be worth putting it in here to...

Quake logic gate tutorial:

I will add it to the wiki with images soon. 
Logic Gates Again 
So I wanted to make a post about logic gates, dug up this thread and found the very last post was about...logic gates!

Than: I read through your tutorials and had two ideas. The first was a simpler construction for the "if...else" device - I think it's easier to understand as well as saving an entity, so I thought I'd share. The idea keeps two spikeshooters aiming at the if and else triggers. Set the two shooters up next to each other, then create a single blocking door just large enough to block one of the shooters. Have that door move up and down between the two firing paths, so it blocks one when it is up, and the other when it is down. Diagram:

>.....|�����[+] (if)
>..........�[+] (else)

>..........�[+] (if)
>.....|�����[+] (else)

The other suggestion I have is more radical: replace the trap_spikeshooter with an axe! Less obliquely use an info_notnull with "use" "W_FireAxe". Set the angle of firing with "v_angle" (although since you're free to build the firing range at any angle you might as well choose to fire due north and not bother setting v_angle at all!).

The axe fires an instant hit traceline which starts 16 units above the info_notnull and traces for 64 units. This removes the need to create a stream of spike entities and wait for some number of frames until they score a hit. The axe has a few advantages over the player's other instant hit attacks - it's quieter, needs no ammo, and doesn't require extra entity hacks to set up the angle of attack.

The big appeal of the axe over the spikes in my mind is the instant reaction of it - making the system much more tidy. This leads me onto the discussion I wanted to raise in the first place. For a few days I've been wondering about trying to find a better hack for the doors. The fastest reaction time a door can have is 0.1 seconds. You can get better reaction times turning an input on by having the spike shooter aim near the bottom of the door, which then moves quickly out of the way. However, this is traded against worse reaction time when turning that input back off.

Another issue with doors is that you might actually miss inputs, if a second input comes in too soon after the first and the door is still moving. This might destabilise a complex set-up which 'knows' how many triggers it takes to turn inputs on and off, essentially inverting subsequent inputs. So there are non-aesthetic, if obscure, reasons for wanting an alternative.

What I want to start with is clarifying the way quake logic gates work right now, compared to silicon ones, and make sure it's the right model to use. Silicon logic gates have a continuous stream of electrons pouring into the inputs, and the output stream responds to changes in the inputs with another ongoing stream. The streams from AND gates begin when both inputs are active simultaneously.

The first challenge in converting that into quake entities is that the triggering in quake is instantaneous, not continuous. This means that it doesn't make sense to talk about two triggers occuring at once: only one can fire at a time. So the model we have is that continuous streams are actually represented by entities with state - currently doors - being toggled to indicate a particular input is turned on or off.

That deals with the input. The output needs to work in reverse - a continuous state (the outcome of the logic gate) needs to be converted back into an instantaneous trigger. We do this by querying the current state of the gate - in practical terms by launching our spikes into it and seeing the trigger fire if the gate is open.

That's the theory as far as I can see it - is that more or less what everyone expects from logic gates? Or is there a better way for them to work conceptually - if only we could find the hack to use? 
Thanks For That, Preach 
I had no idea you could fire the player's weapons from an info_notnull. That sounds a little more streamlined, although the spikeshooter method works nice if you actually want the system to be visible to the player of course.

The time lag problem is a little bit crap, but it's not the end of the world, since you can move the spikeshooter closer to the trigger if there is too noticeable of a delay. Of course, the axe trick is better since it minimises the delay.

I had thought of the trick to save doors, but I don't think it works if you want a combination of IF/ELSE and AND. In any case, I thought of it after implementing in the tutorial map :/ 
While working on a new and improved logic gate contraption, I came up with something short and sweet:
A new hack to get a trigger_damagethreshold in stock quake. Not the most commonly used entity to be honest, but obviously someone went to the trouble of inventing it. Can you see a use for a logic gate? 
That is such a clever idea o_o 
Logic Shooters 
This mostly what I did with my Q3 "Edge of Forever" map. I even wrote a long article explaining some of the logic I built using entities.

Logical Madness 
It's Done 
Okay, as promised, an alternate logic gate with the emphasis on instant response and being highly obtuse! There is another selling point on offer here though - it has separate targetnames for opening and closing the gate rather than a toggle. This may be desirable if you have many potential sources for the trigger to open or close.

This one now uses both of the mini-hacks I've posted about this week. It also went through a fairly big rewrite in the past 24 hours or so. Originally it worked a lot more like traditional logic gates, so the wierd hacky solid-toggling entity only blocked attacks, rather than receiving them as inputs. It relied on a "touch" function for the off switch, which had a potential race condition. The new way with the unusual use of the damagethreshold hack avoids that, and does away with the separate detector entity as well! 
And Some More 
The second half, where we restore the logic functions to logic gates:
The AND gate set-up is a bit lazy, I might try and think about a better way. The OR gate is rather cool though, if a bit more fiddly. Finally we have an IF-ELSE patterned after the OR. 
Still need to wrap my head around it, but it certainly looks like a new level of awesome! So now functions can be used in classnames as well?! Thanks for sharing your genious.

And well-timed, too, as I was going to post a brain teaser for you which just may have been already partially solved by your latest discoveries.

How would you go about creating a sort of dynamic counter functionality in an edict-efficient way? I mean something like a pot where counts are added and substracted, almost like a monetary system.
For each monster that you kill or item you pick up, a token (for the lack of a better word) is added to the pot, which then, if a sufficient number has been reached, can be used for different actions such as triggering certain evens, unlocking corresponding doors etc. Using it will deplete the pot by the number of tokens required for the specific action.
So for example, there's a bronze door that opens for 10 tokens, a silver door for 20, and a gold door that needs 30. The player can decide whether to spend his earnings right away or save them until he has enough for a better door. Using them substracts the amount from the pot, so it's an exclusive decision. Having 30, it's possible to either open the gold door, or both bronze and silver.

This could be done with a number logic gates and toggleable triggers, but this would be a rather wasteful setup, especially the more complex the system and its options become.

Any ideas? (Bonus points for an additional system to check the current number of tokens in the pot) 
What's In A (class)name 
Re. money: I have a few thoughts on what might work there but nothing concrete yet. Watch this space...

Thought I'd pick up on something here:
So now functions can be used in classnames as well
Yeah, essentially classnames ARE functions - when an entity is spawned, QC imbues it with a unique behaviour by running the function whose name matches the classname. The function doesn't have to be very special either, as long as it acts on the entity called "self". So you can often run two functions on a hacked entity by pairing an unusual classname with nextthink and think.

InitTrigger is a really great one to use. Pretty much every spawn-function for a trigger sets some fields on self, applies some default values, then calls InitTrigger to actually make it touchable and invisible. If you are trying to hack the behaviour of a particular trigger and need to override a key set by the spawn-function, often you can just set all the fields manually and change the classname to InitTrigger. 
Re. Money: 
Hmm maybe code a 'money/buying' system in qc after all. Its getting crazier and harder to implement as a maphack. And I would love to have some more economics in Quake. 
Well obviously you could do it in qc in three seconds flat, the fun is in the challenge. 
Can you not have something like a func_plat which is moved up and down as currency accumulates or is spent? (With spikeshooters at various vertical distances, firing horizontally, that are interrupted by the presence of the platform) 
I agree that could work, but it's the ability to move it up and down by arbitrary amounts that's hard. Platforms, doors and buttons all move to absolute coordinates calculated at spawn time. Even with a hacked entity which didn't use those spawn-functions, you'd be moving between the pos1 and pos2 keys, which are fixed.

It does also have the old race condition like logic gates made out of doors. On the one end of thing, having to wait for a few frames before a deposit is made is something a player would never notice or mind. On the other though, you're opening yourself up to a double-spend attack... 
'Dynamically'-moving funcs can be done by including a caged monster in the entity (hidden from view and sound). It moves with the func and uses the health or invicibility hack. Then it can be blocked by barriers which prevent the entity from moving onto the next stage until they are removed. 
Yeah, if you can move another entity dynamically you can get a BSP to follow, It's still not enough for an efficient credit system though, because you'd need one more barrier for each credit the player earns.

playing around with trying to make a misc_teleporttrain that isn't MOVETYPE_PUSH (which apparently crashes Quake when telefragging anything except Shub)... I ended up making hologram Quakeguy.

Still no idea how to get this thing to properly move :( 
fyi, figured out how to do what I wanted... MOVETYPE_PUSH is required for a train... but you can bypass the crash if you killtarget the train the moment the enemy you telefrag dies (shub removes the train as well as part of her death functions) 
New Article 
Here's a map hack article that's been sitting half-finished for months. It's a general article on how to build a trigger_ type entity with very little restriction on the keys you can set.

I think most of the regulars who read this thread will know this trick, but hopefully it's a good reference for newer mappers - and there might be some new ideas in the concrete examples of the trick. 
I didn't know that trick, cool! 
Adding Maximum Ammunition ? 
Maybe A Little Too Terse 
Could you clarify, are you looking for a hack which fills all the player's ammunition type (easy to accomplish with backpack_touch), or are you trying to increase the maximum ammo the player can carry (almost certainly impossible)? 
Apologies, Yes The Latter.I Wanted A Kind Of Increase Carrying Ammo 
More Ammo 
You'll want to write a short mod to do that then, it's outside what hacks will do for you. Also, be warned that not all engines can display ammo counts above 255 properly, which means the scope for expanding nail ammo is limited. 
Gameplay Changing Thoughts 
can you dynamically change the gravity values?
or set a trigger to change a mobs .target value? 
I think one of the expansion packs has a way to do this but it doesn't work in coop 
You pretty much can't change the gravity with stock quake - there's a way to change it exactly once with a hack if you don't mind that you can't have an exit in your map. It's very common in mods though.

Not sure exactly what you're asking in that second question - you literally want to change the string stored in the target field? It might be better to do what you want with logic gates triggered by the monster instead. 
global sv_gravity cvar, if you have a trigger or some such to issue localcmds.
or .gravity field, if you have a trigger to apply that field to entities within its boundaries.

I've no idea how to utilise either of those without a mod to do it for you.

in some engines (ie: ones that always register custom fields, ie: fte+dp), you can override .gravity on a per-entity basis by just setting the gravity field. Of course, as this doesn't apply to players, projectiles, or movetype_step (unless you somehow manage to get them airborne), all it can really be used for is to confuse the fiend+dog+spawn attack code. Which might be amusing. 
What Are Some Of The Properties That Can Be Given In The "use" 
Quake Wiki Is Not Working For Me. 
the article text won't show up. 
Fuck Me, Sorry 
stupid mediawiki can't handle the latest version of some library which I forgot to pin when I updated earlier. will be fixed tomorrow. 
Very Well Then, Spirit. 
Don't screw it up again... 
Follow The Leader 
Earlier this morning, onetruepurple mentioned an idea for monsters following the player while he had the Ring of Invisibility. I didn't think it possible, but he mentioned that it was done in E4M1.

So I decompiled the map and discovered a trick that I didn't know about and think it's cool enough to share.

It's very simple, if you make a monster target a path_corner, and that path_corner has no further targets, Quake decides that that monster's next movetarget should be entity 1... which just happens to be player 1.

Here's a .bsp and .map showing this effect... don't shoot! 
I have no idea WHY that works.

self.goalentity = self.movetarget = find (world, targetname,;

Is the relevant bit here, where self is the monster, and other is the path_corner... but why it decides on entity 1 when is empty... it is a mystery? 
I Guess 
Find() must just return 1 if some of the values it's passed aren't valid? 
I wanted monsters to reach the end of their path and just stay there, and so left the target field blank.

But the same happened - they turned and followed the player, ruining the gameplay I was going for.

This is because their movetogoal becomes "" and the player is the last entity added to the server, with that exact name, aka string_null.

I fixed it by giving the path_corners where I wanted monsters to stop a broken target.

Props to Preach for pointing this out. 
What If 
wait is set to -1 on path_corners?
Doesn�t this stop the pathing? 
It does odd things instead, depending if its func_train or a monster_whatever.

Just for RRP guys;

The path code in RRP is more advanced as well; I ported the advanced pathing from extras r4 so there are more control entities for trains, they can be reversed, paused and so on. Wait -1 will teleport a train from one point to another and can be set per path_corner. Additionally, giving a path_corner an event key will trigger whatever targetname it's pointed at, when the train reaches that path_corner.  
And He Did! 
11:11:00 | <+Daz> gomap scampsp2! But not idbase kthx
11:11:20 | <+Daz> ikbase!
11:11:25 | <@onetruepurple> and not fucking dapakbase

5/5 bretty good, could use more Tarbabies though 
Re: 311 
The reason is because = "".

Find() always starts at the first entity in the list (1, the player).

It checks if the entity's targetname == "" which it does (because players don't use targetnames), so it returns the player. 
if you gave the player a non-empty targetname then the monster would find a different entity to walk towards... 
Thanks for clarifying the reason 
Oh Man 
It's been like 6 months since we had a hack. Here's a hack for...Quoth?

Now you can create entities which appear in your map when run under ID1, but not in Quoth. There's one simple application of this, plus the opportunity to go overboard with it instead! 
I was just wondering today how something like this would work. This should be mandatory knowledge for all future Quoth mappers. Thanks, Preach! 
Nice. A much smoother way than the Quoth detection in my levels. 
Lava Splashes... 
targetname "lava"
target "lava"
delay "0.099"

targetname "lava"
use "boss_death9"

why dis no work? :(
tested with a message on the relay, and it is indeed working, but no lavas. 
The function is not reusable. You might want to killtarget it quickly as well, since it increases the killcount at boss_death10. Note that while the function works without a Chthon in the map, you need to put one somewhere for the splash sound to be precached.

I had an idea for Jam6 that involved the lava splash, too. The opportunity is simply good enough to miss. 
Why is it not reusable? If you retrigger before 0.1 seconds it should just keep spawning particles. 
This thread is a treasure and should be pinned. 
that's a heck of a lot of particles! 
it would be glorious... if it worked. T_T 
Just use lots of tbaby_die2 
Rotating Objects Hack! 
GREETZ hax fans! Let's make things spin right round like a record baby.

This entity hack is actually pretty easy, it lets you make a rotating object in stock /id1/ quake, but is somewhat limited in what you can do. What we are going to do is make some non-solid, non-interactive rotating objects. Good for things like a ceiling fan that you will never interact with and just spins forever. I've actually used it before in my sm170 speedmap quite awhile ago, but it seems went unnoticed (negke hadn't heard of this method when I told him about it last night).


Ok, so first off, you need to make a func_wall fan object at the origin of the world. Make it's center at (0, 0, 0) in the world, this defines where it will rotate around. You'll need this entity's modelindex, so it may be best to make sure it's the first object in your .map file. As explained by some other hacks in this thread, the modelindex is a number given by Quake to each model in a level and lets us instance those models to other entities. The command 'edicts' in Quakespasm/Fitz/etc will help you find this number on entities in your level.

Now, where ever you want to have a rotating fan, place an info_notnull with the following properties:
"classname" "info_notnull"
"avelocity" "0 256 0"
"movetype" "8"
"model" "*1"
"modelindex" "2"

That's it! Obviously, use the modelindex of the func_wall fan you made. avelocity is the part that makes it spin, is the same thing that makes weapon items spin. Here we are spinning around the Y axis at 256 somethingspeed, this is good for a ceiling fan but you'll want to experiment with what is right for you! You can use negative values if you want to spin in the opposite direction.

Another key aspect is the movetype key being set to 8, this means MOVETYPE_NOCLIP in .qc, which is a movetype that allows objects to be rotated with avelocity.

Example .map and .bsp Enjoy! 
Thanks! We need fans in these hot, hellish environments! 
Really Cool! 
That Is Genius Scampie 
You better believe I'm gonna abuse that hack. 
Cool Stuff 
I just fiddled around with the rotation thing and you can totally have multiple objects, as long as they do not necessarily need to be shadowed. Even if you need 2 shadowed objects you can still do it with a bit of a caveat.

The source func_wall does not need to be at 0 0 0.

If it will only rotate on the z axis (world, which is y for the object, why is this shit mixed up, btw?) you can move it up and down on the world axis ( and if we want rotation on another axis of course that would work too, just move on the according axis) so that it does not overlap with another object there that needs to be lit.

Now you only need to move the info_notnull up or down counter the direction you moved the func_wall. For this to work the properly the info_notnull still has to be inside the world and ideally visible from all the points to the player where it would be would it not be shifted around. If that happens the object might disappear. That in itself could be used for some weird effects too though.

I was wondering if it might be possible somehow to give the info_notnull or the func_wall some kind of offset modifier so that the info_notnull can actually be at where the object should appear, without being shifted if the origin is not 0 0 0. 
is it possible to use it in conjunction with a func train to make a moving spinning blade trap thing? 
No :( 
the rotation values are odd because I'm pretty sure it's using Pitch, Yaw, and Roll, so rotation around the Z ends up as the second value. 
Yeah, I think that is right. 
I just made a clock in my map using this method. I noticed that the further away from 0 0 0 your func walls are the bigger the arc they travel in.

Also, there are other movetypes that also work, some that rotate as the object falls to the ground. Could be interesting to play with on a low gravity map.

Some more ideas for this, moon / sun / planets orbiting your map. A scale model of the solar system. Gears, or clockwork in maps. A fully sick car with spinning wheels. A spinning leek... I'm sure there are more. 
Back To The Future!? 
Here's a "hack"... in the id maps!

I was zooming around e1m4 when I noticed a funny looking block with an Ogre walking into it... Using sock's mod with path's visualized to show what is up:

Turns out, that block is a func_door on top of the first path_corner in a sequence the Ogre is trying to walk to... so it can never reach it and ends up sitting there forever!...

Until a trigger lowers the block out of the way. The Ogre can continue to walk out the door and eventually gets placed into a path_corner loop on the dock over the water. The end result is like a scripted sequence of triggering the ogre to walk out of the door on demand!


It's odd because it's very unlikely a player will ever notice this happen, the ogre walks so slow and the trigger that lowers the block is right at the edge of the water... In all honesty, if this were me, I would've just teleported that Ogre onto the dock when the player was out of view. But what id did here was make a basic scripted sequence with their primitive tools that only a few % of people might notice... But you might just hear the door open, and see the ogre lazily walk out and it makes the world so much more alive. It's wonderful :D 
That's Pretty Cool 
and the way monster teleporting works in vanilla is only slightly less of a goofy "hack" really. 
yeah, and mods as early as zerstorer 'unhacked' it and added progs functionality to just trigger a monster to make it appear.

id may have just never bothered developing anything better than teleport boxes because that's what they had in Doom. You built a long tiny tunnel to propagate sound into a room full of monsters to get them angry, then tagged a door in the room to open and reveal a teleport linedef and then just hope all the monsters eventually crossed it as they wandered angrily around said room. id probably thought having the 3rd dimension on their side to make monsters fall directly into the teleport brush was high technology. 
High Framerate Animated Textures 
Has it really been more than 3 months since the last hack? Well, good things come to those who wait.

Today's hack offers a trick to upgrade the 5 fps animated textures into 10 fps animated textures instead. This should benefit maps with waterfalls and lava flows a great deal... 
Notnull Hack? 
Im not sure I know this one, can someone explain it or point to a resource that explains it? 
A Primer On Info_notnull 
My intro to map hacks post uses info_notnull and mentions why we like it so much 
Awesome Preach! 
Thanks for posting this Preach! It will be interesting to look into at some point. Your waterfalls are already at a pretty high fps so I take it this wouldn't' do much/anything for them correct? 
abutton1, bbutton1, cbutton1....mind blown!

Whoa! func_wall.use changes texture...mind blown again!

Double wammy there Preach. 
Don't Go Chasing Waterfalls 
Thanks for posting this Preach! It will be interesting to look into at some point. Your waterfalls are already at a pretty high fps so I take it this wouldn't' do much/anything for them correct?

This trick is really for animations on BSP object, things made out of brushes. My waterfalls are in .mdl format so they aren't applicable to this trick. However, I think this will be great for making waterfalls in places where my model can't be used, e.g. in vanilla maps or spots where the waterfall has to be made to fit. 
I'll Stick To The Mdls I'm Used To. 
Ah okay I was figuring that was the case. Always excited to get a new map hack from you. I already have numerous ones from the past implemented in my current project! 
That's Deviously Clever 
Nice one! 
Could Make It Even Higher Framerate 
In theory you could go higher framerate and double it again for the framerate hack. just need to add another 2 layers of meshes switching at .25 and .75 seconds delay. I think I will have to give this a go at one point as well :) 
Monster Only Teleports 
Neat trick I found. If you place a trigger push with a velocity of 100 right in front of a teleport the player won't be able to use it (if its angles are right, you could always suck the player in for a neat trap!). If you then place a trigger_monsterjump a hair bit in front of it and give it the same forward velocity of 100 but an up velocity of only 1, it will negate the push and let the monster teleport. You could reinforce the concept by putting a func_illusionary in front of it with a unique teleport texture. If you want to make the teleport useable later such as after a fight, you can killtarget the trigger_push and the func_illusionary. 
Sort of a neat trick as opposed to TE_TELEPORT effect at either side of the ent being teleported is if your engine has a .alpha field you could "fade" him out while non solid, hijack his think to be the fade function until hes perfectly transparent, then transport him, and fade him in using the same function in reverse. If done with the right timing it could look pretty good, and you could throw in a EF_BRIGHTFIELD at the end for maybe the last few frames while transporting, and the first few while "rematerializing"....

If the engine has EF_ADDITIVE for blending, I think it looks even better. 
Invisible Teleport Randomizer 

targetname movingteleportdest1
target path1wp1
speed 200
avelocity "100 200 300"
solid | 0
movetype | 7
use train_use
nextthink 0.2
think func_train_find

Borrows code from the misc_teleporttrain to create a moving teleport destination that is invisible. Use in combination with a monster teleport box whose targetname is movingteleportdest1. Give a nice path above an area to drop in monster in a randomized locations. Put multiple monsters in the same long teleport box with only one teleport and you can cut down on trigger_teleport requirements, and add randomization. 
Oh And... 
make sure something targets it or else it won't move.

As an extension of this idea, you could have a teleport that changes destination by having it target this entity and giving the 2nd path_corner a wait of -1. 
You can teleport to monsters, even dead ones. :) 
And Items 
Fiends Hatching From Grunts 
So you give a grunt 'effects 8' and when he dies, he trigger spawns a fiend into his own location. 
Too bad you cant gib corpses this way... have a grunt spawn a zombie or fiend in a spray of gore! 
You Could 
Spawn a zombie, then after 0.05 seconds spawn a fiend at the zombie's position.

Best way would just be to use qc though so as not to inflate the monster count. 
Would be unwise to spawn large monster from small monster due to bbox Size difference. 
Yeah, qc would be good again to check for !walkmove. 
Public Polling 
So, which hack should I write up next:

a) A trigger which randomly selects between triggering "event_a" and "event_b"


b) A trigger_counter which can be reset and used over and over again.

I mean, eventually I'll get round to both, but which one should I do first? 
a, though b sounds more interesting. 
i can do a) myself already VERY hacky, i'm most interested in hearing your solution. 
A Is Just A Logic Gate Shooter With A Func_train Oscillating Rapidly 
Do b) 
You'd Think That 
but im sure there is a much more clever solution to it. 
Preach us probably accessing the video buffer for the screen and using the pixel colours as random numbers with 3 info_notnull entities. 
I Vote B! 
For I Have Touched The World..... 
// Try it...jump around on any map

void () test_touch =
if (other.flags & FL_CLIENT) bprint ("OUCH !n");

void () worldspawn =

world.touch = test_touch; 
Reusable Trigger_counter It Is 
From what I can see, there's been more discussion about the randomised trigger, but more explicit votes for the reusable counter. Since we live on a democratic message board, we will ignore the prevailing enthusiasm and go for the winner instead.

I've been playing around with the idea over the past week, trying to come up with the simplest implementation of a reusable counter. I think I'm basically there now, but one of the features requires a logic gate, and a flaw in my previous article on those has become apparent, so I will fix that first, and then the new hack will follow. 
Oh Goody 
Another two-fer! 
The Ol' One-two 
So the fixed logic gates are up at

The updated portion is highlighted in yellow. I've also updated the example .map at both to incorporate the update to the article, and to make the example map playable. All four gates are hooked up to example entity systems and can be tested in-game.

Now for the new stuff...
Not only featuring reusable triggers, but also triggers which you can interrupt to reset during their count.

Bonus content: What went so wrong in the original logic gate post to make Preach miss out a vital entity? I often use a "clean" copy of the QC source to test things out. Unfortunately, this clean copy is not quite 100% identical to the basic Quake source, and W_FireAxe is one place they differ. My "clean" version has a call to makevectors which the original Quake progs is missing. This doesn't affect the player code which has some redundancy, but the axe hack entity is not so lucky and started firing in a random direction. The changes to the article work around this. 
When you ask a question and then answer it before anyone had a chance to say something, that's usually a rhetorical device. Not today though, I just happened to crack the puzzle I set myself last time, and made the reusable counter work without a logic gate. Read the follow up article here:

Still not enticing enough? Well, the post links to an example .map file, so you can copy-paste the hack without the need to understand it! You want more? Well, the article even invents the anti-counter - an entity which acts like a trigger_relay until you've used it n times, rather than one which only acts like a trigger_relay after you've used it n times. If you want a crusher or trap the player can only activate a few times before recharging it, this does the job. 
Preach You Mad Man! 
All shall bow to the Quake hacks of the one they call Preach. This is Preach's world full of logic gates, high framerate clocks, and waterfalls (That only spawn on nightmare.)

Countless possibilities with this addition, thank you sir. 
Preach, I am in awe. 
I can't even comprehend any of this madness... You're basically the gandalf of map hacks 
or the map hack of gandalfs. 
or the enemy of compatibility... 
This Is A Public Service Announcement... 
or the enemy of compatibility...

Oh believe me, I spent a long time working round map hacks in Quoth - there are specific "shims" for maps which use hacks that subsequent version broke. It's also something that I do bear in mind when making changes to the code base - e.g. renaming OgreGrenadeExplode to MonsterGrenadeExplode would be appropriate in Quoth because Defenders fire the same grenades, but that would break a basic map hack which outweighs the benefit.

For everyone else I think it's worth repeating the standard reminder: Map hacks are for standard Quake only. There is no compatibility guarantee for any other mod. Do not use them in Quoth or AD or anything else. 
Sock had a strict rule that we couldn't use map hacks in AD. Made sense 
Very Fair 
I figured it was for vanilla Quake. The only hack that I currently readily use is the nightmare hack. I am currently mapping using AD and the hack works wonderfully. Actually, with triggers like monsterkill I can fix the kill count totals when playing on hard!

I know I use them at my own risk though. ;) 
Well, if you are mapping for a mod in development, that makes sense since you could just code up whatever you needed. Map hacks are cool to add surprises to standard quake. 
I am currently mapping using AD and the hack works wonderfully.

What happens when sock releases a patch that fixes a long standing bug in the lightning gun and as a byproduct breaks the hack? There are a multitude of ways that could happen: renaming the function, checking the current ammo rather than the cells or adding a new parameter to the function to name but three. All perfectly innocent changes which happen to break your map.

The issue is that the map hacks are not forward compatible - new versions of the mod might break the hack even if it works on current and past versions. This isn't theoretical, it happened in practice on maps between Quoth 1 and Quoth 2. The safety of the hacks in vanilla Quake also depends on iD never releasing another patch, it's just that after 14 years it seems a fairly safe bet... 
A Fair Point 
Would the example be the same with the Shambler magic lightning?

Either way, I suppose if a patch came out and it broke the NM hack and I was fully invested in my current project...I'd remove the nm hack components.

I fully understand the risks good sir. :) 
The only real thing to say in this instance is that you'll have to package your project with your version of AD to retain the functionality. Or figure out a way to implement your ideas without resorting to map hacks, if possible. 
Cause And Effect 
Either way, I suppose if a patch came out and it broke the NM hack and I was fully invested in my current project...I'd remove the nm hack components.

But if the patch comes out after you release your map, you're stuck. Unless you want to keep patching your map.

For their part, mods ought to look at the most popular map hacks and see them as features they ought to offer in a supported way. I'd guess that was part of what the no-map-hacks rule for AD was about - code the needed feature instead for all to use. 
Sock didn't want us relying on map hacks as patches and stuff could break the maps. If the mappers wanted a feature in their map then Sock would just code it into the mod. 
Something To Ponder 
I appreciate the advice. I may remove the NM hack. Luckily, the current project I am on I have yet to implement it...and this particular project I hope to publicly release someday.

Hell, I could always make a seperate version of the map that supports the NM hack. For now, I'll worry about Easy, Normal, and Hard.

Thanks FifthElephant and Preach again. 
Thats a doosey of hack Preach (and another two-fer no less). I see more awesomer puzzles in the future. 
Random Numbers 
Now, I'm more into my stats than most people, I know that. So for my upcoming random switcher hack, I decided to check just how random it was. I made sure that the hack generated some loggable messages I could parse, ran with -condebug, generated 10,000 random events and loaded them into R.

The results were disappointing. Although the number of "Choice A" and "Choice B" generated were nearly identical, the chance of getting "AA" (an A followed by an A) or "BB" was higher than getting "AB" or "BA" (all four should be 25% probability if the system was fair).

I had spent several nights trying to fix this with various reconfigurations of the entities, but never managed to make significant headway. Then I decided to knock up a quick mod which would spit out A and B into the console using the random() function directly, just to check. And of course it turns out to have this same issue but worse. So I will be releasing this map hack shortly... 
The Most Unpredictible Follow-up Post 
Here's the hack:

Whatever will happen next? It's impossible to predict, because I haven't hyped it for months or even thought of it yet! 
QC support for Notepad++, including Function List support and syntax highlighting: Tutorial & download
Have A Semi-working Hack That I Need A Little Assistance With 
I am making a false train using func_wall and info_null. The purpose is to get a couple of overlapping entities that behave like a train (follow a path).

I have a func wall for the model, 2 path_corners with each other as their targets, a trigger triggering it and an info_null with the following values.

use train_use
think func_train_find
speed 20
modelindex 8
model *1
movetype 8
nextthink 1
target stop_1
targetname me

the odd behaviour is, that when it gets to the first stop, it spazzes out and jumps forward and back among the path corner locations, without traversing them first.

any ideas? 
Possible Tweak 
Hi Shamblernaut, can you try something for me and see if it helps? Change the movetype from 8 to 7. It's a hunch, and it'll take a lot of explaining which I'd rather only type up if it's the correct fix. Thanks, let me know how it goes! 
how just about trying to use a true train?..

and yeah, the SUB_CalcMove function, which is responsible for setting up velocities and nextthink for the various pushers to use, is explicitly tied to MOVETYPE_PUSH(7) on account of its use of 'self.ltime' rather than 'time'.

movetype_push and solid_bsp(4) are kinda tied together in many engines too, so be aware that separating the two will often give engine-specific results. 
That worked a treat, thanks preach. I still need to sort out the sound not being precached, but any victory is a victory and I'll take it.

@Spike, using a true train doesn't allow me to overlap my geometry, which is necessary for what I'm trying to do. Also, thanks for the headsup about engine pushtype handling, I guess I'll just require people to run the map in quakespasm =P 
Existing Practice 
movetype_push and solid_bsp(4) are kinda tied together in many engines too, so be aware that separating the two will often give engine-specific results.

Don't all engines need to handle it already because of misc_teleporttrain, which does exactly this? I mean, yeah, it probably shouldn't be written like this, but we work with what we have... 
Teaching Old Preach New Tricks 
Mankrip - Thanks! 
Static Entity Shooting Scrag Projectiles 
is this a thing that's possible? I want to use it as an acid drop in my mapjam 7 map (quoth). 
Post #14 
Cheers Man 
Please use info_trap instead of a hack that we will unintentionally break with a future patch to Quoth. 
the scrag / wizard stuff doesn't work with info_trap :( 
Trap Sprung 
Holy Shit 

"modelpath" "progs/w_spike.mdl"

I thought that wizard / scrag magic was a particle effect.

my bad.
To Elaborate 
I was using the scrag shooting function like one would with a info_null as in post #14.

Didn't even consider using the trap function as intended. 
Invisible Water? 
has anybody made water with invisible(transparent) texture, just wondering because that might have some interesting uses. 
Just Try It. 
I'm interested of the outcome. 
But using q3map2, so probably not what you're looking for.

*waterskip Texture 
fuck, I misunderstood.

I feel like fiddling around in the progs could get what you want fairly painlessly. 
I asked in mapping help but maybe here would be better for my question.

In AD I want the Golem to only have melee attacks, no projectiles. This is listed in his mon_golem.qc right before the range attack code:

if (!self.enemy) return;
if ( < 1) return;

Now if either of those are true he will skip the code for firing projectiles.

I tested a modified AD progs by the simple addition of a return; above the "if" statements and got a melee only Golem. But that's not really an option.

The function is called void() golem_rockstorm =

Any progs.dat tricks for this? Even if it's not an "old" progs :-P

Could he fire the doggie's attack instead!!! I still need him to STOMP though... 
Don't Trick The Mods 
It's a bad idea to use map hacks against a mod which is in development. In effect you're trying to apply a hack to a moving target - the mod may change that code in the next version and break your hack. The reason that id1 hacks are acceptable is because id aren't ever going to release another patch for Quake, so all behaviours (even unintended ones) are unchanging... 
I bet plenty of custom engines break certain map hacks. I don't have any examples to hand tho - know of any? 
You write: "I want the Golem to only have melee attacks."
Then you edited the code and write: "I got a melee only Golem."
That was what you want. So what is wrong?

If you want to give him a different behaviour for ranged distance, then all you have to do is edit his ranged attack code. There is no TRICK needed. Just do it.
The Golem code works like any other monster code.
You first have to know what you want. Then do it. Yes, its that easy. 
I don't think I should "fork" the AD progs. I'd see that as a nightmare for a map(s) release.

Requiring players to duplicate their AD directory, replace the progs.dat with "my" version and then install maps and not get confused is it a bit much, yes?

That's why I was looking for an alternate solution.

I'll just put it on the backburner for now.. 
In Theory Or Practice? 
I mean, in theory almost anything could be broken by a determined custom engine. One that I worry about in theory but haven't ever seen break is the high frame-rate animation from
This relies on a global timer on .bsp animations. Given that some engines have removed the global timer on looping .mdl animations (much to my irritation) it doesn't seem impossible that the same might befall the .bsp ones.

The thing with a lot of the map hacks is that they involve tricking the QuakeC - and engines tend to preserve QuakeC behaviour pretty well. Most of the stuff that happens in a map hack is legitimate QuakeC, just unintended. I suppose any hack which involves the order of the list of entities would be vulnerable to an engine which changed the order to be non-deterministic, but again I've not seen it in practice. 
Was intended as a toolkit. That includes making your own stuff 
You mind if I send you an email with the map setup and why I want this?

No worries if you don't ant to bother. 
Go For It 
@FifthElephant, Sent 
My email addy is strange, begins with uw_ Don't ask, hehe 
Fun Fact 
The function trigger_reactivate is defined in standard QC but not actually used anywhere. In full the function reads:

void() trigger_reactivate =
���self.solid = SOLID_TRIGGER;

Can you think of an interesting hack to perform with the unused function? 
Kinn was complaining that you can't have disabled triggers in id1.

Couldn't you have a trigger with SOLID_NOT (SOLID_NONE?) and then come up with a way to use the above to activate a trigger that started disabled? 
The sophisticated 'super logic gate' idea Preach is about to come up with!

Or perhaps at least an easier way to do things like the switchable push hack and the like? 
Yup, It Was Hype For A New Hack 
New hack is a respawning trigger_once

The twist is that the hack doesn't use that function. What it uses is the fact that the function is redundant, and exploits what replaced it in the code.

I have come up with a different hack that uses the function since, watch this space... 
That's a really interesting article and could help with the usual complaints of not having the ability to have inactive triggers change states.

Cheers to you! 
A shoutout and a question.

First thanks for your tutorials. I used two in my RetroJam pack to great effect.

Second: I wonder if you or anyone else has ever considered completing the "From scratch" tutorials that were so informative on insideqc

I have no coding experience and wanted to jump in with that tutorial but the author never completed it. Maybe you know of another tutorial that could be a 101 starting point for newbs. 
But, couldn't you just have a trigger multiple that targets a logic gate?

The gate then could be turned on and off to turn the trigger_multiple's effect on and off. I'm thinking like toggleable shooters that can be deactivated or reactivated this way by toggling the trigger_multiple's effects (gate targets shooters). 
There already is an inactive triggers hack in stock id1. I think it was Preach's who triggers the trigger. 
More Shameless Hype 
But, couldn't you just have a trigger multiple that targets a logic gate?

The follow up article will discuss exactly this, it's almost, but not quite that simple... 
If toggleable 0/1 switches are possible, where is your 'fully functional computer processor within Quake' hack like there is for Minecraft! 
Correct me if I'm wrong, but the only thing stopping that ATM is the entity limit.

Aren't most of the logic gates already possible in vanilla? Albeit with some hackery. 
These hacks save entities.

Plus I'm sure Preach can add something nifty in the process, like multithreading support... :) 
Scratch Tutorials 
Second: I wonder if you or anyone else has ever considered completing the "From scratch" tutorials that were so informative on insideqc

I love the scratch tutorials, but the returns on them diminish steeply. The first one is a great way to show what's essential, how to go from a blank mod that doesn't work to the bare minimum that runs. By stripping everything back, it exposes at a glance what functions come built into Quake, which has a value beyond actually creating a mod from scratch.

The second tutorial is exactly what you want to follow up with - the lighting isn't an actual barrier to launching a map, but it is something that's broken in every map until you program it back in. But by the third, we're more or less reduced to straight copy-pasting the code we removed back into the game. It has stopped giving you things any conceivable mod needs, and started just copying Quake itself.

There probably is a way to continue the series of tutorials in a way that makes each instalment less about recreating Quake line by line and more about exploring what makes up all mods great and small. But personally I am not clever enough to pull that off... 
Activating And Deactivating Triggers 
Yeah, the follow up you all saw coming is here, how to turn last week's hack into a trigger which turns on and off, in a slightly better way than previous attempts.

There's some bonus content here as well, the map features a better logic gate. I need to write this up into a proper article, but here's the deal:

In the logic gate post a few years back, the idea was to have two entities that attacked the gate itself. One used player lightning to inflict a high amount of damage, and "kill" the gate (provoking one reaction) and the other used the player axe attack to do less damage, only "hurt" the gate, and so cause a different effect. Last year I discovered that you need a 4th entity to aim the axe attack and make it hit reliably, and on top of the extra overhead you need to keep the entities in the right order in the map or it doesn't work.

For the example map in the new hack, I had the bright idea of trying to replace the axe attack with something that doesn't have this problem. It turns out that shambler lightning fits the bill perfectly - it works just like player lightning but only does 1/3 of the damage. It doesn't even need ammo! There's also something quite poetic about the idea that the logic gate is now literally powered by different levels of electric current... 
Thanks, good insights. 
Trigger_hurt Speed Control 
It seems lately that each time I work on a hack, I discover incidental things which lead to another post. So hot on the heels of the past two posts, here's a hack that delivers something I'm sure was requested in the past: a trigger_hurt which isn't quite so slow

It's a two-for-one really, because there's a much better kill-trigger for void maps in there as well - a trigger that deals damage to everything it touches every frame. This fixes weird things where two monsters leap into the pit at once and one of them survives for a bit. 
Here Be Dragons... 
how to break a trigger_hurt?...
easy! use a teleporter while its hurting.

the teleporter causes force_retouch, which relinks the trigger_hurt while it is solid_not, unlinking it. because its solid_not, it won't get relinked.
when the hurt_on function then gets called, its .solid field is set back to trigger, but its already unlinked, preventing anything from re-triggering it (other than by using a force_retouch somewhere, forcing it to relink).
loading a saved games should have a similar effect.
this doesn't affect all engines... 
In fairness, the hack is actually making that less likely to occur, since the trigger spends a shorter length of time in the vulnerable state.

Am I right in thinking that loading a save is another thing that can cause relinking at inopportune times? I had a vague idea for a hack based on that, but it did play on my mind that some engines would probably fix the odd behaviour it would be relying on, and I never followed up on it.

I suppose you could also set up an info_notnull hack that periodically runs teleport_use, so that every so often things which have been linked wrongly get linked back in correctly again. Or am I missing something there? 
Fish Friday...Three Days Early 
It turns out all that stuff from the last few posts can also affect hack logic gates, because the hack makes them go non-solid, and a teleport at that point unlinks them. I can rework a simple gate to stay solid the whole time, but it was an essential part of how the OR gate worked. So the promised logic gate article is on hold until I figure out a new way to make an OR gate...

In its stead is a way to fix the rotfish kill count bug in unmodified ID1, which I think is kinda neat.

PS: can you spot how to make a flying shambler? answers on a postcard... 
If you don't care about adding more entities, you can also target an info_notnull that has "use" "boss_death10" to increase the death counter by 1. 
Brain Teaser For Preach 
Gravity change by map entities, or a way to reset the changelevel function after using the cvar hack without the need to reload. Or anything related to this. What's the whacky stuff we can do by hacking worldspawn... 
Oscar Academy Award� Winner Gravity... 
...will not be screening tonight. I've looked for a way and I think it's impossible. One of the things about gravity in particular is that the QuakeC is actively working against you to reset it. It's pretty much the first thing that worldspawn does.

On the other hand, your one opportunity to put something arbitrary into the console is the changelevel command, and that's equally well locked down in the engine. The function which sets the changelevel_issued command does it unconditionally, and the one place it gets reset is starting a new level. So you can't get more that one command a map, and you need to save one to restart the map.

It really is the two working against each other that sinks the plan. There is just enough wiggle room to change sv_friction in the following way: call your map "my_map_name" then create a trigger_changelevel with the key "map" "my_map_name;sv_friction 0.05". When you hit that trigger you restart the level, but with sv_friction set to 0.05 (getting the player to hit the trigger at the start of the first visit to the map, but not on the second visit, is left as an exercise).

Sadly, sv_gravity is the only cvar which this doesn't work on, because of the specific QuakeC code at the start of worldspawn preventing it. Unless you can surgically remove the worldspawn from your map, but I don't like the odds of pulling that off... 
New Logic Gates 
Hi all, big article incoming!

It's the much hyped replacement logic gate set-up. These logic gates aren't vulnerable to being broken randomly by using teleporter at the wrong time. If that's not reason enough to start using them, they support an unlimited number of outputs which you can switch between! If you want to be able to switch a button between 8 different targets, this is the hack for you.

Thanks to Newhouse for his proofreading and feedback in writing this one up, I think the explanations have come out much clearer as a result. A follow-up with the OR gate, AND gate and XOR gate will be posted shortly. 
Seems really neat. Can the player here the LG explosion, though? 
I Don't Think So 
Because it happens on the first frame of the server, I don't think the player gets a chance to hear it. In any case, you can put the boxes containing the logic gates far from the main level if it ever becomes an issue. 
Crosspost: Custom Door Touch Functions 
Hard to imagine that anyone doesn't follow the Mapping Help thread, but just so this thread remains a complete archive, a new hack on how to create a door with a custom touch function.

I've had this masquerading idea bubbling around for a few weeks now, but I had something completely different in mind for debuting it. That may have to wait another week, this one has already bumped the logic gates follow up off schedule once! 
Preach is on a roll....I feel a maphack jam coming on! 
More Logic Gates 
Another week, another article. I like to think that the production values on this week's article are above the normal standards for a map hack post. The test map looks pretty decent, the article has screenshots, flow diagrams, and tables. Plus it's the second half of the new logic gates post, this time with actual gates, the AND, the OR, and the XOR gate. 
very nice article! 
Above and beyond Preach, the layout is very approachable! 
Most Advanced Spambot Ever 
I'm a bit scared 
He He He 
It makes sense if you're reading posts from about a month ago in the thread. And yes, that would mitigate the issue a bit (although depending on how frequently you run the function some errors might slip by). In 1997 some might have objected that it slows down the game a bit on weak PCs, because it removes one of the optimisations in the physics engine. Doubt anyone would notice any more... 
We may have talked about this, not sure. I want to reproduce the light globe sprite in an info_notnull, because I've hit the static entity limit, but can't seem to find the correct modelindex. Air bubbles and explosions, sure, just no globe. Strangely enough, s_light.spr doesn't show up in the modellist, either. All thanks to makestatic? Surely, there must be away. 
I don't know about other engines, but fte has a 'precaches' command that should show give you the index easily enough.
note that s_light.spr will only have a modelindex if it was precached (and the order should normally be the same for any engine), so if its missing then that's because nothing precached it yet.
So make sure you have at least one light_globe entity otherwise you'll not be able to get a usable index for it.

Do be aware that any other entity changes might change the order spawn functions are called in (depending on your editor). Creation/deletion of doors/triggers/plats/etc WILL change your modelindexes too.
So you should perhaps consider knocking up some find+replace tool if you're going to be making a lot of changes.

Or just use an engine with higher limits. fte+dp shouldn't have any specific limit, while ericw bumped the static ents limit in quakespasm recently though I've no idea if there's public builds for that yet (if not, qss has a slightly higher limit). No idea about other engines.
That said, protocol 999 or dpp7 will cap out at about 2048 max static ents due to the limited sv.signon buffer size. Less if you have many non-static ents too, because baselines contribute to the same buffer. I could rant about how fte servers are immune to that issue, but I'll save that for another time...

If it insists on being invisible still, you'll probably also need to figure out some way to make sure that the entity is linked into the server's pvs nodes. I expect Preach has a tutorial for that somewhere, probably involving triggering a teleporter... I'm not sure if its actually needed though. 
Thanks, got it! 
Sleeping Zombies 
Do you think there's a way to make zombies start off lying down and only "wake up" after certain conditions are met? Something smoother than a hurt trigger keeping them incapacitated (not least because of the pain sounds). I was just wondering considering that freak glitch where zombies sometimes don't get up again but can't be gibbed, either. Something to make use of? 
zombies use walkmove to get up, so while you could probably create some sort of crusher that squishes into them for 50 damage at a time and then stops above them, that'll both knock them down and prevent them from getting up. you can then killtarget the crusher and they'll be able to move again.

however, walkmove also includes a down-tracebox from 22qu above so you'll need your crusher to sit at least 24qu off the floor, which is also more than the player can step.
so you might need to make your crusher as a stepped-pyramid so that your player can still step over the sleeping zombie.

make it out of clip brushes and it'll be invisible. many qbsps complain at that though.
a train that moves to a single path_corner will do it (with a really long/infinite pause), there's probably some better way.

obviously it'll still keep playing zombie/z_idle.wav every 5.1 seconds... and flicker between $paine11 and $paine12 at the sameish time.
alternatively, AD has some proper feature for it... 
Other Hacks 
There's a way to make a silent zombie corpse which can be triggered to wake up using SUB_CalcMoveDone. The problem is that it's always solid, and also wakes up (without playing the animation) if you shoot it. So you'd need to build a skip brush shield around it which you killtarget, which is pretty much the same as putting a zombie inside a skip shell then hitting it for 25 damage at the start of the map. The skip shell prevents it from standing up, so you don't need to keep injuring it.

Anyway, if the marginal benefits of silence and waking up the instant you trigger it are worthwhile, the entity goes like this:

"classname" "SUB_CalcMoveDone"
"origin" "240 -64 56"

//finaldest must be the actual origin
/you want the monster to appear at
"finaldest" "240 -64 56"
"think1" "monster_zombie"
"use" "zombie_paine12"
"targetname" "reanimate"
"frame" "172"
"yaw_speed" "20"
"view_ofs" "0 0 25"
"flags" "32"
"takedamage" "2"
This Thread Delivers 
Thanks, guys.

Ineed, this only works in certain special situations due to the clipping/skip box thing, not for zombies lying around in openly accessible areas (=on the floor). For the spot I have in mind, however, the hack is just perfect. 
Preaxch Delivers 
He's the best. 
Custom Bmodel-type Entity 
Another noobish question that I feel has either been answered before and I'm too dumb to find or can't remember.

I know how to create custom stuff based off other entities using their model/modelindex values, but how do I make an info_notnull brush entity appear in the first place - visibly, that is. A function to get it started on the actual bmodel, like InitTrigger for trigger volumes.
Thought I could make a simple nonsolid prop that's doing something or nothing depending on the touch function. Problem is nothing shows up in game. 
I Believe 
You need to use a func_illusionary hack. 
Displaying A Model 
func_illusionary has the problem that it makes the entity static straight after, so you can't make it interactive.

Probably the best thing to do is to use
to create a visible entity. If the "model" key added to your brush entity by the compiler is "*1", you need to use modelindex 2 (0 is no model and 1 is the world, 2 is the first "free choice" slot).

You'll probably need to handle any interaction in separate entities (e.g. killtarget this entity) - InitTrigger interferes with this trick, likely because it calls setmodel. 
What I mean is having a brush-based info_notnull show up in game like a normal entity would - instead of 'visually cloning' an existing entity in a point info_notnull. All in one edict if that's possible. It appears a brush info_notnull strips itself of its own model/modelindex properties unless if used as a trigger volume (the model=bbox part in this case). 
Trigger Volume 
The trick does work with a single brush-based entity (referencing the modelindex of its own model). It is - like you suggest - when you turn it into a trigger that things go wrong, because the trigger is trying to do its own thing with the model code which interferes with the modelindex hack. If you didn't want a trigger, you'd probably be OK. 
To avoid a possible misunderstanding: I'm not using any trigger stuff, just mentioned it as an example.
I can't seem to get it working as a visible entity just like that, even if I make the info_notnull reference its own modelindex (unless I'm doing something fundamentally wrong and can't see it). That's why I thought perhaps there was some neat think function to run (in a similar way that InitTrigger that makes the bbox appear); sort of like "think" "func_wall", for instance, but without the hardcoded behavior this would add.

The weird thing is, I'm under the impression that for a while I had some floor bits show up just being brush info_notnull without any extra fields, but at some point during development this ceased to work. IIRC, anyway... 
Brush Based Entities 
If you add a brush entity with classname "info_notnull" it gets translated by the compiler something into this:
"classname" "info_notnull"
"model" "*1"

What may vary is the number after the * in the model key. What you want to do is add keys to that brush entity so it ends up like this after compilation
"modelindex" "2"
"mdl" "progs/player.mdl"
"think" "SUB_regen"
"nextthink" "0.1"
"classname" "info_notnull"
"model" "*1"

The tricky part is that you need that modelindex key to be 1 larger than whatever number the compiler decides to put into the model key. The numbers are given out in order by the compiler but if you delete other entities or do something to reorder them in the .map file it may change.

If you do all of that, you should get a visible entity which is only different from a func_illusionary because it is non-static and so can be killtargeted or given a use function. You can probably move SUB_regen into the classname slot and use a different think function as well. However, bear in mind that many other hacks (like the aforementioned trigger stuff) does break this hack, it's pretty fragile. 
Timed Power-ups 
We know its possible to make any item respawn, but is it possible to make power-ups last longer or shorter than the usual 30 seconds? For example a biosuit that lasts a minute, or a quad damage that's only 20 seconds. Can this be accomplished? 
Thanks Preach 
Finally got it to work. Apparently the "mdl" field is crucial whereas "model" doesn't have to be specified in this case. This is different than with point-based cloning which got me confused. In game, whatever is referenced in "mdl" is copied over to "model" as well, so I set it to "*1" (or rather the respective number of the model) instead of player.mdl; either seems to work as long as the modelindex is correct. However, the hack also required me to set "mins" and "maxs" for the entity to be drawn. The "think" function, on the other hand, seems only necessary if the entity is supposed to be used further, e.g. for a touch action.

Playing around with mins/max/size/origin made me curious as to whether it's possible to customizable trigger sizes from point entities like in Quoth...

Orl: I briefly tried it a couple of years ago. If it is possible, then at least it has to be more complicated than simply calling "powerup_touch". You can replicate the visual effects like that, but not the actual powers. 
@orl, yes increase the nextthink to respawn,
if ((self.classname == "item_artifact_invulnerability") ||
(self.classname == "item_artifact_invisibility"))
self.nextthink = time + 60*5;
self.nextthink = time + 60;

and for each pwoer up theres a *_finished timer

this is in items.qc 
Thread title "Teaching Old Progs.Dat New Tricks" means needs to work with original progs.dat, typically via entity/think/field abuse.

It's a shame you don't play single player maps, some like negke manage to do seemingly impossible things in maps that work in original Quake. 
Is there a way to place a static corpse in vanilla quake? Like a 3D model of a killed grunt or something? Is there a way to add custom entities? if so is there a place that has models of dead grunts or enemies?

You can do a corpse in a map. Do a func_illusionary and set the model (like progs/player.mdl")and frame number (like 169).

In vanilla quake there is no way to add custom entities. 
Interesting, thanks. I'll have a play around :) 
So i create a brush entity, set it as func_illusionary, and then add the keys "model" and "frame" ?

Like this? 
Create a point entity, set the type to func_illusionary and yes change the "model" and "frame" (it *may* be "mdl" if "model" doesn't work).

Like if you were creating a monster. 
(There are differences between TrenchBroom and Jackhammer. In Jackhammer, you create a point entity and change the entity type. I would assume you can do that in TrenchBroom, but couldn't swear to it.) 
Ah yep it works! great. Is there a place that shows the various model names? like gibs for example? 
Open up pak1.pak in Pakscape 0.11 and look in the progs folder. To find out frames, you would have use QME to look at the different model frames.

Without opening a model in QME, it's gonna be hard to pick the frames for most models as all the monsters have dozens of frames.

You also may want to set "angle". 
amazing thanks, that should give me everything I need to make some nice corpses...

I tried setting angle as -1 and rotating the entity but it doesn't seem to change the angle it appears at. Say I want the player model to appear lying on its back facing upwards - shouldn't angle -1 do this? 
Also it seems like some models work and others dont. The soldier.mdl doesn't seem to work at all and the map wont compile.

Could this be something to do with quakespasm having less models in its pak0.pak and having them in a pak1.pak instead?

It seems to have the paks reversed compared the original quake paks 
It Has To Be Precached 
Include at least one monster_army in your map.

Set yaw like normal to rotate the corpse.

-1 won't do anything since that is a special case for doors. Set the frame correctly and the model will be in one of its lying poses. You may want to check out the qc files to see which frames are death poses. 
ok cool, thanks. I tried adding a monster_army but now I seem to be having a problem of the entities disappearing when I select something else. Using TB2. None of the entities I've created are visible (I tried show all in the view) and the map is still failing to compile and citing lack of precache)

Here's the map file:

as soon as I deselect the func_illusionary entities they seem to disappear... 
"angle" is typically 0-359 like degrees for non-door/non-platform entities and operates as yaw (like pitch/yaw/roll, the 3 different x-y-z axis in Quake). 
func_illusionary was only really expected to work on inline models (ie: those submodels baked into the map). As a result it doesn't bother to precache the model (these are implicitly precached by the server).

The exact set of models that are already precached depends on the order that entities are loaded. So for instance you can use progs/soldier.mdl ONLY if there was a monster_army entity preceding it. the player's various models (player.mdl, eyes, backpacks, projectiles, gibs, etc) are precached inside the worldspawn entity's spawnfunction which is normally guaranteed to come first.

while there are engines that will automatically precache stuff on demand (ie: dp+fte+qss), these engines will generally warn, so its not something you want to do other than as a last resort, plus people hate engine dependencies.

func_illusionary forces angles to '0 0 0'. You cannot change the angles without qc.
If you want that then there's a more complex way using info_notnull, but figuring out the correct value for the modelindex field is a nightmare. 
ah ok cool. That should solve the caching problem. Not sure why the entities are disappearing though... 
Also how do I work out which frame to use from QME? QME gives me frame names like "deathc11", but the frame key needs a number. Is there a good way to work out what the frame number will be - I tried counting down from the top but it didn't give me the frame I was looking for. Say I want to use frame "deathc11" from the soldier.mdl - which number would I enter in the frame key? 
QME: Bottom Left corner when you select a frame, it says "Frame: 005 walk1". You have to click on the frame otherwise it doesn't say, haha. 
Ah yep, perfect. thanks! it works.

Now I just need to work out why the entities disappear after I select something else... seems very strange 
Undefined Point Entity 
Maybe TB2 doesn't see func_illusionary in its fgd file as a point entity since ot is only defined as a brush entity...and deletes it! Protect you sillt users from yourself. Ha, no its probly just a bug...ask about it on the TB thread. 
Disappearing HexenMapper 
as soon as I deselect the func_illusionary entities they seem to disappear...

Check the View menu upper left side of 3d window. Make sure you somehow didn't accidentally uncheck func_liiusiionary. 
Combining Two Hacks? 
So here's a conundrum: there's two map hacks I'd like to combine, namely the one for delayed/dynamic entity spawning ( and the one for rotating brush models in stock id1 ( Both of them work properly on their own, but combining doesn't quite work as it means trying to turn an info_notnull into another info_notnull (to expand, the entity doesn't stay hidden until triggered like it should because it's already an info_notnull with the proper fields to act as a rotating, visible brush).

I even tried a number of hackier methods, like making a specific texture for the brush entity with the starting texture completely transparent and the secondary (+a) texture, then triggering the func_wall so it would change texture- no go. The original model will change but the 'cloned' rotating one doesn't copy it, and triggering the rotating model does nothing. Am I totally out of luck here? 
^To add on to that, after a bit of fiddling it turns out you *can* change the texture from the +0,1,2... set to the +a,b,c... set on the cloned model by adding 'func_wall_use' to the 'use' field on the info_notnull. That would normally make things very simple, as one texture set could be made transparent, but apparently animated textures with alpha masking isn't possible (at least in Quakespasm) due to conflicts between the required first character- { tells it to take color 256 and turn it invisible, but then ignores any other special character; likewise, + allows for an animated texture but doesn't allow alpha masking.

Back to square one, I guess. 
Delayed Rotator 
classname info_notnull
avelocity "0 90 0" //spinning the whole time
nextthink "999999999" //otherwise func_wall(read: movetype_push) will not spin/move. this persists through both spawn functions.
think "SUB_Null" //just in case someone leaves the map running that long. note that it'll stop spinning, but at least it won't crash.
model "*1" //not visible until func_wall uses it
modelindex "" //MUST be omitted/blank/0, otherwise it'll be visible as something BEFORE its triggered.
use "func_wall" //what to call when triggered
targetname "spawnit" //what to trigger

will give you an invisible info_notnull that effectively becomes a rotating func_wall when triggered, is the theory.
(if you killtarget a normal func_wall at the same spot, you can make it appear as though it simply started rotating).

note that if there are any entities inside your pusher at the time that its triggered then those ents will get trapped and maybe block the rotation.
due to engines that don't support proper rotation physics, you should probably just make sure the player can't walk through it with eg a clip brush surrounding the area. 
Works in theory but doesn't quite work in-game, unfortunately. Copied it exactly other than the targetname- it acts like a standard delayed func_wall, solid with no rotation at all; including the
'movetype' '8'
field from the rotating brush hack was my first thought but that didn't change anything. 
The problem with your current approach is that the appearance of your entity isn't caused by the info_notnull spawn function, it's caused by your hacks. So there's no benefit to delaying the spawn function. You would need to delay your hack, but there isn't a function which can turn the hacked values on or off, our only opportunity to set them correctly is the initial load.

Instead, we need to think laterally. Go back to the original rotating entity hack, and then add an "origin" key to the entity of '0 0 -4000' - this probably positions it a long way below your map (if your map goes that far down choose another coordinate which is outside the map). This way the entity is present, but the player can't see it.

Then we add a "use" function to the entity of "SUB_CalcMoveDone". The idea is that rather than spawning the entity mid map, it will always exist and we will just teleport it into sight when needed. You can use the "finaldest" to specify the coordinates you would like it to appear at.

Bonus hack: if you are using the rotator hack, but would instead like to stop the rotation at some point, you can use the "use" function "SUB_CalcAngleMoveDone" to do just that. You can't start it again though... 
Works Fantastic! 
Man, I dunno how you folks figure out this stuff. Way above my head. It works great, though; can't tell what position rotation-wise the entity will be in when the player triggers it and causes it to teleport, but that isn't a big deal at all and I'm sure a number of neat things could be done by loading up a bunch of entities and teleporting them in while killtargeting the previous in order- might be heavy on the entity count but I'm not worried about that right now. 
Neat. As a matter of fact, I tried to get the same effect (sun gem), but didn't succeed. Seems SUB_CalcMove* has some unused potential. 
Praise The SUB_CalcMoveDone 
I'm actually planning to write a whole blog post just on this function, it's the best! 
Changing The Kills/secret Totals? 
Not sure if I'm just bad at looking for information or figuring out Quake C, but I couldn't find the answer to my problem:

Is there a way to change the number of kill/secret totals midgame? I'm working on a map with branching exclusive paths, meaning that you can't have all the secrets and kills in one run. I was hoping it would be possible to adjust the total counters for the kills and secrets upon choosing a path, so once you finish the path, you can still get a satisfying end screen with all the kills and secrets you can get for that path.

If that is not possible, the next best thing, I thought, would be to just trigger every secret and use the boss_death10 function for every monster one can't kill on a chosen path.

I'm just having a surprising amount of difficulty triggering the secrets in the desired fashion. I'd like the secrets to silently trigger (no sounds, no messages) once I choose a path.

There is a problem, however: There HAS to be a sound for the trigger_secret, it can't be set silent. It's not necessarily a problem however, if the secret is triggered so far away from the player that it's completely attenuated.

Another problem is the message "You have found a secret area!" Well, I figured I'd just find a workaround solution by just having the trigger_secret display a single space as its message. So the silent triggering problem solved, kinda.

Problems arise, however, when I DO want the secret to be normally triggered in a path where the secret is attainable. Since I have set the trigger_secret to display a blank message, I thought I'd just create a trigger_once with the message "You have found a secret area!" inside the trigger_secret but that creates a new problem: whenever a trigger_once displays a message, it can never be silent, either, even with the "sounds" key set to 0! So, when I touch the secret, I hear both the normal "secret" sound and the message sound from the trigger_once.

So that is where I ran out of juice and turned over to you guys: Any ideas? Is there a way to make a custom silent trigger_secret out of scratch with an info_notnull or something? I'm too confused right now to figure it out myself. @~@ 
There's no way you'll get a hack that changes the secret count or monster count mid-map. It's really hard to do even if you're making a mod for the game, because of client-server separation. The QuakeC always changes things on the server side, and relies on the engine sending updates to clients. The server by default only sends the secret/monster count when a player first connects. The code you need to manually send an update to a client isn't contained in the vanilla progs.

A hack to make a silent trigger_secret is pretty standard though. Add the following key

"sounds" "-1"

How it works: By setting an invalid sounds value, we skip the code which default the key to -1, and skip all the code which sets a path to a sound file in "noise". As long as "noise" is unset, the actual trigger code remain silent.

However, I have a better plan than that. It turns out you can create point entities with the classname "trigger_secret" (like a trigger_relay). Imagine that you have exactly one secret on each of your branching paths. Alter your map to contain a single point trigger_secret, and in each path's secret area, place a trigger_once which targets it.

This pattern easily generalises to two or more secrets on each path, so long as every branch has the same number of secrets, they can share the trigger_secret. And if one of your branches has fewer secrets, you could use the silent trick, but why not just add some more secrets to balance it out! 
we skip the code which default the key to -1
should read:
we skip the code which default the key to 1 
Monster Counts 
You could place trigger_teleports under every monster.

Go down path 1, teleport monsters from path 2 over into positions on path 1.

Go down path 2, teleport monsters from path 1 over.

You'll run into problems such as having monsters on paths moving off the teleporters, but you can overcome this by trapping monsters temporarily in a func_wall fence. Once the path is chosen and teleports are done, then killtarget the "fences" to let the monsters roam freely again. 
Another Way 
of using Qmaster's idea would be to put all the enemies in teleport boxes, and kill the teleport destinations of the other paths after the player can't go back to take another route.

For the enemies that won't fit in other routes or if some routes you want them to have more enemies, you can killtarget the ones of the other routes just before the exit as no one will notice the numbers growing out of nowhere. You can do the same with the info_intermissions so they show a different scene depending on the exit. 
of using Qmaster's idea would be to put all the enemies in teleport boxes, and kill the teleport destinations of the other paths after the player can't go back to take another route.

Isn't there a problem that in vanilla you don't have multiple targetnames? If you have a single trigger_teleport linked to two info_teleport_destination entities they must have the same targetname. When you killtarget one, the other gets removed as well. I think you need a separate trigger_teleport for each destination, and killtarget that instead (or just only ever trigger one of them).

I mean, there's a way to do it with "use" "SUB_Remove" added to just the first info_teleport_destination on the map, but any hack that is depending on the order of entities in the map is unpleasant to maintain... 
Thanks Guys! 
Why didn't I think of using shared trigger_secrets for each path's secrets; that's genius, Preach! :D Thanks also for telling about the -1 value for the sounds key. I had tried numerous other integer values in vain, from 0 to larger ones, but hadn't thought of negative ones. You're a lifesaver, thank you! :)

Thanks for the monster teleport trick, Qmaster! I had actually read about it somewhere else in this forum, if I recall right. I guess that's really the best one can do in an unmodded game. o:

Actually, I had also read something about updating the secret totals in the mapping thread, in a post written by Preach, actually (post number 4316 from the year 2005)! ;D Something about servers, clients and SVC_UPDATESTAT, which made me think something like "wait, don't servers n' stuff mean multiplayer stuff" but I guess the singleplayer runs on a server/client basis as well, so I guess there really is no easy way to modify the totals.

Anyway, too bad I have some monsters present only in one path. Seems the only thing I can do is add the kill count to the right number after choosing a path or right before ending the map (killtargeting the monsters didn't increase the number of kills in my tests, so I'll have to go with boss_death10). Maybe I'll go with right after choosing a path, so the player can keep looking for enemies in a given path before exiting the map to make sure they've exterminated them all. >:D 
Spare Monsters 
shove a trigger_teleport over the untaken paths (one per). trigger it when you feel evil.
all monsters within the triggered teleporter will be teleported to a single spot, telefragging all of them instantly without needing to do anything per monster.
bonus points if you can come up with some logical reason for the gibs to appear in front of the player. spontaneous fountains of gibs! 
Oooh, I like it! It gave me the idea of adding a Doom 3 like teleport sequence at the end, where the player flies through a hellish shower of red. 
sn't there a problem that in vanilla you don't have multiple targetnames? If you have a single trigger_teleport linked to two info_teleport_destination entities they must have the same targetname. When you killtarget one, the other gets removed as well. I think you need a separate trigger_teleport for each destination, and killtarget that instead (or just only ever trigger one of them).

I forgot that. I have done it with using trigger_once or multiple as intermediates but it was for func_walls and triggers. That way for one route the end entites are killed and for the other routes the intermediates. Teleport destinations can't use intermediates so in this case it cannot be used.

What could work is to put one trigger_teleport for each route on each enemy's box (all of the same route with the same targetname) and the destinations on the desired points and kill the triggers after the route is chosen. The downside is that no enemy can be put before that if only this method to deal with the enemies is used, can contribute to reach the limit for brush entities, and that teleporters have to be activated all of the same route at the same time. The upside is that it is quite fast to do.

killtargeting the monsters didn't increase the number of kills in my tests Interesting, i thought it did. Then try telefragging them like it does at the end of e1m7. 
Other Lethal Weapons 
Although not quite as spectacular as teleport gib fountains, there's a trigger capable of killing all the monsters within a trigger here (the second variety): 
Ambient Sounds From A Point 
Can we do them?

For example, the regular torches and fires in quake create a sound that decreases as you walk away, and originates from a point in the map.
Can we do this with custom sounds? Is it possible in id1 or do we need to code something? 
Need To Modify Progs. 
I'm not entirely certain, but to my knowledge, any sound you intend to use in Quake must be precached, and this is done in your progs file. Thus if you intend to use a custom you must modify the progs.dat and therefore must create a mod in essence.

Arcane Dimensions apparently works some black magic to precache any sound you place in the ad/sounds folder and thus you can use your custom sounds without further altering the AD progs. It also supports attenuation (sound at a distance) with the speed key.

In summary, this has already been done but to my knowledge cannot be done in ID1. 
HexenMapper: something like in #8

You can, for example, use a 'notouch' trigger (ideally point entity) with a "use" "train_wait" or "use" "plat_hit_bottom" field or the like, and a corresponding "noise" "ambience/fire1.wav" key, provided the sound is precached as Redfield says. If it's a looped sound, it'll play forever from the origin of this entity, although it'll have a different attenuation than regular ambient sounds. As a bonus, it also possible to killtarget it if you want the sound to stop. 
Any Way To Compile The Func_etc? Like The Fields... 
For doors... The "effects" field... I would do this. I don't want a flame war... I have a sever impediment... It is not laziness...
It would be awesome to be incorperated in the Entity def's and qrk. files etc

Ric... Mapper since 99 
New Post: Five Statues Challenge 
Got a challenge from a reader of the old blog and I can't resist a challenge. The basic premise is to have five statues in the map, where the most recently touched one is selected, causing it to be lit up.

It's a real multimedia extravaganza as well today, with a full write-up, an example map and even a video, so come on down! 
Weapon View Angle/Pitch Fix? 
While I know of talisa's/seven's nail-position fix which offsets the NG's & SNG's nails to come out of the barrel instead of your face when aiming upwards, I miss such a fix for every other weapon, especially the GL, which makes shooting upwards a PITA. I'm no coder and wouldn't even try to mess with the source code/progs.dat. So by request, is anyone else up to the task to do it? Thx in advance. 
Nice Preach 
I'm doing exactly the same thing in my current map, except with the AD entity state system, wouldn't have bothered ever trying in vanilla hah. 
Follow Up: The Alternator 
Hot on the heels, the promised hack that lets us ignore the order the entities are placed in the map, but still dictate the order that triggers fire.

The article also includes how to make an "alternator" - a setup where a single input trigger switches between activating two different targets. 
Brain Teaser For Preach 
Imagine you have several shootable triggers or buttons and want to fire an event once a certain total amount of health has been depleted. The damage done to the triggers transfered to an independent source, so to speak. So you can shoot each a random number of trigger a random number of times and once the overall health depletion reaches n, the event fires. Basically like a counter based on "health" instead of "count". > W_FireAxe notnull hack
W_FireAxe hits a func_door. = 1000 or 2000 etc.

And voila, just add func_buttons. 
but, don't you want the player's actual weapon damage to matter? E.g. shooting it with 10 nails should cause less total damage than 10 rockets. 
Make as many "shootable buttons" that you need. Select all of them, turn them all into one func_door with a health value, give it a target, set lip equal to bounding box so it doesn't move. 
The sum of all damage done combined. No idea if it's possible, and the applications would certainly be limited. For the lack of a better example: a machine needs to be damaged by a certain amount in order to be charged or explode and there are several exposed shootable parts. You can focus on a single one, or shoot each of them equally - the event fires once its global health is depleted. 
Exactly was @ metlslime.

But yeah, turning them all into a single door or button should work. Though what happens if they are supposed to be spread all over the map 
yeah, will you exceed max efrags and it disappears? I think in modern engines the efrag issue is solved and it is always drawn maybe... 
Spread All Over 
Nothing as far as I know, so long as the lip is set right for whichever movedir is set. I can't recall if func_button has an option to be silent in vanilla, so a func_door probably would work better. 
One Doesn't Tease Preach's Brain With Trivial Matters! 
And yet, I have another possibly simple or already-answered-but-I'm-too-dumb-to-find question: how to spawn fully functional movers like trains, doors and plats half-way through the map? Basically invisible until triggered and then working like normal entities. Think "use" "func_wall" but without being thwarted by precache functions. 
I'm indeed stupid. It should work just fine that way as long as you override the sounds. Or is there anything more to it? If not, please delete me. 
inline models are implicitly precached, so those are not an issue for doors/plats/trains/etc.
while they'll have a model string set, their starting modelindex will be 0, which means they'll remain invisible until they're properly spawned.

regarding sounds, you can just have a second door/plat anywhere else in the map, its sole purpose being to precache the required sounds.

a bigger issue is that if you're using use+targetname, you'll have no way to clear said targetname before the use is called.
this means that plats will need to be triggered twice (one to spawn, once to activate them so that they can be used).
doors are more problematic - you'll need to manually create a trigger field around the missing door to allow it to open, and you'll need to spawn that trigger field the same way as the door otherwise they'll spawn the door when you walk through them the first time. 
Reaching back to this post from 2009 and trying to understand something.

Would this allow for a silent trigger_push? My set up is:

classname info_notnull
use InitTrigger
touch trigger_push_touch
speed 500
angle 90
spawnflags 2
targetname test

Mark V and Quakespasm are still complaining about not caching the ambience/windfly.wav sound file. I thought this was the whole point of this hack.

Just put a trigger_push out in the void and it will ensure that sound is precached and avoid the warnings. 
Yep, that's in the map off in a tiny room but the hack'd entity plays the sound in that case. 
Yep, that's in the map off in a tiny room but the hack'd entity plays the sound in that case. 
Different Intent 
The intent is to make a delayed spawn trigger_push. The sound precache is the reason we have to do something a bit different to the standard "classname as use function" hack, it's what we're trying to work around. But the lack of sound is not intended - I would pair this with a regular trigger_push hidden somewhere in the map to perform the precache and remove the warnings.

You'd have to be pretty creative to get rid of the flying sound, only thing I can think might work is finding an entity hack that sets fly_sound on the player to an impossibly high value using ltime shenanigans on a doctored movetype_push entity. Haven't quite cracked that yet.

On a related note, this has reminded me of an undocumented Quoth 2.2 feature: you can specify the sound a trigger_push makes using the "noise" key. You can create a boiing! noise for jumppads, or using "misc/null.wav" will prevent any sound being made. Will write that one up when I get back... 
Alright. I was afraid of that, but luckily it's for academic purposes not a real project. Great news about the noise keys in Quoth 2.2 That does open up some possibilities. Thanks for the response.

I hope you get a chance to play my 100b4 entry. Lot's of sound work went into it. 
Cool Beans 
The pack is next on my list, so I'll watch out for it! 
Func_breakable In Id1 
Hey everyone :) So earlier someone on the TB discord asked if it was possible to make a brush that acts like a HL style func_breakable so I did some fooling around and figured out how to do it! Now this is pretty easy stuff that probably isn't really worthy of going here but I'll post about it anyway lol. So here is how you do it, you make a func_wall as you would normally do, then after you've made it you add a few keyvalues to it. First add a takedamage key and set it to 2, that allows it to take damage, obviously. Then you add a health field and set it to however much health you want the breakable to have. Then when it's health reaches 0 it will try to call the function in the th_die field, if there isn't one the map will crash as I found out :D So add th_die and set it to SUB_Remove or any other function that calls SUB_Remove at some point, depending on what your needs are. Optionally you can add an armortype and armorvalue to give the breakable damage resistance so it can be broken with some weapons but not others. I haven't exactly figured out how to customize the sound it makes when you hit it or break it yet but I will keep trying and see if you can do it without needing a mod 
Previous Post Continued 
So after a little more discussion I've figured out how to add sound playback to the breakable, so the full setup looks like this:

takedamage = 2
health (whatever you want it to be)
armortype/armorvalue (whatever you want it to be
noise (whatever sound you want the brush to make when you hit it but don't break it)
th_pain = train_wait (plays sound in noise field whenever you hit it)
th_die = SUB_UseTargets (targets 2 separate info_notnull's that play the sound you want to play when the object is broken and removes it, respectively)
target = the name of the 2 notnulls

Notnull 1
targetname = whatever you put in the target field of the breakable
noise = the sound you want to play when the breakable breaks
use = train_wait (play the sound when triggered by the breakable dying)

Notnull 2
targetname = same as the first one
killtarget = name of the breakable
use = SUB_UseTargets (remove the breakable when this gets triggered by it dying)

Please feel free to correct me if something I put is incorrect, I'm still pretty new to q1 mapping and map hacks especially. But map hacks are really fun and I've almost become more interested in them than actual mapping at this point (but not completely though) :P I'm also trying to think of how to add rotation to a turret hack I made last week but I haven't really checked any of the quake c sources related to rotating functions to see which ones I might be able to use 
Hi Therektafire 
That's a really well constructed and described hack. Welcome to the thread!

In terms of rotation, a warning and two pointers. First warning is that standard Quake just doesn't do collision on rotation. The amount of highly specialised code that mods apply to get even crude approximation of rotating solids, I wouldn't expect a hack to be able to get anything like collision working.

If you just want visible rotation things are better. There are already suggestions in this thread about how to use avelocity for simple looping animations. If you're looking for something more triggered, you might want to look at SUB_CalcAngleMove. Although any entity which used the function got cut from the final release of Quake, it's still available for hacks to use.

Alternatively, you might want to look into the AI functions if you'd like rotations that follow the player. You need to set quite a few keys on an entity to trick the game into running some of the built-in AI stuff for turning to face an enemy, but it should be possible. More advanced stuff, but something to get your teeth into... 
Having your breakable also create some info_notnulls using external .bsp models for rubble and have a movetype 6 would be cool too. Can't remember a good way to give them starting velocity at the moment though and still be triggered on break. 
Thanks :) I got the idea for the armor from one of your articles I may add it to the turrets too if possible. Speaking of, I will definitely look into the AI turning/rotating functions to see what I can do with them 
How can I make worldspawn shootable and killable?
Perfect accuracy gameplay challenge... 
A Trigger Curiosity 
So, I was idly tugging my way through some of the vanilla QC files, and noticed functionality I was hitherto unaware of!

In the blurb for the trigger_once entity, it says this:

if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0.

The code to do this seems to be in there, but I cannot recall a single time in the id1 levels where I noticed this behaviour.

Is this used anywhere in id1, and if so where?

Yours curiously... 
one place is on start.bsp
those 'this hall selects foo skill' centerprinting triggers only display their messages when you're facing towards the teleports. walk backwards into the teleporters and you won't see the messages at all. 
Two Custom Map Examples 
Rehashing Old Work 
I didn't bother to dig into the whole backlog of messages here, but I made a (fairly simple) hack that allows for killable "static" entities. I've tested this with flames, but not with other things, I suspect that light globes may work.

step one, make a trigger under the player spawn and make it target an info_notnull called "flame". Make sure this info_notnull is some distance from the player, as touching it too early will crash your engine.

Place a "light_flame_large_yellow" somewhere in the map to precache the model.

give the info_notnull the following keys:

targetname flame
model progs/flame2.mdl
frame 1
use func_wall
think PlaceItem
nextthink 2
mdl progs/flame2.mdl

This should now allow you to killtarget the flame entity. Note that static ents don't occupy the edict list, however this hack will. I guess it will also allow for a touch function to be run on it after this point too.

One final thing to consider when using this hack, touching this entity before its had its "nextthink" even by a monster will crash the game. Even shooting the flame will crash it. I suggest spawning them well away from players and monsters.

The nextthink function forces the notnull entity back to a non-solid non-bsp state whilst retaining the flame model. In the example above this happens 2 seconds after it spawns. 
(oh, the trigger should be a trigger once) 
those 'this hall selects foo skill' centerprinting triggers

Blimey, I didn't have to go far then to find one. 
That's a fair amount of work for a killable flame. Rather than messing with thinks and nextthinks and all that, you can just set the modelindex of an info_notnull to that of the spinning flame model (flame2.mdl, check in the console first to see which slot it takes of course) and have a simple displayed model that you can killtarget like normal, no extra futchery with crashing when touched or anything. The flame will automatically do its snazzy little spinning and burning animation, similar to a backpack, and the frame field changes the size with 0 being the smaller flame model (light_flame_small_yellow) and 1 being the larger version. Old example webm here
the flame models are static and don't appear in the edict list though? 
They're still given a modelindex, no different from the player or enemy models or worldspawn/brush models. Not sure how to find which model has what number in Fitzquake-derived engines but Darkplaces (ugh) has a handy modellist command that will print out every model currently loaded by the game in order. Worldspawn comes first, then count the list by one. Worst case scenario, experiment a bit until you find the right modelindex and remember to place things in the right order that enemies/health changing by difficulty won't break the hack. 
Worst Case Scenario 
You might have to make separate entities for different skill levels, with each having the correct model indices for the corresponding skill levels. :/ 
Move On Up 
Moving the static torch you're using to precache the model as near to the top of the entity list as possible will help to stabilise the modelindex across all the skill levels in your map. Also worth remembering that each time you add a brush entity, that adds one to all the precache modelindex values. So you want the map to be basically finished in that respect before you finish off the hack. 
Rotating Turret Hack Finished (mostly)! 
Hey guys, back for another update. My rotating turret hack is almost 100% done :D I just need to take a few minutes tomorrow to iron out some little kinks related to the offsetting of the body model in relation to the shots and it will be good to go and I can make a demo map and full write up on it. In the meantime here is a weirdly rotated screenshot from QuakeDroid showing it in action in a crappy little box room :) 
The Absolute Fucking Madman 
Eagerly looking forward to seeing it in action. 
Nice that a "newer guy" can make cool stuff! 
If what he's posted in #tf and related channels in such short time is any indication, rekta is a new maphax savant. 
I mean it's not that impressive, you can do it easily if you have basic programming knowledge and take the time to read the sources to know what fields and functions you can and cant use where... Or in my case, try and figure out why entire segments of code were replaced and moved elsewhere but still in the original files commented out, then get confused when what you want to do isn't working the way it should :D it's not like I'm making Quake Rally 2 or something like that... Though I do like racing games so maybe I'll give that a shot some day ;) 
Rotating Turret Writeup/demo Map (part 1 
Ok, so, here is the write up on the rotating turret hack. Now my setup probably isn't the best but it works fine, at least in SP, so I'll probably keep using it in maps going forward anyway. It's not too difficult to set up but there are several steps involved. Also apparently this is too long to put in one post since the character limit is 5k and I have more than that :O So i will need to divide it into multiple parts.

So, here is how you do it. First at the map origin you need to set up the model of the turret itself. Of course I suppose you could use a custom mdl but these are vanilla maphax we are talking about here :) Now after you make it you might need to move it up a little depending on the type of projectile you want to use so it doesnt look like complete crap when it shoots, I used hknight_shot so I had to move the model up a few units to get it to look right. After you made the model you need to turn it into a brush entity so it will have a model and modelindex value, I used func_wall. And of course you should encase it in a box to prevent leaks and add appropriate lighting. Then add a info_notnull in the spot where you want the turret to be and give it a target name like "turretmain" or something, it will be the main turret body. Now you will want to copy the main model to the notnull, you do that by setting the modelindex and model fields to the same model and modelindex values of the turret model you want to use, if you want to have multiple different styles in your map you need to create multiple models. You can find these values using the "edicts" command in the console, if you want to be able to find the edict numbers of the turret models easier just cut and paste them to the top of your .map file just under worldspawn, that should make things a little easier since now they should be closer to the top of the edict list. In my case the model was *1 and modelindex was 2.0, so I used those. So so far you should have something that looks like this

.....origin = whatever the position is that you placed the notnull at
.....model = *1 (or whatever the model number of your model is)
.....modelindex = 2.0 (same as above)
targetname = whatever you want the targetname to be i guess.

Now if all things went well when you go into your map you should see your turret in the spot where you placed it. Good. But, it doesn't shoot obviously, or rotate either :( SO we need to fix that. Unfortunately I couldn't figure out a way to get any "smart" player detecting functions working so it can only really reliably track 1 player meaning this hack is technically SP only for now. But that's ok, you can just make multiple copies that track specific players, no big deal. First add an "enemy" field and set it to 1, this will cause it to track the first player since they are always the first entity loaded in a map. Now let's get the rotation part out of the way first. For the rotation to work properly we need two things, we need to add a "yaw_speed" field to the turret that contains the speed that we want it to rotate at, and a function that consistently sets some specifc values, specifically ideal_yaw and angles_y. Luckily there is a function that does just that for us, ai_face. So we need to put that somewhere, but where is a little tricky. We can't put it in think because neither ai_face or ChangeYaw (the helper function that ai_face calls that actually rotates the model) resets nextthink meaning it would only run once which isn't exactly ideal. There are 2 options that we as the mapper can consistently control though, use and th_pain. So we can put our rotation function in one and the shooting function in the other, it doesn't really matter which one since the pain state of the turret will need to be activated by a use'd entity shooting at it anyway. So I put ai_face in use and the shooting function in th_pain, in my case hknight_shot. So now it should look like this: 
Part 2 
.....origin = whatever the position is that you placed the notnull at
.....model = *1 (or whatever the model number of your model is)
.....modelindex = 2.0 (same as above)
targetname = whatever you want the targetname to be I guess
yaw_speed = the speed that you want the turret to rotate at
enemy = 1 (or whatever the player number is that you want it to target)
use = ai_face
th_pain = whatever shoot function you want the turret to have, only *MONSTER* shoot functions can reliably be used as far as I can tell since I haven't been able to find a function that will reliably set the values required for you to be able to use player weapons effectively, you can still technically use them, you just can't constantly re-aim them so they will either always shoot in one direction or shoot wherever the player is pointing at the time, depending on how you have it set up. Who knows, maybe that's what you want and you can find a use for that, but this "tutorial" of sorts is about hostile turrets that attack the player, not shoot in the direction they are facing ;) Oh yeah, and the monster whose shoot function you want to use needs to be precached in the map first.

Now as you can probably imagine, we need to set up some triggers so that the turret will do it's thing. So make 2 identically sized trigger volumes that take up the exact same area that will correspond to the line of sight of the turret, of course they can be multiple brushes if you want a concave shape, it just matters that they are targeting the things they should be. One of the triggers should target the turret itself, which when the player steps on it will cause the turret to rotate since its use function causes it to do that. The other trigger will target a new notnull that we need to add in the exact same position as the turret one which is supposed to trigger the turret's pain state, causing it to shoot. It will do that by being inside the body of the turret and constantly shooting it with it's own projectiles. Of course for the turret to be in pain it needs to have health, so you should add a health field to it and set it to whatever you want. You also need to set "armorvalue" and "armortype" as well, so that the turret won't kill itself by being shot by its pain trigger. If you want it to be destroyable you should set the armortype to soak up exactly as much damage as the triggering projectile will give (a tutorial on how to do that is given by Preach here and make sure that the player will have a weapon at that point that does more damage than that. Finally, you need to add 3 more fields, "solid", "takedamage", and "movetype", and set them to 4, 2, and 7 respectively. The solid and takedamage are set so that it will, you know, be able to be shot and take damage, and movetype 7 (PUSH) is required by solid 4 or else the map will crash.

So now that the turret is all set up to get shot and in doing so shoot at the player, now we need to add the notnull that will be firing those trigger shots. This is suuuuuper easy. just add an info_notnull in the exact same position as the turret and give it a targetname, in my case "turrettrigger", a use of hknight_shot, and an enemy of whatever the edict number of the turret's notnull is, in my case 7. Now when it is triggered, it will shoot at the turret, which will cause it to go into "pain", which will cause it to shoot at the player since that's what it's pain function is set to do! And it will rotate as well assuming you have another trigger covering the same area targeting the main turret itself.

And thats about it! Now you should have a turret that, when triggered, shoots at the player and rotates to track them! The final setup looks something like this:

notnull 1 (turret)
.....origin = whatever the position is that you placed the notnull at
.....modelindex = modelindex of turret model you want to use
.....model = same as above
.....targetname = whatever you want the targetname to be I guess
.....yaw_speed = the speed that you want the turret to rotate at
.....enemy = 1 (or whatever the player number is that you want it to target)
.....use = ai_face
.....th_pain = whatever shoot function you want the turret to have, taking into account the restrictions outlined before = whatever
.....armortype = minimum value required to negate damage from triggering projectile but not from more powerful player weapons
.....armorvalue = a number high enough to where it wont go down when it gets shot, i believe 999999999 is a good amount, Preach has an article on this topic)
.....solid = 4
.....takedamage = 2
.....movetype = 7

notnull 2 (turret shoot trigger)
.....origin = same as the turret itself
.....targetname = whatever
.....use = hknight_shot
.....enemy = entity number of turret 
Demo Map And Map Source 
Here is a link to a zip containing a small crap box demo map showing the turret in action and the map source I would have taken the time to make a somewhat better demo map but this took a little longer than I expected to write since I suck at trying to explain things lol, so I just decided to throw out the map I used for testing instead of making a somewhat more realistic use case environment. As usual if you have corrections or tips for improvements feel free to point them out :) 
Haven't read this yet but GG. Grabbing my reading glasses. 
Well parts of it might be a little overexplained which accounts for some of the length lol. I wanted to be really informative though and make sure people get it so maybe it's ok. 
Holy shit, you got it working and working well to boot. Hell of a write up and a tricksy workaround with the th_pain bit, almost surprised you didn't find some evil way to make it rotate vertically as well as the usual horizontal rotation. 
Cool Turret 
Another impressive hack, well done. It's also inspired me to finish off an article I've been working on for a while. It's an ode to the oft mentioned function while hacking: SUB_CalcMoveDone

If you want to know the best way to make a gib fountain, or what the "Duke of York" hack is all about, come have a read... 
I am just getting started "cutting and pasting" QuakeC. I followed your recently revised tutorial on monster spawning here:

I'd like to add a small random delay automatically to each teleporting monster as you can do in Quoth. Reason is I am using custents multiple triggers to trigger these delays spawns. As in Quoth it would be nice to have a little variation on the timing if the monsters all share a targetname.

Would this be as simple as modifying this:

//override the random delay some go functions apply
self.nextthink = time + 0.1;
spawn_tfog (self.origin);
spawn_tdeath(self.origin, self);

to this:

//override the random delay some go functions apply
self.nextthink = self.nextthink + random()*0.5;
spawn_tfog (self.origin);
spawn_tdeath(self.origin, self);
I was finally able to try this last night. Does do it. Any hints would be appreciated. 
Typo Above 
Doesn't do it. 
No Expert Here But... 
Should it be

self.nextthink = time + random()*0.5 
I tried that as well. It's going to be a bit more complex I think. 
Don't Have The Source Files On This Computer 
What values does the random function give? Anything between 0 and 1? Does the function require parameters? Like random(5) giving values between and 0 and 5? 
Just googled the answer myself. 
QuakeC Questions 
would be better discussed in the Coding Help thread. 
Apologies. I associate this thread with Preach and forgot it was more of a hacks thread. 
See my suggestion in Coding Help 
Very Interesting Stuff All This Is, But I Have A Question. 
First off I mostly play a form of teamfortress, regtf, custom, and megatf. I've noticed a lot of maps use trigger_hurts to simulate mine fields and things of similar sort. I wanted real exploasion, real particles, and I used the infomation here in this to do just that. It's targetable or touchable however you need it, but it only fires once. Nothing I have done will make it work again. Is there a way to reset an info_notnull? 
You probably tried the barrel_explode hack which indeed only works once. The only way I could imagine for this to work without custom code is using a W_FireRocket hack that shoots a rocket right into the ground. It can the used multiple times because you can set its ammo count to a very high value. Of course there'll be the rocket launch sound, but that's probably acceptable. Read above to see how it's done. 
I See, So It's Relying On The Ammo In Needs. 
"classname" "info_notnull"
"use" "GrenadeExplode"
"enemy" "1"
"group_no" "1001"
"health" "1"
"targetname" "proxi1"
"nextthink" "0"
"origin" "-264 -90 -352"

I'll try adding this to it and see if that helps.
"no_grenades_1" "200"

thanks btw. 
Well My Way Doesn't Quite Work. 
I could perhaps use the rocket like you said, however, I was hoping more to use effects from something not a trap already. Like triggering detpacks, or airstrikes. So far the only thing that keeps firing are monster attacks. Now consider these mods are stripped down, there are no monsters so none of their effects can be used. I'm starting to think I've gone about this wrong, and theres a better hack, but I only noticed this a week ago. I am at a huge loss right now, I'm quite ignorant. 
You should take a look at MechTech's progref.

There are several examples of what can be done within the commen progs.dat.
It's just a way of placing map entities with the right statements.
The first example is a trigger_multiple for lavaballs. I think it is easy to change it to GrenadeExplosion. 
Thanks Madfox 
I will surely look right now. 
Reading, Reading And More Reading, But 
The more I try things the better it gets, so far I have managed to find a repeating explosion. However, it always targets 0 0 0. Is there anyway I can simulate a players perspective to get a fixed point other than 0 0 0. That's what the code is calling for, someone to paint a target. 
Which funtion name are you using? W_FireGrenade? 
Not Quite 
I know you all recommend using standard quake progs, I am using the tf mod. It's not going to be updated. I used airstrike_target. I cannot use monster skills, well there are some but limited to zombie, grunt, dog, and fish. The rest of the code was stripped down to make room for the tf classes and abilities. I'm having to go through the qc and find function names. Trial and error for me at this point. 
Multiple Explosions 
The difficulty with a hack that lets an entity repeatedly explode is the explosion sprite. Typically the entity that explodes gets turned into the sprite, and the last command in the sprite animation sequence is deleting yourself.

I think you could pull something off though, using SUB_CalcMoveDone as a use function to cancel the removal on the sprite just before it happens. You'd need a second field like th_pain to be setting off the explosion I guess, not tried to build all this but it sound feasible... 
place a spawn and a scrag in the map

place the spawn somewhere else because we only want him for the precaches

give the scrag a touch key, set the value to tbaby_jump1

run up and bump into the scrag
there will be error messages, but shit is hilarious. 
Works Spookily Well 
Dang if only I werent at work 
Lightning Without Event_lightning 
I'm working on a gate where flashes should light to a central point. I've tried event_lightning with gate_logic and read everything about it. This does not seam to work because it's not continouse and also not continouse triggable.
I thought about using a lightgun to direct it to an info_null.
Has someone an idea or solution to this? 
See post number 11 on this page. Click the thread name to load all posts. Not sure how to bookmark a post 
Extra Trick 
Thanks. Will check it out. 
Metal Gear Solid Map (question For The "progs Whisperer Preach) 
Hey Preach, I'm a really good friend of Shamblernaut and a lot of the guys at the Quake speedrunning scene/Discord. I've been making Kaizo (insanely hard and novel) maps for an episode. I'm starting the 6th map and wanted it's theme to be, stealth. Now sure invis rings are great for this, but I want parts of the map to require you to dodge pathcorner monsters without invisibility using swift movement and other tricks. However, I want it so that if 1 monster is aggro'd (by seeing you, you shooting them, etc.) that ALL specified monsters in a group/unit are aggro'd as well immediately. Not just upon said monster's death. I've tried all manner of map hacks and the closest I got was using the touch function in conjunction with SUB_UseTargets. But obviously that won't suffice. I want a group of monsters to aggro as one unit, REGARDLESS Of line of sight if any of them are aggro'd. Is this at all possible? Thank you so much in advance. <3 
Hm well it could be doable but you might need to design your map in a specific way. My first instinct would be to have the monster set up to where its path comes near several triggers or maybe is even completely bordered by triggers, said triggers would be what aggros the other monsters if one spots you and deviates from its path, now the obvious problem with that is that the player could trigger it too, im not sure if setting the owner to 1 (the entity number of the player in SP games) would help prevent the player from triggering it or not since I haven't tried that before but I guess its worth a try? 
Not A New Trick... 
Just noticed in the id QC, if you "use" a func_wall it toggles its animated texture sequence.

I can't recall ever seeing this in action in the original maps - was it ever used? 
I don't think so, but it's relatively well-known and is listed in most documentation you can find online. Sort of the opposite scenario of something like directional trigger volumes, which are used in the start map but rarely mentioned anywhere when looking for information. 
directional trigger volumes

Holy shit i'd forgotten about those.

Seems we need some kind of resource of "things quake is designed to do but no-one knows about". Sort of the slightly more straight-edge, but still cool, cousin of this thread. 
Kinn said:
Just noticed in the id QC, if you "use" a func_wall it toggles its animated texture sequence.

This is actually surprisingly annoying from the point of view of hacks, because it means you can't set the use function on a func_wall in a hack - in fact it's nearly impossible to set a custom use function on any solid brush entity. It is used in the high framerate animation hack though, so not a complete loss.

FODDER said:
...However, I want it so that if 1 monster is aggro'd (by seeing you, you shooting them, etc.) that ALL specified monsters in a group/unit are aggro'd as well immediately...

I've come up with a new hack, that's pretty interesting, but doesn't quite do what you want yet. I think it would suffice for static monsters, but would be nearly impossible to use for patrolling monsters without some false positives (which is of course the worst possible thing imaginable for stealth gameplay).

I'll keep playing with it a while to see if I can work around that somehow. If not, I'll write up what I found and share it anyway. I think the functions which the hack uses are the ones you'd need to modify the QC to get the desired effect - so it might prove useful in a roundabout manner anyway. 
New Year, New Hack 
Here's the idea I came up with over the weekend - Security Cameras!

You can train a security camera on a static monster and it'll always notice if that monster has been alerted (with a bit of fiddling you can also ensure that it never sets off by itself, even if the monster is killed under its nose). The problem is that this doesn't generalise to a moving monster, so it doesn't quite do what FODDER was after. Still, I think it's a pretty cool idea in its own right. 
Progdefs.h Is Out Of Date 
I'm trying to change some things about a the swinging hook mod that require it to be recompiled. I can get the code to compile and have no problems when changing the game over to the mod. When I try to load a map or start a new game VkQuake gives the error:

Host_Error: progs.dat system vars have been modified, progdefs.h is out of date

I'm new to Quake C so any help would be nice.
If its helpful this is the progs.src


I am pretty new to this myself but it's very important to not change certain things in defs.qc.

If you change anything above line 220 (give or take) you are asking for trouble. The rule of thumb is don't change anything above

void end_sys_fields; // flag for structure dumping

Not sure if this is your issue but good info nevertheless. 
new to QuakeC, and yet your progs.src is lacking monsters?
Sounds like you're trying to compile a QuakeWorld mod instead of a (Net)Quake one.
The two are similar but mutually incompatible (primarily but not exclusively due to changes above end_sys_fields).

If you truely want to run a QuakeWorld mod then use a QuakeWorld engine (eg: FTE, ezQuake, or MVDSV). (Net)Quake engines like VkQuake, QuakeSpasm, or even DarkPlaces cannot run QuakeWorld gamecode. 
Its probably the quakeworld thing since I have not touched defs.qc. I'll try that, thanks. 
That Was The Problem 
Thanks for the help. It works now. 
TY Preach 
I appreciate that new map hack idea a lot Preach <3 even if it isn't exactly/fully what I needed (since I had ideas for patrolling monsters) I still will definitely look into it. I'm putting off my Metal Gear Solid map for now until my 2nd Kaizo Quake episode now since, as you can imagine after making this hack, getting what I want is virtually impossible in vanilla Quake sadly. :[ 
Controllable Models 
I'm needing a way to control a mdl with an entity. So when I target it it will start frame group 2 and it's series of animation. I tried using an info_notnull, and I must have gotten close but the server shutdown with non bsp model error. 
Custom Model 
Hi Aberrant. I think there's little chance of that being possible with a map hack. I'm unaware of any hack in vanilla quake that allows inclusion of a custom model the way that misc_model entities allow in some mods.

Quoth's equivalent does come with the ability to toggle between two framegroups, but you need to set the model up so that those two framegroups are frame 0 and frame 1. See full details at 
If my guess is correct, Aberrant isn't looking to load totally custom models, but to use existing ingame models and animate them when activated; e.g. using an info_notnull to display a monster's model, and then make the 'fake monster' display one of its animations (run, shoot, die, etc) when the notnull is triggered by something else. 
Does QuakeSpasm, QSS, FTEQW or Darkplaces support custom (QC-defined) interpolation timing for MDL frame animations?

Makaqu supports this through self.frame_interval, but I'm not aware of any hardware-accelerated engine that does. 
Fitzquake variants have it in the protocol but it’s not directly controllable from qc — it uses the nextthink field to decide how to set it and caps it at 1 second 
Ok, thanks.

By the way, what are the known engine-independent methods for fixing the problem of the player sliding over the heads of the monsters when he jumps on them?

I've tried setting a .touch function on the player, to detect when the player touches a monster, but it's not working. 
Good question ... I fixed it in-engine in early builds of fitzquake but then removed the fix later once i realized it's a bad idea to make bug fixes that change gameplay. In my readme I said "this bug can be fixed in quakec also" but I have no memory of how. Maybe setting the .solid of monsters to a different value? SOLID_BSP? 
Needs to be a monster touch function
Also works if you set it on exploboxes

void() monster_touch =
if (other.classname != "player")
if ( <= 0)

if ((!other.flags & FL_ONGROUND) && (other.absmin_z >= self.absmax_z - 2))
other.flags = other.flags + FL_ONGROUND;
That worked, thanks c0burn. 
also this stuff should be in Coding Help thread. 
I had forgotten about Coding Help; can that thread go to the Permanent Threads section? 
So What About Animating A Model? 
Hello everybody,

Has Aberrant's question (#612 & #614) been eventually answered?
I would be eager to achieve such a thing to put some RPG sequences in my own project (which is actually for Hexen II) the way Heretic II does.

That is:

1. the view switches to a third person view thanks to a camera_remote (a handy thing we have in H2 which does basically the same as the intermission view, but triggerable mid-map)

2. the view represents the player facing a monster and they interact by talking (with centerprints) or doing something (like one killing the other or running away) by triggering the corresponding animations on the models.

3. the view returns to the player and the adventure goes on.

Has everyone ever tried to do that? Succeeded? How?

Thank you in advance for your insights! :-) 
Portal of Praevus has an intro scene that it possibly a demo file. Maybe you can look into it and see how it's done? But playing intermission demos would require saving-loading or a way to save state so you can reset back to. 
this really sounds like it requires QuakeC, not map hacks 
@kalango Indeed the PoP intro scene involves a demo file. How such files actually work is a mystery to me... Obviously they are not just video files standing alone on their own since an actual map exists corresponding to that intro scene, full of extremely complex settings involving more than 50 trigger_relay and almost 20 of those camera_remote things travelling along path_corners... So which part is "demo" stuff, which part is scene scripting through entities inside the map... ? I confess I am puzzled.

@metlslime You may be right. If so, since I don't want to pollute this topic I'll start a new dedicated topic. :) 
Unthinking Custom Monsters 
monster_zombie with nextthink -1 allowing to set the use function and do some funkiness

"classname" "monster_zombie" // zombo
"nextthink" "-1" // disabled on spawn
"frame" "174" // lie frozen on ground frame
"use" "zombie_cruc1" // pop into crucified state
"touch" "zombie_run1" // hunt enemy on touch/damage
"flags" "544" // needed flags
"yaw_speed" "20" // turn as normal
"targetname" "bob" //
"takedamage" "2" // damageable

'use' can even be from another monster, for ex. dog_leap1..
Some useful use keys would be puttin him to the ground with zombie_paine11 or on the cross with zombie_cruc1. Maybe use SUB_CalcMoveDone + finaldest for some awkward teleporting?

Thought this was worth sharing, since I don't think I've seen it used. Maybe has potential for more useful set ups. 
Thanks For All The Replies And It's Been Awhile. 
I ended up finding everything I needed at preaches site. And I was trying to trigger existing monster animation sequences. It did work quite like I needed, but I learned a lot by doing it. I did notice that if I killed the zombie and then retriggered him, his head would start draging around chasing you. But that is in a megatf mod I am working on whatever you're on might react differntly. If you are wanting to animate mdls the bast way is to just setup a mdl with an animation sequcnce that just loops, can then call it with whatever ent you use to spawn mdls and it'll keep looping. Like the candles in arcane dimensions. Using info_notnull can call the mdl too, but I never found a way to kill them and bring them back. Currently i'd love a way to make a info_notnull solid wihout getting the non bsp_model error. I took a tank Xage made and added things to it and it never crashes being solid. Normally, fireing rockets at it will crash everything, but this one doesn't. 
Post That Tank Map Ent In It's Own Area. 
"angles" "0 0 0"
"classname" "info_notnull"
"enemy" "1"
"health" "9999999"
"model" "self.model"
"modelindex" "4"
"movetype" "7"
"origin" "44 -3 289"
"solid" "4"
"takedamage" "2"

The tank sit perfectly at 0 0 0 on the map.
I'm sure this has been posted before, this was just my way of getting it to work. Getting it to fire is something else entirely. When I trigger a notnull that uses a monsters attack frame that contains ai_face and it fires it will crash with non bsp_model error. Not from my fire like the rest. 
1 post not shown on this page because it was spam
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2020 John Fitzgibbons. All posts are copyright their respective authors.