News | Forum | People | FAQ | Links | Search | Register | Log in
Coding Help
This is a counterpart to the "Mapping Help" thread. If you need help with QuakeC coding, or questions about how to do some engine modification, this is the place for you! We've got a few coders here on the forum and hopefully someone knows the answer.
First | Previous | Next | Last
I figured it out. It uses the entity as the start point regardless of the co-ordinates passed. And this is why the lightning beam starts at the origin of the player, regardless of anything else. 
beams last 0.2 seconds. QC respawns them every 0.1 seconds.

the entity argument is just there to avoid the resulting double-beams issue (trying to depend upon precise timing would be too unreliable with network latency etc, hence why they last longer).
Using world would break when you have two players firing beams, although some engines do understand world to mean 'don't replace any beams'.
tbh 99% of the time that entity arg will be self.

ignoring the startpoint and using the player's position is just to smooth things out so that the player doesn't leave the beam behind when moving sideways etc.

note that there's already an engine extension to provide those as builtins (with that name), so beware of potential conflicts if a modder uses *extensions.qc. 
W_FireLightning Start Origin Incorrect On Players? 
original code has

LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);

(even URQP has it that way)

But i had long changed it to

LightningDamage (org, (trace_endpos + (v_forward * 4)), self, 30);

this is especially obvious when shooting from RL window on DM3 and aiming at someone on the lower bridge.
this is because:

org = self.origin + '0 0 16';
traceline (org, org + v_forward*600, TRUE, self); 
The original is "waist lightning". Darkplaces has specific settings to let you pick which style you prefer, waist or gunpoint. 
That only fixes the position of the bolt VISUALLY, which is what Spike was explaining. The above fixes the tracelines/damage as well. 
ya the original deals damage from the gun but visially it came from the hip
i keep confusing myself that sel.origin is the bottom of the model
where the feet touch the floor 
Trigger_push Project 
Still taking baby steps into QC with very little coding background. Wanted to check with experienced coders. This bit of code makes a trigger_push silent with a spawnflag. It appears to be working fine in game and no errors in FTEQCC but I feel like the syntax is still wrong.

Next steps will be to learn how to toggle it and add custom sounds.


float PUSH_ONCE = 1;
float PUSH_SHHH = 2; //DMS push silently

void() trigger_push_touch =
if (other.classname == "grenade")
other.velocity = self.speed * self.movedir * 10;
else if ( > 0)
other.velocity = self.speed * self.movedir * 10;
if (other.classname == "player")
if (!(self.spawnflags & PUSH_SHHH)) //DMS
if (other.fly_sound < time)
other.fly_sound = time + 1.5;
sound (other, CHAN_AUTO, "ambience/windfly.wav", 1, ATTN_NORM);
if (self.spawnflags & PUSH_ONCE)

/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE
Pushes the player
void() trigger_push =
InitTrigger ();
precache_sound ("ambience/windfly.wav");
self.touch = trigger_push_touch;
if (!self.speed)
self.speed = 1000;

You could also check the spawnflags in the spawn function and only precache the sound if needed. 
Quakedroid would be about the only reason not to just precache everything. 
What does this mean?

if ( (rand()&3)==1 
if ( (rand()&3)==1
rand() returns a number between 0 and RAND_MAX.
&3 truncates all but the lowest 3 bits (so a random number between 0 and 3 inclusive).
==1 gives you a 1-in-4 chance of being true.
and there's no closing bracket, so the entire thing is a syntax error and won't even compile.

of course, rand's randomized bits are generally least reliable in the lower bits, so the above might be quite predictable, but it depends upon the rand implementation. 
Truncatorial bitwise AND. Mkay.

So 25%ish chance in movetogoal to "bump around" using the wall following code if the monster can't step in the direction of its .enemy

I guess that makes (rand()&1) evaluate to 50%ish chance. 
lowest 2 bits, sorry. and yeah, bitwise and.

movetogoal is just all kinds of screwed tbh. its very much an attempt to replicate doom's monsters, but in a way that's 5+ times as expensive due to all the floor checks etc. it can't slide along walls so can't deal with narrow passageways, etc. it works well enough, but its far from ideal. 
Its strung out multi-function calling madness yes. Trying to recreate it. 
Which Coordinates Do I Use For ReMStud? 
So I got the save file and the console output, but I can't seem to find the correct coordinates for putting the camera in one place and a place to view it. What set of coordinates do I use for the 3 sets I'm given from the console output? 
Not sure it is what you're aiming, but in a mapeditor with a viewscreen it is easy to turn the view camera and the info_camera aligned.
Just make sure the arrow of both viewpoints are the same. 

Here is a rotfish fix I knocked up for otp. It fixes the fish count, makes fish gibbable, makes them non-solid straight away when dead, and includes a fixed fish.mdl due to the bugged head size in the death frames.

It's all combined in a pak2.pak so it can be used as an id1 fix if you drop it in there.

Source is included, only fish.qc and monsters.qc have been modified however. 

This is a command line based tool which will read a QuakeC progs.src and all .qc source files listed within, and output a .DEF file compatible with a map editor such as TrenchBroom.

This assumes your QuakeC source files contain /*QUAKED*/ style definitions such as those found in the original id software QuakeC sources, as used by the original QuakeEd. For example, from items.qc in the original source:

/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)

This makes the laborious task of hand creating a .DEF file a thing of the past, as long as you include the relevant entries in your QuakeC sources when adding or amending entities. While not as powerful as .FGD files, .DEF files have a place and can be a quick way to add map editor support for your new mod!

Source code is included as a simple .c file, which should build on any C99 compiler. 
Oh!! That's what those hideous comment blocks are. I figured it was just a way for someone to copy and paste it over into some wierd editor definition in case they lost it. It sounds cool but I still don't understand the use case.

What other formats are there other than .def and .fgd? 
The use case is that the original QuakeEd (that id developed and used on NextSTEP to make the original maps) parsed the .qc files and used those definitions to display what entities were available.

The modern use is that all the entries can be stuffed in a .def file and trenchboom (etc) can use them to populate the entity list.

I'm not aware of anything other than .def and .fgd, but maybe there are other formats in use in some of the more esoteric editors. 
Not Convinced 
This makes the laborious task of hand creating a .DEF file a thing of the past, as long as you include the relevant entries in your QuakeC sources when adding or amending entities. While not as powerful as .FGD files, .DEF files have a place and can be a quick way to add map editor support for your new mod!

This is a bit of a tautology - the reason those comment blocks were there was so that ID could write the .def file inline, and then extract it into a single file using a command line tool. The comments don't do anything for the QuakeC processing of the file. You're basically saying you can take all the effort out of writing the .def file, so long as you've already written the .def file. 
Thats true however I think the original QuakeEd read the QC files directly at launch and there never was a tool to pull the definitions out into a .DEF. I may be wrong though. 
That's True 
quakeEd already supported cleanly ignoring anything that wasn't contained in a /*QUAKED */ comment block, and when I discovered I could just point qe3 at lunsp2/src/*.qc instead of maintaining a separate .def file an angel got its wings

(the other clue to this is that the comment blocks start with /*QUAKED in the first place ...) 
Would Be Nice If 
There could be a utility that generates a list of all functions in the qc like so:
Function(float arg1, vector arg2),called 0 times, precache Yes
W_Attack(),called 1 times,
weapon_blaster(), called 0 times, precache Yes
SUB_Remove Edicts Piling Up 
I have a problem with edicts piling up that have no information other than Think = SUB_Remove and Time = -1. I'm not sure where to look in the qc to find what's causing it. Do TE_STREAM_* ents look like this in the edicts dump? 
Code Request 
Hi Shanjaq. TE_STREAM_ things aren't using up your entity slots, "temporary entity" is just a bad name for them. So the problem must be elsewhere.

Think = SUB_Remove and Time = -1

Can you post the full lines of code that these quoted parts come from? It's hard to tell if they're right or wrong from what you posted. 
ent.nextthink <= 0 means the entity will never think, and thus never get removed. use 0.1 instead, or something.

note that the remove builtin will also set nextthink=-1, clear classname+model, but not clear the remove builtin.
those removed ents will be reused later (no sooner than 0.5 secs). so if you're spawning+removing within the same frame then you're going to have at least 0.5 seconds worth of them building up.
qc can still read+write removed ents (unfortunately), but nextent+find+findradius won't find them, and saved games shouldn't list them so I've no idea if this is what's causing them or what - how are you seeing this list of useless ents? 
Edicts Anonymous 
Thanks all for your insights! I'm wondering if there's a leak somewhere in the edict de-allocation, as I sometimes see models/sprites frozen in mid-animation which have no clipping and findradius can't see them. Here is a snippet from edicts.txt after a crash. note the last two, which I'm seeing in the hundreds:

Fte Quake C Dev 
While changing from ftcq to fte dev compiler I found some small errors. And before get passed with an unknown punctuation, I see for all monsters:

warning F307 type mismatch void entity_pain to void (entity_attacker, float dammage) self.th_pain

What is the statement to catch this error? 
You need to pass inflictor as well:

void (entity attacker, entity inflictor, float damage) th_pain; 
Usually just self. This is used to differentiate between the projectile inflictor (e.g. the rocket, self) and the attacker (self.owner). 
Just add "(entity attacker, entity inflicter, float damage)" to each monster's pain functuon. Example:
void () ogre_pain = {

void (entity attacker, entity inflicter, float damage) ogre_pain = {

WAIT WAIT...just attacker and damage. AD adds inflictor. 
Yes, Thanks! 
Most errors are fading, when I changed it in an addon monster, but it still keeps errors.
They're not major but when I try to change athe Vore's pain it loops back to the self.th_pain string. And for Shub's error I can't find a pain function, but SUB_Null.

The error starts in client.qc (line 552) PutClientIntoServerclient.qc at the statement for
self.th_pain = player_pain; 
I had changed my defs.qc into .void(entity attacker, float damage) th.pain!
Me donkey. 
It needs to be that way, so it's the other way around.
I think fte looks for more loose ends than I thought, while it still passes the progs.dat.
Strange that doors.qc with its self_pain error. 
if you just want to silence the warning, you can do:
self.th_pain = (void(entity,float)) foo_notquitepain;
Such casts are generally not recommended as they'll not catch any future changes to your 'foo_notquitepain' function, and you should only ever ADD arguments to the rhs when casting functions (removing/changing args results in the function getting gibberish for the args that were not passed, or passed as the wrong type).
Such explicit casts should always be seen as a claim by the programmer that they know that the result will be safe despite its inconsistencies.

The vanilla qcc just saw function types, and didn't bother to validate the return types nor parameters. whereas fteqcc is somewhat annoying and warns about any inconsistent code that it sees.
Its worth noting that the vanilla qc code is inconsistent but not otherwise buggy. You could fix it purely using casts if you wanted to, but its cleaner to just add the extra args.
And yes, there is some door or trigger or something entity that mixes up touch functions and pain. You can fix that occurrence with a wrapper, but a cast will perform better - not that its significant enough to matter at all. 
Thanks for the info, that keeps me going! 
New Monster Qc 
I'm trying to make a new monster, that shots nails and launches rockets. When I run the qc the monster shoot nails and launches rockets at a low angle, half from bottom.
Also the two actions bump at the same time and I have no idea where to look.

Where is the statement that give more time between the actions? 
Rabbid Fire 
As long as the player is running the relation between missiles and nails is almost even, but when it is tricked into a corner the thing blasts missiles every 0.5 second.

That's no way of surviving, I know it is called Terminator, but unlimited charge is no fight. 
...half from bottom... try changing the offset amount from '0 0 10' in TermMissile to higher amount such as missile.origin = self.origin + '0 0 24'; or try copying the value you used for org in LaunchZhaser if you want the missiles to fore from the same place as zhasers do.

missiles every 0.5 seconds you have melee set to fire missiles. If you stay back away then he will only shoot zhasers.

Maybe if you want more delay add more frames or add an attack_finished check. 
Or do
self.th_missile = sknt_atk1;
self.th_melee = sknt_atka1;
To switch it. 
What do you mean bump? 
The Enforcer.qc has a code for setting the laser
org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
and as far as I can see the v_foreward sets the space that messures the armlength foreward, and v_right is the distance from the entity to the right sideways.

I'm looking for the space upward, as a terminator that launches from under the belt is a bit odd. In game it is not so pronounced as with testing.

I will try your statements in the hope they lead to a better result. For sofar here is the map as far as I have finished it. The scr file is included. I've played the map myself only, and I think the gamepath isn't realy clear.

Vector Upwards 
Hi madfox, have you tried using v_up? That's the "upward" vector I think you're after. 
Belt Blaster 
@-Qmaster Changing the self.th_melee = atka1; worked for splitting the attack in two different shapes. Although I don't see the reason why self.th_melee = sknt_melee won't work.
It is defined as sknt_melee = sknt_atka1; (?!)

@-Preach : sure, but I can't find the place for the statement.
Whatever I add or change it seems 7up for the compiler.
missile.origin = self.origin + '0 0 10'; is the place to look I think? 
That's The Correct Line 
That's the right line to modify, keep playing with it until you get an effect you like. 
Algebra Dabra 
the only way I can make the missile launch higher is when I exclude
//missile.origin = self.origin - normalize(self.velocity);
missile.nextthink = flytime + time;.
Then the changes seem to have effect, although I get an eyeheight missile launching and ending on
missile.origin = self.origin + v_forward * 8 + v_right * 1 + v_up * 10; 
Changing The Order 
Yeah, that would be the problem. Notice how both lines are setting the value of the same thing - missile.origin. The second line completely overrides the first one, like changing your order in a restaurant - you don't get two meals, you just get the second one. 
Right, Uhm Wrong 
missile.origin = self.origin + v_forward * 8 + v_right * -16 + '0 0 24';
returns a launcher that shoots from the launching point left above the player.

missile.origin = self.origin + v_forward * 8 + v_right * -16 + v_up * 16;
returns a missile that explodes left of the player.

I'm thinking I'm changing the end point of the missile hitting the player. It launches from the right point, but it ends up blind. Also the negative parm comes out strange. It's not left handed? 
In TermHome,
dir = normalize(vtemp - self.origin);

I used the enforcer_laser methode to launch the missile.
This way it is the simpelest way to compile for the wanted use.
The code was from the Orb, and I had a hard job on coding the weapon.

Thanks for the hints!
They were helpfull. 
Rubicon 2 question:

You have IT_NO_WEAPON replacing IT_EXTRA_WEAPON in the code. However, I'm not sure how to implement this in a map. Not seeing a spawnflag or other way to enable it. 
Trace Volume? 
Is there a way to trace a volume similar to traceline? I need to find a volume that is not occupied by players or monsters of any size. maybe something like traceline? 
any decent engine will have a tracebox builtin for things like that.

failing that, you can also exploit quirks of droptofloor or walkmove(typically with FL_FLY?), but these are much more limited and may have additional engine-specific quirks that break your mod (at least in DP). 
Something I wrote before on how you might write a tracebox function using the method Spike suggests. His caveats stand 
Spawning with no weapons works but was never used in any of the maps so I didn't finish the part where an info player start can opt in to it. Right now it's just hard coded so to only happen if mapmame == test.bsp

So you would have to make some quakec change to complete the feature, or just change the hard coded string it's looking for -- or name your map test.bsp :) 
2 posts not shown on this page because they were spam
First | Previous | Next | Last
Post A Reply:
Website copyright © 2002-2019 John Fitzgibbons. All posts are copyright their respective authors.