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
@metlslime 
I told the code to print the fish's corpse self.watertype, and "-3" show up in the console. I don't know what "-3" means, but it was printed just one time, like the code is ignoring the self.think and not checking again if the fish is still in the water :P 
Darkplaces Engine Bug 
in the darkplaces engine, fiends get stuck on geometry all the time. Does anyone know specifically what is happening? I'd like to fix or attempt a workaround. 
 
Some dark places differences can be toggled using cvars. Usually they start with “sv_gameplayfix_” so take a look at those to see if any of them fix it. 
Darkplaces Engine Bug 
Nope doesn't appear to be a relevant fix. 
 
That's just how Darkplaces do, as far as I know. Its physics code has been changed for various reasons. 
Darkplaces Engine Bug 
Sorry to be rude but I'm looking for a technical response or even a guess, rather than that non-answer.
Engines are extremely complicated so "That's just how it do" is an understandable response though :D 
Darkplaces Engine Bug 
Even a basic idea like are they literally getting stuck in geometry, or failing to navigate around it? Is it a bug in pathing code or collision code? Something else? 
Darkplaces Engine Bug 
Or perhaps someone can help with detection of if they are stuck or not from within QuakeC to apply some hackery.
Currently I am storing their coordinates in one animation frame and comparing with coordinates in the next frame:

autocvar_DemonLoc = self.origin_x;
autocvar_DemonLoc2 = self.origin_y;
};
void() demon1_jump5 =[ $leap5, demon1_jump6 ] {self.nextthink = ((time + 0.1) - autocvar_monster_rangedattack_animation_speed_factor * 0.001);
if (autocvar_DemonLoc == self.origin_x && autocvar_DemonLoc2 == self.origin_y)
{

But I am hoping I can do much better than this. 
Totalitarian: 
I didn't explain myself very well. Darkplaces has a number of "gameplay fixes" which address quirks of the original engine that are objectively wrong, but fixing those quirks will break vanilla gameplay.

Those fixes can be turned off using the cvars, turning them off gets you closer to vanilla behavior and might make your Fiends work again.

Due to this, most people here will not recommend Darkplaces for playing standard quake maps or mods, since they often won't work correctly. Darkplaces is often recommended more for devs trying to make a brand new game (or a mod that only intended to work in Darkplaces), since they don't need to worry about compatability in that case. 
 
speaking of darkplaces: has development stopped? it was heavily focused on Nexuiz, but Xonotic has its own thing now, so... anyone actually working on DP? 
Darkplaces Engine Bug 
@metlslime as of version whatever, Darkplaces has all those "gameplay fixes" cvars disabled by default. Furthermore I am making an add-on for an existing mod built upon Darkplaces, so changing engine isn't really an option. 
Mr. Clean's QuakeC 
Found this nice QuakeC repo that's been tidied up and fixed, although at first glance not sure how many QIP fixes are included. Still a good resource.

https://github.com/Jason2Brownlee/CleanFixedQuakeC 
Currently Working 
On a trimmed-down progs.dat with only essential URQP fixes (e.g. megahealth rot, fish count, walkframe leak, door unlock sound) since I consider it bloated with all those extra options Maddes added which almost nobody would use. At least in singleplayer, which is what I am interested in. Based on Preach's cleaned-up QC 1.06 source.

Compared to the progs.dat I am using in the vanilla fixes or AMQ, it's shaving off at least 60 KB of extra code. Doesn't sound like much, but it's all about what you really need. 
@nightfright 
That's crazy I was thinking about the same thing today. I took those fixes for SMP 2021.11 from Quake Info Pool and then URQP.

I realized it would have been better to start there and strip stuff out but it's too late for my project. Good luck. 
Is There Any Tutorial 
About how to add Deathmatch modes 3-5 to vanilla code? Even though I am focussed on SP changes, I think this is something that should be in, anyway. 
QuakeC Cleaned With Fixes 
Up for review here:

ID1 cleaned source + selected URQP fixes (1 MB)

I would really appreciate if anyone with profound QC knowledge did a thorough review of all the fixes I applied. Everything compiles just fine, but I might still have made some mistake(s). Especially the DM stuff couldn't be tested.

All edits should be sufficiently commented. If you want to see a complete list of all changes, please look into progs_fixed.src (which you also need for compiling the fixed version, progs.src only gives you cleaned up code without any other changes).

BTW: I added a few fixes going beyond URQP. 
QuakeC: Control Viewpoint Angles 
Hey! So, I need some help with this.

I'm working on a mod to put Q2 weapons into Quake. Similar to the Quake 2 Weapons Project from long ago if anyone remembers that.

I got this menu system where players can select a marine to play as: Q1 ranger or Q2 marine. It works pretty well but I have some trouble with the viewpoint angle. I want to lock the viewpoint so the player can't look around until he's selected a class. I can lock the viewpoint alright, the problem is that it'll snap to the wrong angle; 90 degrees to the left or right of the spawnpoint angle usually, and no matter what I try I can't reorient it to look in the right direction.

Here's the code in question:


void() SetMarineClass =
{
local vector loc, ang;
local entity spot;
spot = SelectSpawnPoint();// store the spawnpoint orientation

// disable weaponmodel if we don't have a class yet.
if (!parm11)
self.weaponmodel = string_null;

// Kex fix: delay select text for 0.5 seconds
if (marine_select_wait < 30)
{ marine_select_wait += 1; }

// postpone until wait timer has reached 0.5 seconds / exit if we already have a class
if (marine_select_wait < 30 || parm11 || self.marineclass)
{
menu_origin = self.origin;
menu_marine_selection = 1;
return;
}

// spawn a marine to display as menu choice
else if (marine_select_wait < 1000) // bogus value - doesn't get reached until we set it here
{
// self.v_angle = self.angles = spot.angles; // does nothing wtf?
// self.fixangle = TRUE; // turn this way immediately
makevectors (self.v_angle);
ang = self.v_angle;//spot.angles;

loc = self.origin + v_forward * 100 + v_up * 12;
menu_mdl = SpawnMenuMarine(loc);
menu_mdl.solid = SOLID_NOT;
setmodel(menu_mdl, "progs/player.mdl");
menu_mdl.frame = 12;
marine_select_wait = 1000;
}

// don't let monsters see us
self.notrace = 1;

// rotate menu model every tick
menu_mdl.angles_y -= 2;

// print class options
centerprint(self, "Choose your marine (1-4):");

// restrict movement
self.origin = menu_origin;
self.velocity = '0 0 0';
// restrict view
// Only keeps the correct rotation for the copper start map. Player gets insta-rotated 90 degrees to the left/right in other maps.
msg_entity = self;
WriteByte(MSG_ONE, 10);
WriteAngle( MSG_ONE, ang_x);
WriteAngle( MSG_ONE, ang_y);
WriteAngle( MSG_ONE, ang_z);
// put the marine in front of us at all times
makevectors (self.v_angle);
menu_mdl.origin = self.origin + v_forward * 100 + v_up * 12;



As you can see from the code that's been commented out, I've tried out a few different things to make this work. The result is always the same tho. The player's viewpoint ends up pointing 90 degrees to the left or right of the spawnpoint direction. I'm out of ideas for this one. Does anyone here know what I'm doing wrong and how to fix it?

Here's the pak and progs.dat if you wanna try it out and see for yourself:

https://drive.google.com/file/d/1fpnM1e1_Ux2wcrx2GAuXbVFW_bpkh7ql/view?usp=sharing 
Experiment 
What happens if you try out different hard-coded values in your WriteAngle code?

msg_entity = self;
WriteByte(MSG_ONE, 10);
WriteAngle( MSG_ONE, -20);
WriteAngle( MSG_ONE, 45);
WriteAngle( MSG_ONE, 10);

recompile

msg_entity = self;
WriteByte(MSG_ONE, 10);
WriteAngle( MSG_ONE, 40);
WriteAngle( MSG_ONE, 100);
WriteAngle( MSG_ONE, -25); 
Success! 
Ohh found it. Seems like I made a dumb mistake. 'ang' was a local variable that only got set once, so after the one-off conditional had finished it would just stay zero forever.

Thanks for helping! Here's how the code looks now:

void() SetMarineClass =
{
local vector loc, ang;
local entity spot;
spot = SelectSpawnPoint();// store the spawnpoint orientation


// get orientation from spawn point
self.fixangle = TRUE; // turn this way immediately
makevectors (spot.angles);
ang = spot.angles;


// disable weaponmodel if we don't have a class yet.
if (!parm11)
self.weaponmodel = string_null;


// Kex fix: delay select text for 0.5 seconds
if (marine_select_wait < 30)
marine_select_wait += 1;

// postpone until wait timer has reached 0.5 seconds / exit if we already have a class
if (marine_select_wait < 30 || parm11 || self.marineclass)
{
menu_origin = self.origin;
menu_marine_selection = 1;
return;
}

// spawn a marine to display as menu choice
else if (marine_select_wait < 1000)
{
loc = self.origin + v_forward * 100 + v_up * 12;
menu_mdl = SpawnMenuMarine(loc);
menu_mdl.solid = SOLID_NOT;
setmodel(menu_mdl, "progs/player.mdl");
menu_mdl.frame = 12;
marine_select_wait = 1000;
}

// don't let monsters see us
self.notrace = 1;

// rotate menu model every tick
menu_mdl.angles_y -= 2;

// print class options
centerprint(self, "Choose your marine (1-4):");

// restrict movement
self.origin = menu_origin;
self.velocity = '0 0 0';
// restrict view
msg_entity = self;
WriteByte(MSG_ONE, 10);
WriteAngle( MSG_ONE, ang_x);
WriteAngle( MSG_ONE, ang_y);
WriteAngle( MSG_ONE, ang_z);


// press 1-4 to select
if (self.impulse == 1)
menu_marine_selection = 1;

etc... 
Why Doesn't My Function Run? 
I created a new class chaos.qc and added it to progs.src. I get no compiling errors but when I load up a DM map nothing happens. The bprint doesnt even show up. Trying to add monsters to DM using info_player_deathmatch entity as spawns.

Heres my code contained in chaos.qc:

void() chaos_monsters =
{
bprint("started");

entity spotMon;
entity newMon;

if((total_monsters - killed_monsters) <= 16){

bprint("spawn");
newMon = spawn();
spotMon = SelectSpawnPoint();
precache_model2 ("progs/enforcer.mdl");
precache_model2 ("progs/h_mega.mdl");
precache_model2 ("progs/laser.mdl");

precache_sound2 ("enforcer/death1.wav");
precache_sound2 ("enforcer/enfire.wav");
precache_sound2 ("enforcer/enfstop.wav");
precache_sound2 ("enforcer/idle1.wav");
precache_sound2 ("enforcer/pain1.wav");
precache_sound2 ("enforcer/pain2.wav");
precache_sound2 ("enforcer/sight1.wav");
precache_sound2 ("enforcer/sight2.wav");
precache_sound2 ("enforcer/sight3.wav");
precache_sound2 ("enforcer/sight4.wav");

newMon.classname = ("monster_enforcer");
newMon.solid = SOLID_SLIDEBOX;
newMon.movetype = MOVETYPE_STEP;

setmodel(self, "progs/enforcer.mdl");

setsize(self, '-16 -16 -24', '16 16 40');
newMon.health = 80;

newMon.th_stand = enf_stand1;
newMon.th_walk = enf_walk1;
newMon.th_run = enf_run1;
newMon.th_pain = enf_pain;
newMon.th_die = enf_die;
newMon.th_missile = enf_atk1;

newMon.origin = spotMon.origin + '0 0 1';
newMon.angles = spotMon.angles;
newMon.fixangle = TRUE;
walkmonster_start();

}
}; 
CasJak: 
The function won’t run just by existing. It would need to be called by something else. One exception is if it’s name matches the class name of an entity in the map. This is how spawn functions are called. In your case, I assume there is not an entity in your map called chaos_monsters.

Also, it appears you want to run this in a loop so that it keeps spawning entities. Currently this code would only attempt to spawn one monster and then be finished. Or, if you want to run at most one monster per frame, you could call this function at the start of the frame. 
Metlslime 
How would I call it at the start of a frame? 
 
In world.qc there is a function called StartFrame, you could try calling it there.

On the other hand, it might be better to create an invisible entity to control all of your monster spawning logic, which can then use think and nextthink to periodically check on the state of the world and spawn more monsters when appropriate. If you do it that way, that entity could be created from the worldspawn function. 
Also... 
You might check out Aardappel's "DMSP" mod, which does something similar to what you're working on. It has source code too so you could use it as a reference.

https://strlen.com/maps/dmsp/index.html 
Hhmmm.. 
I guess I’m just not understanding something about how the engine operates. I created an entity with the worldspawn function. It has the same classname as the function above but the function doesn’t run. I obviously am not doing this right haha. I’m trying to spawn the monster handler entity and then make it run a function. That way this mod will work on any DM map. Must be above my skill level right now… Going to have to study that mod you linked. 
First | Previous | Next | Last
Post A Reply:
Name:
Title:
Body:
message
question
exclamation
idea
flame
noflame
error
skull
beer
moon
pent
rocket
sheep
pacman
pig
cheese
worldcraft
gauntlet
crate
pitfall
pimp
smile
cool
sad
frown
oi
yay
tongue
evil
wink
neutral
q1
q2
q3
ut
hl
cs
doom
dkt
serious
cube
Website copyright © 2002-2021 John Fitzgibbons. All posts are copyright their respective authors.