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
In-fighting 
What determines which monsters in-fight and which don't?

Can it be stopped?

Can it be forced? 
 
Mike: If they have a different classname, they will infight (this is also why ogres and ogre_marksmen do it). It can't be stopped without resorting to QC. In some cases you might be able to hack around it by making the monsters owners of each other, but that only works with melee enemies. It can be forced - a monster can be made angry at another by placing it in a trigger volume with a certain touch function that simulates an attack by another monster, again the correct owner field is required. Search the progs.dat thread for more information.

necros: Looks good, but also a bit too little shadow-casting on the second shot, no? Also, BJP once recommended using sunlight3 instead of 2, because it would look better or something. 
Infighting Contd. 
grunts always infight; even with eachother. if you're interested in tinkering with the code it's T_Damage in combat.qc. one thing that is pretty easy to implement is an extra monster key (such as 'group' or 'gang' where you can specify that monsters also don't react to damage if targ.group == attacker.group. as to forcing it, you'd probably have to mess with the existing classname comparison... 
Allegiance System 
The relevant code is in t_damage, so this test gets triggered every time a monster takes damage from somewhere.

��if ( (self.flags & FL_MONSTER) && attacker != world)
��{
��// get mad unless of the same class (except for soldiers)
����if (self != attacker && attacker != self.enemy)
����{
������if ( (self.classname != attacker.classname)
������|| (self.classname == "monster_army" ) )
������{
��������if (self.enemy.classname == "player")
����������self.oldenemy = self.enemy;
��������self.enemy = attacker;
��������FoundTarget ();
������}
����}
��}


In this case the rule is: if I'm a monster attacked by somebody, who is not me and is not already my enemy, and the enemy is a different class of monster (or I'm a grunt) then get mad at the new enemy. From now on I'm going to call the grunt behaviour psychopathy.

It's quite easy to add further exceptions to this rule. At the moment monsters refuse to attack other monsters of their type, and for example in Quoth all three types of hell knight extend that same courtesy to each other. If you have lots of this kind of thing going on I would invent a new field like
.float allegiance
Give each mutually trusting group of monsters a unique number for their allegiance and a special value like 0 for psychopaths.

If you wanted to get really complex you could use bit fields instead of just individual numbers for each alliance. Suppose you had:

float ALLY_TECH = 1;
float ALLY_KNIGHT = 2;
float ALLY_OGRE = 4;
float ALLY_ELDRICH = 8;

You might give enforcers just ALLY_TECH and ogres just ALLY_OGRE, but give a cyborg ogre walker ALLY_TECH | ALLY_OGRE so that they ally with both groups. The test for whether the monsters will attack then becomes

if(self.allegiance & attacker.allegiance == 0)

This handles psychopaths like grunts very easily, give them allegiance of 0. It's also important to note that this method is symmetric and reflexive:

Symmetric means that if a will attack b, then b will also attack a. This avoids the situation where a has got mad at b but b will never engage a, so a just keeps attacking b and b stands there doing nothing but looking stupid. If you notice this can happen in your chosen alliance system, add an exception that any monster is allowed to attack another if the attacker's enemy is self - monsters always retaliate to intentional damage.

Reflexive means that a will never attack another a(from the same class). The exception to this rule is psychopaths with allegiance 0, but that was intentional.

An interesting alternative allegiance test in the bitfield case would be

if(self.allegiance & attacker.allegiance != self.allegiance)

This means that I will get mad at someone who attacks me if they are not part of all the alliances I belong to. It's important to see that this is not symmetric: a regular ogre would not attack a cyborg ogre because both belong to the ogre alliance but a cyborg ogre would attack back because the regular ogre is not under the tech banner. So you would need the intentional damage detection code above.

This could be used effectively with large and small monsters, we suppose that small minions would not dare infight with a huge creature they stand no chance of killing, unless it's life or death because the large monster is specifically mad at them. So the result would be friendly fire from the large monster would get shrugged off as an accident.

Phew, having discussed all that complicated stuff above, do be careful where you tread. Players have expectations about which existing monsters will attack each other, so if you are going to vary those rules make sure your mod is obvious about it. You could have a trigger which turns off infighting in a climactic arena battle but it would be very confusing for a player who chose to tackle the battle by intentionally provoking infights and then having no idea why it is failing. Changing the rules for obviously new or altered monsters is probably the best way in anything short of a total conversion. 
 
Also, BJP once recommended using sunlight3 instead of 2, because it would look better or something.

sunlight3 is just the same as using sunlight2 in combination with the command line option -shadowsense 0.4

The shadowsense option is designed specifically to reduce the uniform look of the second sun and it can be given different values to change the strength of the effect. I haven't done any comparisons. Necros, are you using shadowsense in your "before" shot? 
 
Quick question ... where would one grab the latest and most proper QuakeC compiler for Windows? 
 
FrikQCC on Inside3D, I guess. 
 
OK, thanks. Yeah, this must be better than what I was using in the past because it found 3 bugs in my existing source. :P 
 
In my searches for QuakeC stuff, I came across an amazing quote:

"I consider things like autocomplete to be lazy. and I don't like feeling lazy when I code. I don't use an IDE... I use windows explorer, and win32pad for zeh typing."

I hope the meteor didn't hurt him too badly when it slammed into the earth, wiping out his species. Geezus... 
Probably Changed Jobs 
due to excessive carpal tunnel syndrome. 
Wow 
"I consider things like autocomplete to be lazy. and I don't like feeling lazy when I code. I don't use an IDE... I use windows explorer, and win32pad for zeh typing."

Aspergers is a hell of a thing. 
Extra Qc Compilation 
Willem, there's also a compiler called FTEQCC which has a few more features than FrikQCC so depending on how technical you want to get it's worth a look. The main additions I can recall are c-style macros, field name aliasing and inline assembly support so it's for the esoteric kinda stuff. 
 
Thanks Preach. I'll stick with the basic Frik for now. I'm not looking to do anything nutty, just making my life a little easier in places. 
Re: Qc Ide 
wait... CAN you use an ide for quakec?? i've been using textpad because i had too but... damn man, a real ide that loads all the files up and lets me search through the entire thing, jump to function defs etc... would be awesome... 
Re: Sunlight2 And 3 
the shadowsense setting works a lot like the anglesense setting for lights.
it affects how quickly a face becomes dark based on the angle the sunlight2 is hitting it.
this only has an effect if there are many faces that are on slightly different planes (ie: tri soup terrain).
on a flat floor, with walls around, shadowsense has very little effect.
ex:
shadowsense 0.0
shadowsense 0.9

regarding less shadows from main sun, yes, i agree it is an issue.
the problem is that the fake GI is too dark in general, which means i had to use brighter sunlight2 settings which hides the shadows.

maybe some more tests with higher number of suns with even lower sunlight2 or something may yield better results... 
 
You should totally make a catalogue of screenshots documenting how settings change the looks. That would be so super useful. 
Yeah... 
i've been thinking of doing something like that. i'm just a lazy bum. :( 
 
necros

Yeah, you definitely can! I set it up as per these instructions ...

http://ouns.nexuizninjaz.com/dev:programming_introduction#working_with_the_code

I think that's the right link, it's not loading at the moment for whatever reason. But basically it's using the Code:Blocks IDE and installing a QuakeC plugin. I still compile from outside the environment but it gives you stuff like syntax highlighting, searching through the entire project, intellisense, etc. 
 
thanks for pointing me to that! i had no idea! :D 
Vis 
been out of the loop for a while. Does anyone know any ways of tricking Vis into thinking an area is not visible even when it normally would be? For reasons that are fairly fiddly to explain, it doesn't matter if it causes a whopping great HOM. 
Kinn 
Only two things I can think of are:
* Using the version of vis that lets you set a maximum visibility range - afraid I can't remember which one this is but if you're interested I'm sure someone can supply it.

* Using skip brushes to obscure it, but then that does actually create a physical block as well as a vis block.

In theory the quake bsp format should support this kind of weird vis behaviour but I don't know of any examples in practice. 
 
i would use a real directional sun in addition to the global illumination -- the latter is just for filling in light that would be coming from the rest of the sky. if you have a lack of shadows it's the lack of a real sun :) 
Kinn 
It would help if you described better exactly what it's for. I would say there's little you can do to trick VIS. Skip works if you don't mind a HOM (or grey/red void view for those who use gl_clear), but this sounds like a very hacky solution, unless you're maybe thinking about using it in a hint brush sort of way, masked with a func_illusionary or something like that.

Has anyone every experimented with that maximum visibility range thing? Does it even work? 
Maximum Visibility Range 
Tried to use it, its inconsistent at best, random at worst. Cant use it like q3map2. Afair hvis has it. 
 
necros: that link to the multithreading vis doesn't work...

negke - hard to describe. I just wondered if i could sticky-tape up some bullshit I did caused by years of working with engines where you have to do all the geometry culling manually. It's no biggie - I can easily rework my layout to play nicer with Quake. 
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.