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:
First | Previous | Next | Last
no, it's not possible in anything that doesn't have engine support.

i've been trying to haxor that in with only qc for a while, and it's just not possible without massive haxoring (ie: storing player information in console variables like cl_forward or other weirdo crap and then abusing save/loadgame console commands).

the problem is that you only have 16 floats that you can carry across to other maps, 10 of which are already in use. if you wanted to do anything more complex than fire a few triggers off, you're out of luck.
the best you could hope to achieve is to use bit fields on the 6 (7 if you get rid of one parm that's not really needed) to get 6 * 24 = 144 on/off states. and that's incredibly limited.

using an engine that supports FRIK_FILE (which lets you write external files from QC) allows you to save entity states yourself via qc. this is what's used in prydon gate, iirc. 
interesting... if you change line 1350 in ltface.c from:
SkyLightFace (&entities[0], &l, SunLight[i != 0], SunLightColor[i != 0], SunMangle[i], i > 0);
SkyLightFace (&entities[0], &l, SunLight[i != 0], SunLightColor[i != 0], SunMangle[i], false);
this disables minlights on _sunlight2.
then, change the constant NOOFVSUNS in light.h from 4 to 32
coupled with very low _sunlight2 numbers 2~4 will yield a pretty decent fake GI effect like lunaran's recent map... 
that's for MH's version of aguirre's light.exe 
yeah i actually did something like that myself a couple years ago... never got it polished up enough to really be usable though. For example i wanted to generate a full sphere (or half-sphere) of really dim suns for true global illumination / ambient occlusion.

I also had a related idea where seeing the sky wasn't necessary, it would simply shoot rays out in all directions from a surface and the farther the ray could go, the more light i would add (as if teh air itself glowed a bit) -- might look good in skyless interior spaces. 
... but i think this is worth pursuing because the current state of outdoor lighting in quake maps is people just throw in a sunlight and sunlight2 and think they're done, and it looks really flat and bland to me. Global illumination would look much better without any extra work on the mapper's part. 
yeah, aguirre was on the right track when he implemented the minlight skydome idea for exterior minlight, but the results of using additive lights instead of min lights is really quite remarkable.

also, a little more testing found the previous 32 v suns to be way excessive.

12 HSuns and 12VSuns is enough to get a really good and smooth fake GI look.
also, you need to disable the VSun changes for -extra modes. specifically, the if block concerning oversampling around line 1300. just comment it out completely and set NoOfHSuns to 12. you don't want the number of suns to vary now because they are additive and will become brighter in -extra4 mode.
i'm not smart enough to figure it out atm, but i'm sure someone could just take a look at #of suns and divide the light level to keep things consistent, but i found it probably wouldn't matter since at 12x12 suns, it's fast enough to not really matter much when using -fast but won't be insanely slow in -extra4 more (in my original post, it was probably 32x32=1024(!) suns in -extra4 mode which is... ridiculous. 
Mind You... 
this is all just testing on a small ~1000 brush map with only 8000 faces.

i imagine, because of the way light works, with a full size map with tens of thousands of faces, it'll have a much bigger impact on light times. 
i guess a couple of screenshots are in order...

here is the original light, sunlight:220, sunlight2: 60

and with the haxored version, sunlight: 100, sunlight2: 2 
forgot to comment on this:

I also had a related idea where seeing the sky wasn't necessary, it would simply shoot rays out in all directions from a surface and the farther the ray could go, the more light i would add (as if teh air itself glowed a bit) -- might look good in skyless interior spaces.

this sounds quite awesome, honestly... would make a good base light pass. 
that is awesome! the second screenshot looks way better than the minlighted-sunlight. going to have to try that next time I do some mapping.

re: light fantasies, one I was thinking would be cool is if light.exe projected light from fullbright pixels of textures. you could even have the light color be the color of the fullbright, or plain white, or somewhere in between for a subtle effect. 
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 == 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. 
"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... 
First | Previous | Next | Last
Post A Reply:
Website copyright © 2002-2023 John Fitzgibbons. All posts are copyright their respective authors.