News | Forum | People | FAQ | Links | Search | Register | Log in
Mapping Help
This is the place to ask about mapping problems, techniques, and bug fixing, and pretty much anything else you want to do in the level editor.

For questions about coding, check out the Coding Help thread: https://www.celephais.net/board/view_thread.php?id=60097
First | Previous | Next | Last
Different Class...name 
Yeah, it's because the alert code checks the classname to decide what alert sound to play, and doesn't have an extra check for monster_ogre_marksman. Other places this matters are infighting - monster_ogres will attack monster_ogre_marksman, and obituaries, which are uncredited if the marksman gets the killing blow. Most interestingly, while the monster_ogre uses OgreCheckAttack, the marksman uses the generic CheckAttck function to decide when and how to attack.

The differences between the two are that OgreCheckAttack always melee attacks if at melee range, and always fires grenades if enough time has passed since the last attack and line of sight is not blocked. CheckAttack is more probabilistic, with 20% chance per frame of a missile attack if near, and 5% per frame if mid range. On the upside for the marksman, the minimum time between attacks is shorter, randomly between 0 and 2 instead of 1 and 3 for the ogre. So at short range the expectation is the marksman fires faster, at mid range the regular ogre comes out on top, on average. Pretty much all of the marksman's advantage is gone in nightmare.

If you look at the OgreCheckAttack code you might see "chance" assigned various values depending on how far the ogre is from the target. This is all totally redundant, as the function then goes ahead and fires anyway without testing chance. Seems most likely this is leftover code from the generic function that should have been deleted, not an intended design that should have been fixed up.

One other thing I thought of about the AI here is that it shows you how the chance function is not a good way to try and make the enemy close the distance, firing occasionally. Even with a low probability like 0.05, we expect a shot every two seconds. If you're designing your own monster, and you want them to occasionally lay off the attacking to get close, a more reliable way of doing it is to set an attack_finished time.

A crude decision process would be to randomly decide with p = 0.7 say to not attack for a while and instead close in on the player. Then set attack_finished to time + 2, and the monster will just run at the player for that wrong, then decide if they need to melee or close in further, or if this time they should attack. It's useful because it allows you to make a command this frame that affects the ai for several frames in the future. Making better decision than random number generators would be the next step, like deciding to close in if the player has a RL out. 
Than 
Checking whether the entity has a model is a safe way to decide whether the entity is a brush model or a point entity. The original function just assumes the trigger has a model. Any existing maps will always go down the branch of the if() statement that does setmodel, so its behaviour is identical to the original in this case. This will happen for any brush model you give it, as they must have a model by definition. To the engine, a brush entity is really just a point entity sat at the origin with the model field already set. The brushes themselves are just part of the bsp file.

So it's safe for brush entities, but is it safe for point entities? Well, all brush entities have a model, but some point entities have a model too. The important thing is that you wouldn't set the model field on the new point entity triggers you create. That way you can be sure they are safe, as you have complete control over them.

Of course, the question arises, what happens if you make a point entity, and give it a model? Does the sky fall in? Well, it gets treated as a brush entity would, so it gets the size of the model you assign to it. In fact, it works perfectly well, you get a player sized trigger by setting model to progs/player.mdl.

But didn't we just say that the function works in exactly the same what as the original quake function when the model field is set? Yes, and this means that the same thing happens in regular unmodified quake! So to save brush models for things like monster trigger_teleports in normal quake levels, you can make point entity trigger_teleports, give them a "model" "progs/player.mdl" key, and then set them up as normal. Obviously less useful for other triggers where it usually matters what size they are, but still, it's a very cool hack. I might go post that in the "new tricks" thread, just discovered while I was posting this... 
Point Entity Trigger_teleports 
Setting the model field might be useful for regular teleporters (would it be also possible to set it to, say, the size of a Shambler if the model is precached?), but it's not needed for monster in-teleports as the triggers also work without as long as the monsters touch them at their origin. This works with all triggers btw. 
Oh Yeah 
Any model will do, it's just that the player is the largest model that's always precached. Didn't know that about point sized teleports, but it's good to know. 
Preach 
Is it possible to disarm a standard Ogre so that it will never fire a grenade and always try to close the distance to the player through a hack of base progs?

From what I understand, no, but then I don't yet know anything about QC. 
'fraid Not 
I've been caught out before declaring things aren't possible by hacks, but no I don't believe this can be done without modifying the qc. 
Func_plat 
Is it possible to move them in non 90� angles like 45� or 33�? Using Quoth. 
No 
use a func_train instead 
Func_rotate_train ? 
.. but not so much information given on Qutoh tutorial.. I guess it is quite similar to func_rotate_dorr techniques.... Ask Kell if you have doubts.. 
Oops 
I should have added that I want it to move not on the xy-plane but "vertically diagonally".
Rotate would be an idea but I really don't want to do that kind of freaky and hard stuff. =) 
Preach 
thanks for the advice, but it doesn't seem to work. Regular triggers still work ok, but nothing happens when I try to load a trigger without a model. The ent is there, but the size has not been set. I'm guessing there is something about if(self.model) that makes it never return negative. Here is the code:


void() InitTrigger =
{
if (self.angles != '0 0 0') SetMovedir ();
self.solid = SOLID_TRIGGER;

if(self.model)
{
setmodel (self, self.model);
self.modelindex = 0;
self.model = "";
}
else
{
//use mangle for the offset from origin that defines the bounding box. origin is MIN, mangle is MAX
if(!self.mangle) self.mangle = '64 64 64';
if(self.mangle_x < 1) self.mangle_x = 1;
if(self.mangle_y < 1) self.mangle_y = 1;
if(self.mangle_z < 1) self.mangle_z = 1;

setsize(self, '0 0 0', self.mangle);
}

self.movetype = MOVETYPE_NONE;
};


The code in the else statement works on its own, because it used to be in a separate function used by separate point triggers that worked just fine. 
Point Triggers 
Just tested it, that code works fine. The problem might be that your editor is attaching a model to the point entity you're using. You can't check whether it had a model set using the edict command since the self.model code resets it. Instead, extract an entity file from the bsp and see if it has a model number there. 
A Few Questions 
Hey, I'm working on my second map and I'm running into a few problems that I hope someone can help me out with. I'm using Worldcraft 3.3 with the Quake Adaptor, all the progs that came with it and everything is at default.

The lighting on this brush is messed up, I'm not sure what's going on. Here's a pic.
http://img172.imageshack.us/img172/8306/lightsqz9.jpg

I'm having trouble adding powerups to my map, quad, pent, and eyes. They seem to load fine in the editor. But when i load up the map, they aren't there. I'm really stumped here.

I'm also wondering how to trigger stuff to happen when monsters die.

For example. The player walks into a room, bars drop down and block all the exits. After the player kills the mobs, i want to the bars to open. Porting monsters in after a monster dies is something I'd like to do too.

Sorry for the newbie questions, but Google didn't help much :)

Oh is there any good tutorials out there for this kind of stuff?

Thanks 
Opt1c 
Are the brushes perfectly aligned? Is there anything behind that brush? Which light tool do you use?

The powerups don't appear because they touch the wall or the ceiling. You have to make sure their bounding box is some units away from any brush solids. Type "developer 1" in the console and run your map, then you'll see the corresponding warning messages.

To trigger stuff when monsters die, simply give them a target. If you want the bars to open only when all monsters are dead, let them target a trigger_counter which then opens the bars if it has been triggered the amount of times set in its 'count' field. 
/slaps Myself 
Well i figured out why i couldn't add powerups. I just had to place it above the brush somewhat. I guess it can't be flush with the surface like all other items. 
 
Are the brushes perfectly aligned? Is there anything behind that brush? Which light tool do you use?

They look aligned in the editor. But in the game theres a small black line between some of the brushes. It's a 12 sided cylinder. I use the light tool that came with Quake Adapter. Light 1.43 by Bengt Jardrup.

Thanks for the help, I'll have to play around with all these triggers that I've never really used :). 
Opt1c 
There are some good tutorials here:-
http://www.bspquakeeditor.com/tutorials.php

Although they use the BspEditor (which I use) in these, I think they are pretty generic in terms of teaching the basics.

If you haven't settled on your editor of choice, I would recommend that you give BspEditor a try - the latest version is a superb tool. 
Opt1c 
Try snapping all the brushes to the grid. The bugs may be caused by floating point vertices. 
Quake Adaptor 
wooot
this sounds serious :) 
Preach 
Yeah, you are right about worldcraft screwing up trigger_multiples when they are created as a point entity.

To get them to work properly you have to first create the trigger, then go into smartedit and finally add both mangle and ORIGIN values manually.

The alternative method (and my preferred option) is to create a trigger_multiple_point entity in Worldcraft and then strip the _point part from the classname in a text editor before compile.

Perhaps there is a way around this by modifying the entry for triggers in the WC FGD file, but that seems like more hassle than it's worth, and there are probably command line programs that can strip text from files that can just be added to the compile batch file or whatever.

This sucks, but I guess this type of trigger is only used in maps that are going to push the precache model limits, so it isn't really something most people will have to deal with. 
Oops 
Preach, I finally noticed the link to an earlier post you made (http://www.celephais.net/board/view_thread.php?id=47757&start=742&end=742) and have just realised I basically said exactly what you did again. Sorry for the wasted time. I'll see if I can track down a util to strip out the _point part of "classname" "trigger_multiple_point" lines from the .map file and make a useful post shortly :)

By the way, what qcc compiler do you recommend? The size of the progs.dat that Kell sent along with the code is around 100kb smaller than the one I compiled with FrikQCC, and it won't even compile using proQCC.

Necros, if you are reading, please let me know what QC compiler you use along with any special options. I'll probably send you an email about this shortly. 
Stripping Out Point 
That's the idea for worldcraft, although there's a way you can do it in the code rather than have to edit the bsp(in the case that you're using the custom code - when using the player.mdl hack you need to go entity bashing). What you do is add a function to the code:

void() trigger_multiple_point =
{
self.classname = "trigger_multiple";
trigger_multiple();
};

This basically just creates a new entity class that's identical to trigger_multiple. It's better to do it this way rather than copy-paste the trigger_multiple code for three reasons:
1. It's quicker
2. It saves space in the progs
3. If you change the trigger_multiple code at any point, you don't need to remember to make the changes again for trigger_mutliple_point.

The reason for the line self.classname = "trigger_mutliple" follows from all that discussion about monster_ogre_marksman behaving differently to monster_ogre. In fact I was meant to mention this in that post, but got carried away with the AI changes. I don't think there's anything in standard QC that checks classnames of triggers, but best to be safe, it's easy to imagine a use for a check like that.

For compiling I use FTEqcc - http://www.fteqw.com/ - at the moment, it's got a lot of options for optimisations, plus a few advanced features like macros and a precompiler that I never use, but it's nice to know that they're there. FrikQCC is also a popular compiler, and the different sizes might just be the number of optimisations you're applying. So try out FTE and see if it works better. 
Trigger_push 
For vanilla Quake or Quoth:

a) Is there a way to push the player "vertical-diagonally"? Like / or \.

b) Is there a way to make the trigger_push behave like the great Q3 jumppads?

If no, then someone should really make the code for this I think. :D 
Spirit 
Set an "angles" key in the trigger_push with a value of x y z, where x y z are numbers determining the angles of where the trigger pushes you.

I don't know exactly which angle is which, or if it will always work, but I have managed to create a similar diagnol push like you mentioned.

Play around with the angles a bit and see what you come up with. 
Diagonal Trigger_push 
Yes, it can be done with the "angles" field like Orl said. Tip: The viewpos command (e.g. in Fitzquake and aguirRe's engines) makes it alot easier to get the proper values when you're not sure how to change the x y z ones. This is also helpful for the intermission mangle.

Q3-like jumppads work the same way. Small trigger_push on the floor with "angles" and a proper speed value. 
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.