 |
#8212 posted by madfox on 2009/01/11 21:58:47
phone was the course...
 Invisible Func_wall
#8213 posted by ijed on 2009/01/12 00:01:38
With a trigger next to it that killtargets it when touched by player - who'll never even know it was there.
That's assuming you don't need the thing to permanently block monster movement.
In Quoth it'd be a togglewall, or you could use a skipped func_wall, or else a clip brushed func_wall which has visible brushes on the extents. I mean visible as in not clip texture, embedded in geometry, with the functional centre being clip.
 Killtargetting A Func_wall
#8214 posted by Preach on 2009/01/12 00:21:52
Isn't that going to block lots of other important things though, like projectiles, and light of sight checks made by monsters?
 Yes
#8215 posted by ijed on 2009/01/12 01:47:10
But it's another solution. It could also be only 32 units high, which wouldn't block much, though would look wierd if it, with, say, a grenade.
Otherwise the holey floor would work as long as the monsters weren't jumping or flying. Or swimming ;)
 Ideas
#8216 posted by than on 2009/01/13 08:36:50
You could always use a clip wall with small regular brushes textured with skip at the extremes to stop it being glitchy and then kill it when the player gets close. That should work ok whilst allowing line of sight checks to work and projectiles to pass through.
Personally though, I prefer the tip posted by Metl, which I used in a couple of maps in the past - maybe even as far back as apsp1. I like that it doesn't block them movement of jumping or flying monsters, since I will typically want to use it to hold a sniper in place somehow. I may have actually made a small demo map to demonstrate this quirk of clipped brushmodels some time ago, so I will see if I can find it tonight.
Another way that requires no entities and will stop strict walking (no jump attack) monsters is to create a small break in the floor where you want them to stop. Monsters often have problems with floors that have a lot of holes in such as gratings because they do some kind of line of sight check to make sure there is ground below them. When there isn't, they won't keep moving forward. I think the crack only needs to be 16 units wide for it to work, though it needs to be a bit deeper than that. You could then cover the crack up with a func_illusionary if you wanted, though that is not neccessary, and would obviously look shit if a grenade fell in the crack.
Other suggestions include using a trigger monsterjump to fire the monster back very slightly (it may be worth experimenting with speed and angles here) or just embedding it slightly in the wall, which requires no extra entities but is a bit hacky and might not work in all engines.
All of these tips should work in vanilla quake.
 Sorry
#8217 posted by than on 2009/01/13 08:38:16
didn't notice metl had already posted the tip about using a gap in the floor.
 Sorry
#8218 posted by than on 2009/01/13 08:38:16
didn't notice metl had already posted the tip about using a gap in the floor.
 Also Sorry For The Doublepost And...
#8219 posted by than on 2009/01/13 08:46:09
 Monsterclip: Ffs
#8220 posted by anonymous user on 2009/01/13 09:26:02
trigger_monsterjump with low values - height 10, speed 10. if you want it killable, use the info_notnull hack.
#8221 posted by JneeraZ on 2009/01/13 11:14:10
"trigger_monsterjump with low values - height 10, speed 10. if you want it killable, use the info_notnull hack."
That's interesting. Can anyone think of why this wouldn't work? The monster might get stuck in a perpetual state of falling or something.
 But
#8222 posted by than on 2009/01/13 11:51:15
monsters still go through their attack routine whatever state they are in I think. if they are being flung through the air I think they still attack.
Not 100% on that though.
#8223 posted by JneeraZ on 2009/01/13 12:26:30
The problem you'd have though, I think, is that the monster will never get the message. Sure, they'd be rejected by the jump trigger but that will never get them to change their route. They'll just run into the trigger forever, looking retarded.
 Necros:
#8224 posted by metlslime on 2009/01/13 13:37:27
i think clip brushes in func_s do stop player movement. i'm pretty sure i tried that once, but it was a long time ago
clip brushes in funcs work correctly, as long as they are inside the bounding box of the visible part of the func. Quake (stupidly) doesn't bother doing collision detection against other entities when those entities are outside the visible part of the func.
 Monsterjump
#8225 posted by ijed on 2009/01/15 02:39:08
Does work, I forgot that one.
I think I used it with 0 vert ~5 horiz once.
 Does The Info_intermission (?)
#8226 posted by RickyT33 on 2009/01/21 22:32:30
or whatever it is (the cameras for the scores between levels), er, do they take up room in the signon buffer?
 Buffers For Shoes
#8227 posted by Preach on 2009/01/21 23:32:40
The client doesn't know about them, because they don't have a model set, so they aren't transmitted between levels.
If you are having trouble with your signon buffer being too large, the easiest thing to reduce is the number of entities which have a model set at time zero. Static entities count towards this limit, but the only thing you can do about them is remove some.
It's worth noting that things which have modelindex != 0 do in fact count towards this total. I managed to discover this when I tried updating the quoth code to use this code for teleporting monsters:
http://inside3d.com/showtutorial.php?id=171
The line of code which hides the monster:
self.model = "";
is not enough to stop the monster being sent in the signon buffer, and consequently ne_marb started overflowing. If anybody uses that tutorial, it is advised to add
self.modelindex = 0; just after that, a trick which triggers already use.
I suspect though that the map which is hitting the limit is already a quoth map, and so you can't code your way out of it. In which case, I can suggest one or two entity hacks which might save you...
The first suggestion I have is to make some entities spawn later than they usually would, so they are sent in an update after the signon buffer. The candidate I'm thinking of is a func_wall, which is relatively safe to use. But be warned that it should not be done in the following cases:
* If anything is going to spawn on top of the func_wall
* If the func_wall is using an external model in quoth which wouldn't be spawned otherwise
* if there's some other reason that it needs to be in place from the start - don't worry about the player seeing it
Ok, so that's the plan, here's how we do it:
Change the classname of the func_wall to a info_notnull (hello old friend!). Give it the following keys:
self.nextthink = 0.2;
self.think = func_wall;
Can you guess what it does? It uses the fact that classnames are also functions ( http://www.celephais.net/board/view_thread.php?id=4&start=7981&end=7981 ) so that the func_wall initialisation is actually run as a think function just after the signon buffer is sent.
If you can't get enough mileage out of doing this on func_walls, you could look at doing it to other entities. Complex things like doors are probably a bad idea because the parts of the door have to link. You have to be careful that the spawn function doesn't do anything like precaching sounds or models, and you can't do it with static entities - they MUST be in the signon buffer.
Quoth is a bit more forgiving in this regard, as long as the model required has been precached by something during worldspawn, the actual attempt to precache it again later on is suppressed by the code. So you could do this trick on monsters for example - but then why not just give them the silent and teleporter flags, and teleport them in a second after the map spawns? It avoids using a hack to do it, and that bug about the signon buffer above has been caught and fixed ;-).
 Preach
#8228 posted by RickyT33 on 2009/01/21 23:40:22
You are a legend, but allas - 'tis too late!
No fault of your own though, obviously, its just that i have weakened and folded....
 Preach
#8229 posted by necros on 2009/01/22 01:59:05
the stuff i've seen you do without modifying a single line of code is godly.
been meaning to say that for a bit now...
#8230 posted by JneeraZ on 2009/01/22 11:31:01
I agree and echo the sentiment, Preach. Your level of knowledge in the area of Quake is incredible. Thanks for always being so willing to help with questions and being so eager to share.
 Heh
#8231 posted by Preach on 2009/01/22 19:48:56
See, I've been meaning to make a post on exactly the opposite thing - how to code things in such a way to defend against mappers hacking them.
Would people like to read that, or is denying people the fun of entity hacking just too much?
#8232 posted by JneeraZ on 2009/01/22 19:50:53
I guess it depends. What would be your reasoning for preventing hacks?
 Versioning
#8233 posted by Preach on 2009/01/23 00:47:57
If you are making a mod which lots of mappers are going to use, but which isn't final - you may release a new version of this mod in the future, then you have to worry that all of the old maps will work in your new version. In an ideal world all you would need to maintain is the advertised features in your documentation.
Of course, the documentation of what you intended is never finished, and it can be hard enough just maintaining things as you add new code (see: quoth 2.0). If people start using "unadvertised features" in maps, then you can get stuck. You would like to make some change to something you thought was internal, but that will actually break the hack in some existing map.
So I guess the message here is that performing hacks in maps for id1 progs is basically safe because there won't ever be another patch for quake, 1.08 is the end. Since it's going to be unchanging, you can get away with a lot more. With a mod that might in the future. With a mod that might come out with a new version, you probably should colour inside the lines for the most part.
In my defence for suggesting the func_wall trick, it is actually surprisingly hard to break with a mod, since the features it uses (think, nextthink, classname) are all hardcoded engine behaviours. The only thing you could really do to wreck it is change info_notnull to set think/nextthink(which seems pointless for an entity designed to do nothing) or change func_wall to do something that isn't safe after worldspawn like precaching things. So I think it's safe to say that will work in future Quoth versions.
#8234 posted by JneeraZ on 2009/01/23 01:01:07
Oh, honestly, I think you're off the hook there. I know about best intentions and all but if someone is leveraging a bug or a hack in your mod that you haven't documented and that breaks in the next version - so sorry, but oh well.
That's not an unreasonable position to take. Use the documented features only or risk getting burned. That's totally fair.
And, really, I'd rather have the freedom that the hacks provide rather than mod authors going through the work to lock everything down.
 Yeah Preach - You Shouldn't Worry About It
#8235 posted by RickyT33 on 2009/01/23 01:11:57
because the person who is making the dodgy hacked map has a copy of the original progs he was using anyway, so if a later version breaks the hack then the player/mapper just has to roll back his version.
And you guys have catered for that by releasing the individual parts of quoth, upgrade by upgrade...
 Defending Against Hacks
#8236 posted by Preach on 2009/01/24 01:44:21
It's reassuring to hear that, I'll worry less about people hacking. As a future warning, don't hack anything to do with path_corners in quoth, they don't work like they used to in quake, and they are going to change...
Even so, I'm gonna post how you do it anyway, because at the bottom there are two alternate applications of the ideas. And also because the second way in here is a really cool trick that I've never seen anyone post about before.
So if you do want to defend against a hack, what can you do? Well, to my knowledge there are three ways of defending against things, from the very specific to the very general. Even if you don't think you'd want to actively prevent a hack in your code, you might find some useful information at the bottom of the post about making entities more friendly to modification while maintaining sensible defaults.
If you are concerned about somebody putting an unhelpful value in one specific fields for a specific entity, then the way to prevent it is simply to set that field during the spawn function to a correct value. For example, if you have a monster which gets enraged after firing 10 missile attacks, and you count the shots fired so far in self.shotcount, you probably don't want people to be able to set .shotcount to 10 so that the monster is enraged straight away, so you can add
self.shotcount = 0;
in the spawnfunction. Although it sounds like a trivial thing there, you can prevent people from giving your entity a use function(assuming it normally lacks one) with
self.use = SUB_Null;
You could even preempt people making your entity shootable and killable by forcing
self.takedamage = 0;
self.th_die = SUB_Null;
...although some people might call that paranoid. This method is in a sense exclusive, you chose which fields you are going to prevent being set. If you start doing too much of this stuff, you should instead look at the third suggestion.
The second idea is one I've never really used because the idea only just came to me after discovering a light.exe feature. Rather than preventing people from custom-setting one field in a particular entity, this one lets you prevent a person setting the field in ANY entites. A good example of something that might warrant this protection is .super_damage_finished . The super_damage_finished field makes an attacking entity do quad damage so long as the map time is less than its super_damage_finished value. It's a bit of an ugly hack using that to get monsters with deadly weapons.
The fix is to rename the field to begin with an underscore, like _super_damage_finished. Any field which starts with an underscore gets stripped from an entity as it is loaded by the engine. This is intended so that light tools could read extra fields on lights, which had sensible names preceeded by underscores. These fields then wouldn't cause warnings if the qc omitted their definition. What we are doing is flipping that, creating a field which is only used by the qc and never from the map, rather than always by the map(via tools) and never in the qc.
For those of you who are c++/java fluent, I've come to think of this trick as creating public and private fields on entities(with respect to the map loading).
|
 |
You must be logged in to post in this thread.
|
Website copyright © 2002-2025 John Fitzgibbons. All posts are copyright their respective authors.
|
|