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
Painting Method? 
draw a bit, smudge a bit, draw a bit, smudge a bit...

The idea behind this particular hellknight is that I wanted to create a monster that looked like he might have a fate worse than death in store for you. I mean you look at a regular hellknight and you think "yeah he looks like he wants to kill me", but then you look at this new hellknight and you probably think "he looks like he might kill me, but then again he looks like he might do something else to me". And that is one hell of a terrifying concept.

Btw - you lot might find these curves i made useful:

http://dl.dropbox.com/u/61424391/Temp/photoshop%20curves/photoshop%20curves.rar

take any layer in photoshop that has been desaturated to grey, and apply one of these curves to it. Voila! You now have a deliciously Quakey colour!

When you flatten your final image to the quake palette notice that you will get the closest possible colour preservation on these quakerised bits.

I must emphasise - only apply these to grey things, or the colouring will not work. 
Saving Map State Across Level Changes 
Are there any mods that can do this?

What i'm thinking I want to do is have the player leave the current map and go to another small level for a little bit then come back to the main map and have it be in the same state as when they left.

is it possible to do in Quoth for example? That would be perfect :))) 
Thanks 
 
 
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);
to
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... 
Sorry 
that's for MH's version of aguirre's light.exe 
Necros 
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
http://necros.slipgateconstruct.com/temp/fakeGITest_0.jpg

and with the haxored version, sunlight: 100, sunlight2: 2
http://necros.slipgateconstruct.com/temp/fakeGITest_1.jpg 
 
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. 
Necros 
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. 
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. 
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.