Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
gggmork

check if actor is in void?

Recommended Posts

Only thing I could think of is checkactorfloortexture() or getactorfloorz(), figuring they might return -1 or something if an actor is in the void. But it turns out sectors "bleed" for these functions, like if you put a mancubus in the void, both functions will return data from one of the sectors that bleeds over into the void.

I guess you could tediously put dummy objects all around the void perimeter of the map, then test for collision with those dummy objects.. but that doesn't automate or re-use for new maps well.

Like say I have a new monster where I don't really use any decorate, just acs. I control its movement 1 tic at a time manually in acs. I'd want it to move 1 pixel or whatever every tic, but I don't want it to move into the void. I can prevent it from moving on top of another monster or something with collision detection I'm pretty sure if I remember, but no way to prevent it from moving into the void afaik.

Share this post


Link to post

This has come up before and no, there's no facility in the DOOM engine that can reliably detect and differentiate what we think of as "void" from ordinary intended level space.

Doing this would require addition of polygon in-out testing on proper closed versions of subsectors (ie. similar to GL BSP leaves). It would be an expensive operation to perform, though the implementation is textbook.

Share this post


Link to post

If you've ever noclipped into the void and suddenly started to take damage from a nukage sector far away, you now understand why.

Likewise for the camera height changing randomly. You are always in a sector. The binary space partition operates on the principle that you are always either here or there, there's no "neither" answer. You are in a subsector even if you aren't in a sector.

Share this post


Link to post

Maybe I can first "force" warp the actor to a spot, note its position, then try to thrust it. If it's still in the same spot, then its "stuck" in the void (doubt that'd work because lost souls and stuff can still move around in the void when they get there on accident.. but at least it might check for things stuck between a wall and the void, as monsters seem to get stuck in walls leading to the void then are free to move when they pass the wall).
Maybe take a snapshot of the actors camera view and have a sophisticated visual algorithm check for homs, if it sees homs its in the void, lol.

Share this post


Link to post

Try probing the space by spawning dummy actors with small radius, checking if they spawn successfully.

Share this post


Link to post
tempun said:

Try probing the space by spawning dummy actors with small radius, checking if they spawn successfully.

Non-solution. If the thing is in the void but entirely past any linedefs, this will pass with a green light. To do it this way you'd need an operation similar to the one Pain Elementals use since BOOM to test for blocking lines that cross the path between themselves and the Lost Soul's candidate position.

Share this post


Link to post

This is pretty easy. Assuming you have access to the level data:

- for a given point (x, y), find the closest linedef to it.
- if that linedef is not facing the point, and if it has no second sidedef, then (x, y) is in the void.

Facing the point:
(x y): the point to test
(x1 y1): coordinates of linedef vertex 1
(x2 y2): those of linedef vertex 2

Check if (x - x1)*(y2 - y1) < (y - y1) * (x2 - x1)
If true, then it's not facing the first side, it's facing the second side, and might be in the void.
If they're equal, then the point is resting on the line.


How to calculate distance to linedef: I think you can just calculate the distance to one of its vertices. Or the minimum between the distance to vertex 1, to vertex 2, or to the projection (x0, y0) of (x, y) on the linedef line.

Share this post


Link to post

If I remember, acs probably can't access much architecture data like lines/points. That's why I had to use omgifol to do architecture stuff I think.

I think, as an experiment, I should be able to make a torch or something bounce around a room of any shape like a pong ball (using something like thing thrust to test collision with both walls and things). Then it'd be easy to duplicate and have 100 pong balls. If I had line angle data I could make it bounce an appropriately reflected direction relative to the line, but probably can't do that.

If I want a acs controlled monster to suddenly spawn a ring of 8 actors around itself that each do their own unique acs controlled behavior, I could start from the main actor and "drag" to each warp spot, testing collision for each pixel the whole length of the drag.

I think acs has potential to make much more interesting monsters than decorate ones, which tend to be a bunch of clones of the same behavior.

Share this post


Link to post

What about defining an array in ACS, with the same values as the vertex coordinates and linedef-vertex-sidedef references? I hope ACC won't explode upon seeing that rather big array, but I guess you can put it in a separate, included file.

Share this post


Link to post

Why not just not have actors in the void in the first place? Use real walls, and spawn and move the actors within the defined level space. I guess I'm missing something.

Share this post


Link to post

Possibly encase the level in a big sector tagged 30000 that extends to the max size (-32767, 32768 I believe) and just check to see if they are in sector 30000.

Share this post


Link to post
Quasar said:

Non-solution. If the thing is in the void but entirely past any linedefs, this will pass with a green light. To do it this way you'd need an operation similar to the one Pain Elementals use since BOOM to test for blocking lines that cross the path between themselves and the Lost Soul's candidate position.

Then spawn them close enough to the object and have them be large enough.
Although Watermelon's solution may be better.

Share this post


Link to post
Watermelon said:

Possibly encase the level in a big sector tagged 30000 that extends to the max size (-32767, 32768 I believe) and just check to see if they are in sector 30000.

I'd make the sector small. If you're in the void, beyond the sector, you'll still be in that sector. But you still can't auotmate or re-use this method for new maps.

Share this post


Link to post

I don't know if I even fully understand my problem to know if checking if an actor is in the void is ultimately what I need (although that could be useful.. like if a wizard spawns something 128 pixels away, it should only be spawned if its actually in the map). Ultimately I want to control things tic by tic, with complete control instead of relying on built in decorate default behavior. For many things I'd probably want some sort of walking/moving behavior, preferably not retarded like falling off cliffs (decorate probably has a flag for that though) and not walking through other things or walls. And being able to react with everything else in real time, like if I make a pong ball reflecting off walls, I probably want doomguy to be able to walk up to the ball and have the ball reflect off him as well. I might just need to use the simple spawn function but I have to experiment more (I already tested: check a things x, thrust its x, check its x again to see if it moved, ie. was stuck.. that works but you need a delay(1) before the 2nd check or the x will be the same, so that'd be a bunch of slowdown every time you merely want to use that function to collision check. Spawn will probably work better, haven't tried much yet.

Another unrelated idea I have that would almost definitely work is make a giant 3d cacodemon.. out of cacodemons (or similar, basically giant 3d stuff using things as compositional units). You'd just have to have them spaced as wide as the diagonal of their bounding box probably so they could freely rotate all together in unison as the giant caco rotates/moves/etc without getting stuck on eachother.

Share this post


Link to post
Quasar said:

Doing this would require addition of polygon in-out testing on proper closed versions of subsectors (ie. similar to GL BSP leaves). It would be an expensive operation to perform, though the implementation is textbook.

Actually this is not all that expensive and can be folded into the regular DOOM mobj movement. Doomsday does exactly that to determine whether the view player is in the void (naturally it depends on a well-formed BSP of convex regions). Open the console, enter makecam 0 and you should notice that when the camera is outside the map there are no HOM artefacts.

Share this post


Link to post

If you have GL nodes, then DaniJ is correct, it is easy and inexpensive: find the current subsector (as normal) then check if the point lies inside every side of the GL polygon.

Without GL nodes, you need printz's method, find closest linedef (on a horizontal line is easiest) and test if you are on it's front side or back side.

But it must be said: things are never meant to be in the void, either that is a mapper's error or an engine's error (or an idclipping player).

Share this post


Link to post

Re: printz's method

Note that an actual implementation would need to account for various special cases such as "loose" linedefs in the void (not attached to a sector with a positive area), or worse, in Hexen where many of the IWAD maps have linedefs facing the "wrong" way in the void.

In fact, I probably wouldn't even attempt it without GL nodes...

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×