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?
#1837 posted by Spike on 2015/11/24 06:30:50
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.
#1838 posted by Lunaran on 2015/11/24 11:00:39
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
#1841 posted by Spike on 2015/11/25 12:15:43
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
#1842 posted by aDaya on 2015/12/03 18:47:36
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?
#1843 posted by Spirit on 2015/12/03 18:53:11
No clue about quakec but
1) gatlingsound = TRUE surely would be an assignmen, not a comparison?
2) float as Boolean?!
#1844 posted by aDaya on 2015/12/03 19:04:40
Went looking for an equivalent in the quakeC manual, it said "float" was it.
Or maybe I misred it and it's something else?
#1845 posted by Lunaran on 2015/12/03 19:19:16
there's no booleans or integers in quakec, float is what you get.
also, spirit is right, "if (gatlingsound = TRUE)" sets gatlingsound to true and then returns true 100% of the time.
why are you doing this?
float() gatlingsound =
{
TRUE;
};
are you trying to define a variable named gatlingsound? because this is a function declaration.
just trigger the sound on every 8th frame of the animation, you don't need to faff with this at all.
#1846 posted by Preach on 2015/12/03 19:32:29
2) float as Boolean?!
In QC everything is a float - like javascript!
Spirit is correct that your test should use a double equals sign like:
if (gatlingsound == TRUE)
If your compiler doesn't warn you about this then you should get a newer version of FTEQCC.
Also, I think your definition of gatlingsound is a bit confused. What you have defined is not a variable to store a value. It's a function. It isn't even quite a function which returns "TRUE", because you've missed off the return command.
What you want to do is:
.float gatlingsound;
This adds a new variable to the player called gatlingsound. You have to access it as "self.gatlingsound = FALSE" and "if(self.gatlingsound == TRUE)".
That should get you compiled. You may find it doesn't delay the sound very much, but you'll be at the right point to look at the example of invisible_sound for how to do longer delays.
Lunaran
#1847 posted by aDaya on 2015/12/03 20:39:08
I can't play the sound as you said, because the firing animation is played 1 frame every 0.05 second, meaning it would only play half the firing sound every time the animation loops.
And I just can't get the thing to work, even with "==" (it says "==" is not a name). Tried to replace TRUE and FALSE with 1 and 0 while changing "float" with "void", but the same errors always came in: "local functions may not be initialized" (is also said when I still use TRUE and FALSE while using == on everything but the declaration line) for the declaration line, and the rest is "unknown value "galtingsound"".
Preach
#1848 posted by aDaya on 2015/12/03 20:45:02
Your thing got compiled. Thanks!
@Lunaran
float() gatlingsound =
{
return (TRUE); // add return
};
if (gatlingsound == TRUE) // single = is an assignment , double is a comparison
sound (self, CHAN_WEAPON, "weapons/mingn2.wav", 1, ATTN_NORM);
else
sound (self, CHAN_WEAPON, "weapons/normal_gun_sound", 1, ATTN_NORM);
Also realize CHAN_WEAPON is not the same as CHAN_AUTO , so if there is another sound playing on CHAN_WEAPON, it will be overrided as well as another sound on the channel being able to override yours in code executing past the function you are putting it in.
Gatlingsound ()
Sorry, the () is required otherwise it might cause that compile error:
if (gatlingsound ())
// pretty sure this will proceed only if true, but I have seen cases where negative intergers cause a true in some engines , IE: -1, -2 etc.
Lmao
#1851 posted by Kinn on 2015/12/04 21:13:23
float() gatlingsound =
{
return (TRUE); // add return
};
Can we just agree this is dumb as hell and not do it like this?
Just use a constant.
Soundbuffer ()
Also, I have made soundbuffers in my mod but using just the basic sound command "play" stuffed to the console. I suppose it could be done with regular sound calls, best to define a special sound channel for it though, IE : CHAN_BUFFSOUND = blah
Where blah is the sound channel number. Darkplaces suppoert up to 128 sound channels total, not sure if other engines expand the sound channel range.
Basicly:
.string buf1,buf2,buf3,buf4;
.float sounbuffer
So you play the first sound, then call a new function that lists all the possible sound strings that the playing sound can be, and returns a float value equal to the total time it takes to play the sound in seconds, for each given sound. Then -
self.soundbuffer = time + SUB_SNDLEN (current sound);
In PlayerPRethink () , you add
if (self.soundbuffer < time && (self.buf1 != "" || self.buf2 != "" || self.buf3 != "" || self.buf4 != ""))
SUB_ChkSndBuffer ();
From there you just make the new function that checks all 4 buffers if a string is present. If so, clear that buffer with a null (""), and send that old string over to the function to play a buffered sound. that function also needs to scope through all the buffers in order in the even lost of sounds are stored.
Most Engines Have 7 Xhannels
#1853 posted by necros on 2015/12/04 22:33:40
1 to 7 are explicit and 0 is whatever is free.
Of course, you can just spawn new entities and have unlimited channels.
#1854 posted by Spike on 2015/12/05 00:27:06
actually, that's a common falacy.
channel 0 is not 'whatever is free', its a 'don't terminate anything'.
of course if you do play lots of sounds at once then things can get VERY LOUD, which is why stuff tends to use an explicit channel, especially if the later half of the sound is a little echoy such that it sounds stupid when you have multiple instances playing with 0.1 sec intervals.
there may still be a global limit on the total number of sounds that can be playing at once, but thanks to static sounds this is typically quite a high limit (read: thousands).
It's Okay Guys
#1855 posted by aDaya on 2015/12/05 00:57:21
Preach's way was compatible with what I wanted to do, and it goes as expected and flawlessly.
But still, thanks for your attention.
#1856 posted by necros on 2015/12/05 02:05:00
i have also noticed if you try to play the same sound twice in the same frame, the engine will ignore it (or play at half volume?).
the only way around that i've seen is to create two separate .wav files that are identical and play the "different" sounds at the same time.
#1857 posted by Spike on 2015/12/05 14:47:35
if you start two sounds at once on the same entity (on different channels) all you will have done is to double the volume.
with different ents, you will have spacialisation differences so there is still a purpose, but it will still be extra loud.
FTE does randomize the start time of the second sample slightly (this is something q2 also does). This tends to make it a little more echoy without making it quite so obnoxiously loud - more sounds means that it'll *probably* be louder, but this isn't guarenteed as the time difference will negate this effect by a not insignificant amount so volume 1.2 or so instead of 2.0.
This is the sort of thing you want if you have 20 identical monsters all seeing you in the same frame.
It can also potentially help in deathmatch too.
Z-aware Grenade Shooters?
#1858 posted by aDaya on 2015/12/15 18:47:09
I'm continuing on doing monster reskins, and I want to make an Enforcer that's similar to the Defender, but I want it to shoot grenades while being Z-Aware, unlike the Ogres, and maybe make it explode on contact (they'll have to be weakened if I want to do that).
I remembered Inside3D/InsideQC had a tutorial for that, but for some reason I can't find it.
Can anybody help me on that case?
#1859 posted by Lunaran on 2015/12/15 21:20:53
|