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
Thanks A Lot Preach! 
 
Opening A Can Of Worms 
So the next step in my mod is to add my lines of code into the latest quoth release by decompiling it. I could stop here and just have the Infantry Gun, Gatling Gun and Nail Infantry, but for what I want to do I'd love to use quoth's expansion as well as my stuff on top of it, stuff like more base monsters (or hell, more monsters in general), rotating doors, teleporting enemies... all of that good stuff.

So I've been doing a bit of research. I tried this: http://quakeone.com/files/10-miscellaneous/95-mrelusives-quakec-compiler-1999/ but it says the directories don't exist despite what seems to be a clean command line ("path to progs.dat" -d). Then I red this: http://www.quakewiki.net/archives/botshop/code/plus.txt and downloaded said software. When executing it, Windows says the program is not compatible with my current version of W8.1.
Going back to the first software, I grabbed its progs.dat on the software's directories, but it says after analyzing progs.dat "DEC_CalcProfiles - No parameter names with offset 377".
Anybody can help me there? 
Man, Is Decompiling Such A Taboo Thing? 
 
 
"DEC_CalcProfiles - No parameter names with offset 377".

that basically means that the qcc stripped out the names (and very probably types too) of locals.
this means that if you can find a decompiler that makes stuff up, you'll still end up with what is basically gibberish.
You do NOT want to have to maintain that.

I have a private fork of frikdec which will try to decompile anything. nothing is fatal, it just writes out a best-effort instead. which is gibberish.
I don't give it out for a few reasons:
1) I don't want the flak from modders pissed at me for opening up their closed mods.
2) I don't want to have to maintain it.
3) I REALLY REALLY REALLY DO NOT want to have to help other people get it to compile.
4) any encouragement to get people to work on decompiled code is a baaaad idea.
5) unmodified frikdec is good enough for most purposes. mods that it can decompile generally have enough usable hints to not result in gibberish.
6) this way madness lays.

years ago, I did toy with the idea of 'appending' to a progs.dat file. load an existing progs, compile some new code, write out a new one with the extra code added (with some functions wrapped or whatever).
I didn't get very far with it though.

by the way, decompiled code sucks. 
Daya 
If the mod is closed source, your best bet is to approach the authors and ask nicely.

Decompiling isn't really the way forward. 
Changeroll () 
Anyone know where I can find a good QC written function for this one that ID left out? I found one in another forum but its usinf a function called anglemod_view () which has a lot of while statements and seems prone to runaway loops. Mostly because it seems to have problems with a 360 degree roll. 
Private Spoon 
Sorry for the Malice progs.dat
Even when the ones that created feel sorry now for their encriptment. 
Kinn 
I sent Preach an email about that subject yesterday evening. I'm waiting for his response. 
Compiler 
What QC Compiler would you recommend nowadays? 
Fteqcc 
 
I think it's the only modern one..? 
Don't Call It Monsterclip... 
New blog post, detailing how to create func_player_clip, and func_nonplayer_clip, which are solid only to players and non-players respectively.

https://tomeofpreach.wordpress.com/2015/11/18/selective-clipping

It's not technically monsterclip, because it is solid to other things as well. But as long as you use clipping brushes, the set of non-player things which will collide with them and the set of monsters are essentially identical.

Bonus material (cut from the post): There may be a small opportunity for a bug here with hitscan weapons, pain functions with walkmove on the first frame and very unfortunate positioning, but I don't think stock monsters can encounter it. Still, a cookie if you can figure out where it is and how to avoid it... 
 
two players enter a server.
the first player says 'I'm off'.
so the postthink says 'oh, in that case I'll make the other player into a monster'.

you probably want to use setorigin instead of setmodel. its more efficient for what you're trying to do. just leave the .modelindex set and clear out .model
in fte or dp, you don't need to do any relinking.

additional: will not work in fte, dp, or any quakeworld server. in these engines, player thinks are typically out of sync with monsters in order to facilitate prediction.
not when playing coop or deathmatch, anyway. 
Two Players Enter, One Player Leaves... 
two players enter a server.
the first player says 'I'm off'.
so the postthink says 'oh, in that case I'll make the other player into a monster'.


But the player entities are reserved in a block at the head of the entity list, so the slot is only freed up for another player.

My potential worry is that if you attack a monster with a shotgun, that might trigger a pain animation. Frame 1 of that pain animation plays instantly, and if the monster moves the physics occurs immediately. Since we're still within the call stack of the player functions, this gives the monster chance to walk inside an info_nonplayer_clip while it's non-solid, and land up stuck afterwards. It would be better if pain functions never called frame functions, but just set them as a think to happen immediately, but you can't make that change centrally so it's fiddly to do.

you probably want to use setorigin instead of setmodel. its more efficient for what you're trying to do. just leave the .modelindex set and clear out .model
in fte or dp, you don't need to do any relinking.


That's cool, noted. I don't know those corners of the engine well enough to know what you can get away with, and what's too much of a hack for some future engine to bear.

additional: will not work in fte, dp, or any quakeworld server. in these engines, player thinks are typically out of sync with monsters in order to facilitate prediction.
not when playing coop or deathmatch, anyway.


But do those engines let players execute thinks out of sync with each other? The idea is that the natural state of things is non-solid func_player_clip, and solid func_nonplayer_clip. Any time the engine runs physics on the players, we invert the natural order, then swap it back before physics runs on anything else. This is safe so long as all the players get acted on in a block, separate from all the other entities, even if the frequencies differ.

If the engine might ever run the physics on one player but not the others straight after, then the optimisation needs to go, and we must toggle the solidness after every individual player. Piles yet more inefficiency on in coop, but its the price of correctness. 
 
nextent skips entities that are free, correct...
But player entities are never free even if there's not a player in them. nextent thus finds player entities even if there are no players.
this means that flags&FL_CLIENT is unreliable, if not for the map the player leaves on then it definitely will be for the map that comes after.
pre/postthink won't happen for the first/last player slot if there is no player in it.

player entities are run out of order in quakeworld engines. the server runs player physics only when a network packet has been received from the client in question. this ensures that the entity state the server replies with is actually correct with regard to the state the server acknowledges.
this is done out of sequence because with 4 players it would otherwise require up to 288 physics frames per sec (assuming an infinitely fast server, less if the server's cpu is a bottleneck as multiple clients+packets may be serviced between waking periods).
removing the nextent optimisation would indeed also solve this case.

note also that touch events will fire between pre+post think (as well as during walkmove+movetogoal), and may get into an inconsistent state that way. whether this is actually a problem depends on the rest of the mod. 
Noted, Cheers 
Did not know that about empty player slots, but that's certainly a no-go then. I've amended the post to remove the optimisation, it's actually a much easier read now!

Re: touch being another issue, agreed, but like you say it's something that's only an issue based on the mod. Essentially it's movetogoal and walkmove that are the troublemakers - bits of code which set velocity etc. on an entity don't matter as the physics they set in motion isn't evaluated immediately.

A particularly brutal way of dealing with that threat would be a wrapper which simply causes walkmove/movetogoal calls to automatically fail if made during player physics! Both functions can already fail is the monster is blocked, so there's no guarantee of success for any call. It's mighty tempting, even if it's not all that pretty... 
Re: Player Slots 
I have found that nextent (world) will be player slot #1 (colormap 1) and nextent from there is player slot #2, all the way down to your max players setting. This is when doing it outside of Worldspawn () ... for it seems during worldspawn, its also setting up what they use to term as "Quaked" entities or the maps entities....and I dont believe the player slots are set up yet, or they may be inaccessible - but I could be wrong. Its been a while since I experimented with that...I was trying to create a cvar that flags the server as dedicated or local and I believe the 1st player could not be found in worldspawn using nextent. 
Tempstring Error 
If we strcat a corpse's netname to be that of its owners netname such as:

corpse.netname = strcat (corpse.owner.netname, " s dead body");

Notice the "\n" is left off the end...

Now if we eprint that corpse, I believe a tempstring error will pop up in the console because netname requires a newline, and there is none. Also the netname field does not appear in the eprintout, nor will it appear using prvm_edict blah netname at the server prompt? 
 
nextent skips over free entities. possible player entities are never free, even if the 'player slot' is. thus nextent will ALWAYS find player entities, but will find other ents only if they're not free.

the lack of a \n is irrelevant for everything other than displaying a newline when the string is actually printed.
entity dumps should display newlines in marked-up form - ie as a literal \n.

strcat returns a temp-string. temp strings are so named because they are temporary.
they are forgotten at some engine-defined time, either when the builtin is next called, when the builtin is called 16 times hence, when the engine returns to the caller, or when there are no more references to the string. there is at least one engine that implements each ony of these possible behaviours that I've listed.

tldr:
except for fte, all quake engines require you to use strzone for pretty much any temp-string which is assigned to a global or field (to avoid memory leaks you'll also need to use strunzone once you're done with it - but only if it isn't null, just to make things more awkward).
there are possible exceptions, but these tend to bite you later when you try saving the game. 
 
Is there some more elegant way of handling click-and-drag inputs in an event-driven context than "set an isDragging boolean to true on mousedown" and making a big branchy state machine out of it? 
Use The State Pattern 
It's the same principle, but without the switch/case cascades. 
Re: Tempstrings 
@ Spike - thanks. If we have used strcat in that way on a netname field for an ent, and we strzone it, do we need to unzone if remove () is called on that ent? 
@Teknoskillz 
technically yes. you'll leak otherwise, at least for the rest of the map.
whether that's an issue is a different matter. probably you won't leak that many strings so it won't be a problem. if you're allocating new ones every single frame, its more likely to be a problem. 
Floats/Booleans 
So for my Gatling Gun I decided to change the sounds, and now the firing loop sound is designed to be 0.8 seconds long, that means it should play once every 2 times the shooting animation loops comes in.

What I had in mind was to use a float/boolean value, define it as such:

float() gatlingsound =
{
TRUE;
};

But quakec doesn't seem to like it, neither with those:

if (gatlingsound = TRUE)
sound (self, CHAN_WEAPON, "weapons/mingn2.wav", 1, ATTN_NORM);
---
if (gatlingsound = TRUE)
gatlingsound = FALSE;
else
gatlingsound = TRUE;

So what's the correct way here? 
 
No clue about quakec but

1) gatlingsound = TRUE surely would be an assignmen, not a comparison?

2) float as Boolean?! 
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.