Two Stage
#370 posted by Preach on 2010/06/20 13:19:52
If that is a problem(it certainly would be if you need to detect monsters)can use force_retouch to help you out there. The simplest way would be to set force_retouch = 2 in the touch function as soon as you've touched the trigger. This would end up polling the heck out of all the triggers in your map while someone touched the middle one, but it would fix that problem.
I think the above is the only way to make the trigger responsive within a single frame (assuming you shrink the nextthink time lots). If you're willing to have your trigger less responsive (a minimum of two frames, but the values we pick here will be 0.2 seconds) then we can end up only using force_retouch once in 0.2 seconds.
We need the trigger_detector to have three states:
STATE_EMPTY: no player inside
STATE_READY: detected a player recently
STATE_POLLING: checking if there is still a player
If a player comes into an empty trigger we go from STATE_EMPTY to STATE_READY and wait for 0.1 seconds. After that time expires we go into STATE_POLLING for 0.1 seconds. If a player touches the trigger within that 0.1 seconds, we go back to STATE_READY, otherwise we go to STATE_EMPTY (and trigger the leaving event).
We don't actually need to explicitly track these states, they are just to understand what is going on. We have a think function called trigger_detect_startpolling along the lines of
self.nextthink = time + 0.1;
self.think = trigger_detect_fire;
force_retouch = 2;
When our .think is trigger_detect_startpolling, we are in STATE_READY. When our think is trigger_detect_fire we are in STATE_POLLING. When we don't have a nextthink in the future, we are in STATE_EMPTY.
Finally to hook all of this up, we need the touch function to set
self.nextthink = time + 0.1;
self.think = trigger_detect_startpolling;
which both moves us from STATE_EMPTY to STATE_READY when the player first touches, and back from STATE_POLLING to STATE_READY when the player retouches.
On another topic, force_retouch has an important effect on touch/think order which I hadn't considered before. When set, players will touch things they are in contact with before their think functions run (and then possibly touch things AGAIN after physics has run). So anyone who was intending to exploit the order that functions run had better be careful.
Also, I'm gonna go see if things really can run touches multiple times in a single frame. If that is the case, then it really will be important to make touch functions idempotent. This is a wonderful term from mathematics for a function which doesn't do anything else when you keep applying it to it's output. For example rint(x) is idempotent - once you get a whole number out, applying rint to that whole number just gives you the same whole number.
I'm using idempotent in a slightly weird sense here, the idea being that one of the parameters to our touch function is the value of "time", the frame that we are in. Most of the original touch functions have if(self.nextthink > time) type guards in place to achieve this, but it's something important to think about if you're writing a trigger which can be touched every frame - does it matter if you trigger it many times a frame?
#371 posted by necros on 2010/06/21 05:03:00
i don't know why it has to be so complicated, preach... it works fine the way i said. :P no need for force_retouch or anything.
Monsterous
#372 posted by Preach on 2010/06/21 19:46:02
It's needed in the case of non-player entities which don't link to the world unless they move. If you were trying to detect a monster, you would need the force_retouch. It is more than what mike asked for though, the simple suffices there...
Oh Right
#373 posted by necros on 2010/06/21 22:56:54
i missed that you were checking for monsters as well.
Necros & Preach
#374 posted by Mike Woodham on 2010/06/29 20:20:15
Thanks.
Findradius Vs Find Vs Nextent
#375 posted by necros on 2010/06/29 20:53:37
are there any differences in how these three work?
ie: is findradius really just doing
nextent(e)
if (distance of e < dist), add to .chain
or is it faster?
for example, if i did a findradius(org, 64) where i'm checking only a small radius, is it faster than if i findradius(org, 1024) or is it the same speed?
and if smaller radii are faster than larger ones, at what point does it become better to use nextent rather than a large findradius?
i guess that kind of thing would also depend on the total # of entities as well...
Finding
#376 posted by Preach on 2010/06/29 21:26:43
ie: is findradius really just doing
nextent(e)
if (distance of e < dist), add to .chain
or is it faster?
It turns out that it does something extra I'd never known about - it skips any entity that's SOLID_NOT(*). Other than that, the algorithm is as you describe, but because it's written in c skipping to the next entity is a single instruction to increment a pointer, etc. So it does run a lot faster than the QC equivalent, but it doesn't do any culling of the entity list based on the bsp tree or anything fancy.
for example, if i did a findradius(org, 64) where i'm checking only a small radius, is it faster than if i findradius(org, 1024) or is it the same speed?
They are the same speed if they contain the same number of entities. Otherwise the cost of adding more things to the chain is incurred, although that's fairly light compared to the rest of the loop.
(*) Also worth noting: the distance is measured to
origin + (mins + max) * 0.5;
not just the origin as you might guess.
#377 posted by necros on 2010/06/29 22:00:07
It turns out that it does something extra I'd never known about - it skips any entity that's SOLID_NOT
haha yeah, i figured that out the hard way. drove me insane for a while. -_-
Also worth noting: the distance is measured to
origin + (mins + max) * 0.5;
not just the origin as you might guess.
didn't know about this bit though. wouldn't have much of an impact unless you had some kind of weird offset bbox but good to know regardless. it does make getting precise findradius distances annoying though. if i did a findradius from one monster origin looking for other monsters, the find would have been completely accurate if it was going from origins and not bbox centers. oh well. :S
How Difficult
#378 posted by megaman on 2010/07/20 18:57:49
is it to find out what map a given savegame file is for?
Can someone post code / relevant savegame spec? :P
Not Difficult At All
#379 posted by negke on 2010/07/20 19:19:21
Information on the map and its entities is stored in the .sav file in plain text format.
You're Like A Savegame Wizard.
#380 posted by necros on 2010/07/20 21:16:01
interesting that savegames store lightstyles though. one would think that's easily gettable from the progs.
Yeah It's Plain-text Alright,
#381 posted by megaman on 2010/07/20 23:41:57
but the locations in the files seem to change.
I want to parse it with quakeinjector to enable loading savegames for each map, so I'd need to know how to parse the header.
Host_Loadgame_f() in http://svn.icculus.org/twilight/trunk/darkplaces/host_cmd.c?revision=10262&view=markup
seems to be the right function (darkplaces), but it's quite complicated and I'm not familiar with the quake src. For example I have no idea what COM_ParseToken_Simple(&t, false, false); does ;-) It would probably take me an hour or so to get what's going on there.
Wait
#382 posted by megaman on 2010/07/20 23:53:39
is it always on the same line?
#383 posted by metlslime on 2010/07/21 04:12:01
interesting that savegames store lightstyles though. one would think that's easily gettable from the progs.
The current string for each style needs to be saved because there's no post-loadgame callback for entities to set the lightstyle strings again.
Looks Like It's The 20th Line
#384 posted by mwh on 2010/07/21 06:00:27
save game version, description, 16 parameters, skill and then the bsp name.
Qc/engine Question
#385 posted by Spirit on 2010/07/27 13:26:52
if a coder specifies a file "tORch.Mdl" would the engine usually look for tORch.Mdl or torch.mdl or what?
Different Cases?
#386 posted by Preach on 2010/07/27 21:04:34
From what I can glean from a quick browse through the source:
Models in pak files must match capitalisation exactly or they will not be loaded.
Models in the filesystem depend on the operating system's implementation of fopen in the standard c library. I believe this means that unix type OSs will fail to find the file but DOS and windows will succeed, but I can't find any documentation which confirms this for 'fopen'. So where possible make sure the exact case is used.
#387 posted by necros on 2010/07/27 21:05:07
i have had problems with upper/lower case before.
i found it best to avoid uppercase altogether.
for example, ne_tower had a bunch of custom sounds.
when i was developing it, i had all the files loose in folders and setting keys like 'noise' 'necros/someSound.wav' worked fine. when i packed everything into a pak file, someSound could not be found, even though the filename hadn't changed.
Preach
#388 posted by necros on 2010/08/03 03:49:39
i know you've posted about this before, but i can't find it again :S
basically, there was a faster way to compare distances without using vlen.
was it something like vec1*vec2 > distance*distance ??
Necros:
#389 posted by metlslime on 2010/08/03 04:19:56
if (vec_x * vec_x + vec_y * vec_y + vec_z * vec_z > distance * distance) {
//temp is longer than distance
}
#390 posted by metlslime on 2010/08/03 04:20:23
er ...
//vec is longer than distance
Yup
#391 posted by Preach on 2010/08/03 04:39:28
It's almost like that. You can compare the length of a vector v to a distance d with:
v * v > d * d (notice that on both sides of the equation we have the same variable twice)
If you're testing the distance between two positions p1 and p2, you need to take the difference in positions first:
v = p2 - p1;
v * v > d * d;
It works exactly as metl says, but v * v is a single QC instruction which computes the dot product he has expanded out.
Very Cool
#392 posted by necros on 2010/08/03 06:27:27
thank you!
when you say it's one instruction, i guess doing it as vec * vec is faster then?
#393 posted by metlslime on 2010/08/03 08:18:25
It works exactly as metl says, but v * v is a single QC instruction which computes the dot product he has expanded out.
Ah, good to know.
Monster_boss Glitch In Progs 1.06?
#394 posted by negke on 2010/08/10 15:06:28
On skill 2, Chthon's aim prediction fails if the player moves towards him when he's about to throw a lavaball. The result is that he throws it backwards instead (or possibly towards worldspawn). It doesn't occur on 1.01.
Is this a known issue - why wasn't it fixed?
|