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
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 
we 
As Demonstrated In Neg!ke's Recent Doggy Speedmap 
when are we going to see the speedmap session based on tricks from this thread? 
Skip 
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. 
Than 
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? 
Mike 
 
hmm, on a second thought i always used
"use" "trigger_once"
"touch" "SUB_Null"

probably just another way (without apparent downsides). 
Neg!ke 
Thanks for the speedy reply, I'll get on to it. 
Neg!ke/Preach 
Great stuff! 
Mike: 
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. 
Oops... 
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:

http://forums.inside3d.com/viewtopic.php?t=475 
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. 
File 
Here is an example map of stupid test things which happens to also contain the trick I mentioned in the above post: http://than.leveldesign.org/files/invisBarrier.7z

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. 
Than! 
You are simply a one-man repository of l33tness. This'll come in big use with my base map =D 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.