Jump to content
The Dark Mod Forums

Peek through (almost) every door


snatcher

Recommended Posts

I've done this for A Good Neighbor and Written in Stone. Sometimes its janky, but most the time it's pretty fun. A couple other authors have done it for their FMs too

Link to comment
Share on other sites

The idea that I have in mind is quite simple: the player selects a "Peek Keyhole" inventory item, places himself/herself in front of a door and presses the "use" key to peek through. No leaning forward, no accurate positioning. For as long as a door is highlighted, and the player is at a reasonable distance from the door, players can peek through it, just like using lock-picks.

I have yet to decide whether the peek will have an on/off toggle or the peek will be continuously enabled for as long as the player keeps pressing the "use" key. Both options work fine in my prototype but I have yet to examine the pros and cons in detail. Opinions are welcome.

Back to basis, I can think of three mandatory main rules:

  1. The door must have a handle: otherwise you can peek through other items with doors acting as lids, such as chests.
  2. The door mustn't be locked: the reason is that if a door is locked perhaps it isn't the time to know what's behind. Besides, for the peek to work it would seem we must "travel" to other side and we could accidentally trigger a goal before its time. If a door is unlocked nothing is preventing you from passing through therefore you can peek through it pretty safely.
  3. The peek POV must be static: meaning you get to see what's right ahead of the keyhole, in a forward position relative to the position of the keyhole or door. Players cannot use the mouse. Peeking through doors is quiet an advantage already and I think players shouldn't see too much of what's on the other side. Depending on the setup of the door and the area ahead sometimes you will get to see more, sometimes less.

Now, how do we about it?

We can use the built-in "Peek View" (fully or to an extent) or we can create our own implementation. I would like to try all options we can think of and see what works best. I have so far been tinkering with the built-in solution. It works, but there still are some big challenges ahead.

I didn't want to use handles as a reference to avoid any potential clipping and thanks to @Dragofer we can now tell reliably and in in real time the exact center of a door, regardless of its position, orientation or rotation. The center of the door will be the reference point for our peek.

  • Like 1

TDM Modpack 4.0

Link to comment
Share on other sites

Here comes (what I think is) the most difficult trick to pull of. I am not very good at trigonometry and the solution to the riddle requires a community effort.

As explained before, I want the peek to always follow a forward direction relative to the current position of the player and the door. A perpendicular, if you like, to one of the surfaces of the door aiming into the opposite direction the player is positioned at. I strongly believe this is the best possible outcome to keep the mechanic at bay thus preventing players to "peek side-ways", spoiling the whole area ahead.

peek-door.jpg

Red circle: the eyes of the player
Green circle: the center of the door

The player can be looking into many different directions but what we know for sure is that the player is directly looking at some point in the door, otherwise the door wouldn't be highlighted.

What direction should the peek aim at?

The player can be on one side of the door or the other (well, the player can be at an exact point where he/she is in both sides a at the same time but let's obviate this conundrum for a moment).

What if we trace a ray from the player eyes to the center of door  - both points known - that way we know the peek should be aiming to some point in that direction? Does that make sense or is it pointless and we should use the player view angles as the potential orientation?

Shouldn't this trace give us a normal of the door surface we can work with to calculate a perpendicular?

What do you, fine and educated people, think?

  • Like 1

TDM Modpack 4.0

Link to comment
Share on other sites

The trace might hit the side of the door or other things. You can identify the desired peek axis by adding getMins() and getMaxs() to get the total size vector of the door, then check whether the x, y or z component is smallest (absolute size). You can access the components of a vector variable like this (it gets considered as a float):

vector newVector = '100 20 60';

if( newVector_x > 100 ) ....

Make a new vector with only that component and rotate it by the current door angles. Convert this vector into angles and compare it with the player's view direction angles: if the difference is more than 90° the peek needs to go in the opposite direction.

  • Like 1
Link to comment
Share on other sites

Thank you very much. I will require multiple re-readings of your post though 😁

1 hour ago, Dragofer said:

The trace might hit the side of the door [...]

A last resort worth mentioning is to allow peeking only when a door is in closed position. Not only we eliminate from the equation weird player angles but it would also get rid of any potential clipping when a door, in example, is fully open but tightly close to a wall.

Now that think of it the peek feature wouldn't suffer much from having this rule: peeking through a keyhole of an open door can come in handy in the game yes, but seems like a little far fetched or forced? Open a door a little and peek through? Hide behind an open door and peek through instead of leaning? Hmm...

TDM Modpack 4.0

Link to comment
Share on other sites

3 hours ago, Dragofer said:

[...] You can identify the desired peek axis by adding getMins() and getMaxs() to get the total size vector of the door, then check whether the x, y or z component is smallest (absolute size) [...]

Make a new vector with only that component and rotate it by the current door angles. Convert this vector into angles and compare it with the player's view direction angles: if the difference is more than 90° the peek needs to go in the opposite direction.

Following your instructions literally, without me knowing why nor how, I reached a point where I just can't "compare it with the player's view direction angles":

	vector smallest = door.getMins() + door.getMaxs();
	if (smallest_x < smallest_y && smallest_x < smallest_z)
	{
		smallest_y = 0;
		smallest_z = 0;
	}
	else if (smallest_y < smallest_z)
	{
		smallest_x = 0;
		smallest_z = 0;
	}
	else
	{
		smallest_x = 0;
		smallest_y = 0;
	}

	vector newVector = sys.VecRotate(smallest, door.getAngles());
	newVector = sys.VecToAngles(newVector);

	if ((newVector - $player1.getViewAngles()) > 90)
      
CATASTROPHIC FAILURE --- CATASTROPHIC FAILURE --- CATASTROPHIC FAILURE

(fell free to humiliate)

TDM Modpack 4.0

Link to comment
Share on other sites

3 hours ago, snatcher said:

A last resort worth mentioning is to allow peeking only when a door is in closed position. Not only we eliminate from the equation weird player angles but it would also get rid of any potential clipping when a door, in example, is fully open but tightly close to a wall.

I don't think this is going to let you use traces: the door surface may be uneven, so that the detected surface normal is different from the actual door surface normal. Another possible flaw is hitting the frame or handle. Using the direction of the shortest side of the door as the peek direction should be more reliable, but it won't work if the door was created diagonally. I think that's rare, though.

Regarding what you've written so far, it looks good. I'd suggest adding comments to better indicate what's going on and changing some variable names:

- "smallest" should be "dimensions"

- "newVector" should be "peekVector". It can be created directly below "vector dimensions", then have either its x, y or z value changed to the corresponding value of "dimensions".

 

For comparing orientations, one approach that should work is to convert the difference into a normalized vector and get its magnitude from 0 to 1, where 0 means no difference (same direction), 1 should mean maximum difference (opposite direction, 180° turn) and 0.5 should mean half difference (90° turn). You will actually need to keep peekVector as a vector and convert the player view angles into a forward vector with angToForward, input the difference into vecNormalize and use vecLength to get the magnitude of the normalized vector.

When working with such calculations it's wise to insert debug lines like below so that you know what your script is doing and what numbers it's working with:

sys.println( "peekVector is now: " + peekVector );

Link to comment
Share on other sites

17 hours ago, snatcher said:

Back to basis, I can think of three mandatory main rules:

  1.  
  2. The door mustn't be locked: the reason is that if a door is locked perhaps it isn't the time to know what's behind. Besides, for the peek to work it would seem we must "travel" to other side and we could accidentally trigger a goal before its time. If a door is unlocked nothing is preventing you from passing through therefore you can peek through it pretty safely.
  3.  

I can't say I agree with the premise that the door must be locked to see inside. That isn't very real-world such that if a door has a keyhole, it shouldn't matter its' lock/unlock state to be able to peek. Furthermore, I can foresee game applications where there is an advantage to peeking in a room to find a character player, yet the door stays locked and the mission requires other means to get into that room, aka thru secret or a vent hatch or something. This seems like an unnecessary restriction, and I might say same for chests. If the author doesn't want the door (or chest) to allow peeking, then leave the peek script out of that function or have an alternative identical asset library of doors/chests without the peek ability.

 

Link to comment
Share on other sites

22 hours ago, snatcher said:

The door must have a handle: otherwise you can peek through other items with doors acting as lids, such as chests.

I don't think it matters becouse it will be too dark in the chest to see anything. If it's possible to look inside it could actually be interesting.

 

 

 

Link to comment
Share on other sites

@Shadow

The game already has a built-in peek feature mappers can make use of whenever they deem it appropriate (locked doors / unlocked doors / holes in a wall / other purposes...). This built-in feature remains untouched.

As part of this initiative we will be creating an external mod that will allow players to peek (almost) every door in (almost) every mission. Players will be free to use it or not.

@datiswous

We will see what results testing produces.

TDM Modpack 4.0

Link to comment
Share on other sites

@Dragofer, I am afraid I lost you here:

13 hours ago, Dragofer said:

- "newVector" should be "peekVector". It can be created directly below "vector dimensions", then have either its x, y or z value changed to the corresponding value of "dimensions".

Are you suggesting to rewrite the previous steps?

	vector dimensions = door.getMins() + door.getMaxs();
	vector peekVector = door.getAngles();
	if (dimensions_x < dimensions_y && dimensions_x < dimensions_z)
	{
		peekVector_x = dimensions_x;
	}
	else if (dimensions_y < dimensions_z)
	{
		peekVector_y = dimensions_y;
	}
	else
	{
		peekVector_z = dimensions_z;
	}

TDM Modpack 4.0

Link to comment
Share on other sites

1 hour ago, snatcher said:

Are you suggesting to rewrite the previous steps?

Yeah, like this it becomes clearer what the variables represent. Note that peekVector should be created empty, so just “vector peekVector;”.

To better visualise what “dimensions”, smallest component and “peekVector” actually represent, here’s an illustration of a door.

image.png.16178f5ad70c7b65b8526b33390c6d91.png

Regarding comparing orientations, it occurred to me that once you normalize a vector its length will always become exactly 1, so you can’t use the length for checking whether the player view difference is too large. What should actually be done is normalize both the peekVector and the player’s forward view vector (use angToForward on player view angles), then subtract the vectors from each other and get the length of the result. If the vectors were identical (player looks in the same direction as the peekVector) the length is 0, while if the vectors were opposite (180° difference) the length is 2, and if perpendicular (90° difference) the length is 1.

vector playerViewVector = sys.angToForward($player1.getViewAngles());

peekVector = sys.vecNormalize(peekVector);
playerViewVector = sys.vecNormalize(playerViewVector);
vector delta = playerViewVector – peekVector;
float magnitude = sys.vecLength(delta);

sys.println(“normalized peekVector: “ + peekVector );
sys.println(“normalized playerViewVector: “ + playerViewVector );
sys.println(“normalized delta: “ + delta );
sys.println(”magnitude of delta: “ + magnitude );

if( magnitude > 1)
{
	peekVector = -peekVector;
	sys.println(“inverting peekVector”);
}
Link to comment
Share on other sites

Thanks, Dragofer.

I can feel we are getting closer but something is amiss.

void playertools_compass::inventoryUse(player userEntity, entity frobbedEntity, float buttonState)
{
	entity door = frobbedEntity;

	vector offset = 0.5 * (door.getMins() + door.getMaxs());
	vector peekOrigin = door.getWorldOrigin() + sys.VecRotate(offset, door.getAngles());

// ------------------------------------------------------

	vector dimensions = door.getMins() + door.getMaxs();

	vector peekVector;
	if (dimensions_x < dimensions_y && dimensions_x < dimensions_z)
	{
		peekVector_x = dimensions_x;
	}
	else if (dimensions_y < dimensions_z)
	{
		peekVector_y = dimensions_y;
	}
	else
	{
		peekVector_z = dimensions_z;
	}
	peekVector = sys.vecNormalize(peekVector);

	vector playerViewVector = sys.angToForward($player1.getViewAngles());
	playerViewVector = sys.vecNormalize(playerViewVector);
	vector delta = playerViewVector - peekVector;

	float magnitude = sys.vecLength(delta);
	if (magnitude > 1)
	{
		peekVector = -peekVector;
		sys.println("inverting peekVector");
	}

	sys.println("normalized peekVector: " + peekVector);
	sys.println("normalized playerViewVector: " + playerViewVector);
	sys.println("normalized delta: " + delta);
	sys.println("magnitude of delta: " + magnitude);

// ------------------------------------------------------

	peekOrigin += sys.angToForward(peekVector) * 10;

	entity spawnFlame = sys.spawn("light_candleflame");
	spawnFlame.setOrigin(peekOrigin);
}

TDM Modpack 4.0

Link to comment
Share on other sites

Hi wesp5,

22 minutes ago, wesp5 said:

A very interesting idea and I will see where this goes and if it fits with my patch. But I agree with Shadow that this should be possible regardless of whether a door is locked or not [...]

If we succeed you can adjust it to fit your needs / vision.

21 minutes ago, wesp5 said:

[...] provided it has a keyhole...

Well, some doors don't come with a graphical keyhole but can still be locked and lockpicked...

TDM Modpack 4.0

Link to comment
Share on other sites

41 minutes ago, snatcher said:

Thanks, Dragofer.

I can feel we are getting closer but something is amiss.

Aren't we missing somewhere in peekVector the current angle of the door? Vector dimensions is always the same therefore the starting values of peekVector are always the same (for a same door).

TDM Modpack 4.0

Link to comment
Share on other sites

19 minutes ago, snatcher said:

Aren't we missing somewhere in peekVector the current angle of the door? Vector dimensions is always the same therefore the starting values of peekVector are always the same (for a same door).

Yeah, it looks like that line was deleted. It should be rotated before it gets normalized.

In any case, the script isnt done yet. So far you know the center of the door and the direction you need to peek into. At this point it'd be wise to check the console output of the debug lines (sys.println...) to make sure the script is doing what you expect it to before adding more to the script. If you look into the direction you'd expect the peek to go, is:

1) peekVector and playerViewVector almost the same?

2) delta and magnitude of delta almost 0?

3) peekVector doesn't get flipped?

Repeat with various other player view directions.

Regarding the current end of the script, you can't use angToForward on peekVector because it's already a vector, not angles. You'll have to multiply the peekVector by half the door thickness (smallest component of "dimension") and add that to the door center so that the peekOrigin is on the surface of the door, not inside. Then you need to convert the peekVector to peekAngles and make $player1 look in that direction during the peek.

Note that in DoomScript vectors and angles are both treated as "vector" variables.

Link to comment
Share on other sites

50 minutes ago, Dragofer said:

Regarding the current end of the script, you can't use angToForward on peekVector because it's already a vector, not angles.

Ouch, of course, of course! 🤭

51 minutes ago, Dragofer said:

You'll have to multiply the peekVector by half the door thickness (smallest component of "dimension") and add that to the door center so that the peekOrigin is on the surface of the door, not inside.

Ok but let's, for the moment, exaggerate the effect a little for testing purposes.

Here is the result (1 flame out of 6 made it home, the others landed somewhere around the surface):

peek-doors.jpg

 

void playertools_compass::inventoryUse(player userEntity, entity frobbedEntity, float buttonState)
{
	entity door = frobbedEntity;

	vector offset = 0.5 * (door.getMins() + door.getMaxs());
	vector peekOrigin = door.getWorldOrigin() + sys.VecRotate(offset, door.getAngles());

// ------------------------------------------------------

	vector dimensions = door.getMins() + door.getMaxs();

	vector peekVector;
	if (dimensions_x < dimensions_y && dimensions_x < dimensions_z)
	{
		peekVector_x = dimensions_x;
	}
	else if (dimensions_y < dimensions_z)
	{
		peekVector_y = dimensions_y;
	}
	else
	{
		peekVector_z = dimensions_z;
	}

	peekVector = sys.VecRotate(peekVector, door.getAngles());
	peekVector = sys.vecNormalize(peekVector);

	vector playerViewVector = sys.angToForward($player1.getViewAngles());
	playerViewVector = sys.vecNormalize(playerViewVector);
	vector delta = playerViewVector - peekVector;

	float magnitude = sys.vecLength(delta);
	if (magnitude > 1)
	{
		peekVector = -peekVector;
		sys.println("inverting peekVector");
	}

	sys.println("normalized peekVector: " + peekVector);
	sys.println("normalized playerViewVector: " + playerViewVector);
	sys.println("normalized delta: " + delta);
	sys.println("magnitude of delta: " + magnitude);

// ------------------------------------------------------

	peekOrigin += peekVector * 10;

	entity spawnFlame = sys.spawn("light_candleflame");
	spawnFlame.setOrigin(peekOrigin);
}
  • Like 1

TDM Modpack 4.0

Link to comment
Share on other sites

1 hour ago, snatcher said:
	sys.println("normalized peekVector: " + peekVector);
	sys.println("normalized playerViewVector: " + playerViewVector);
	sys.println("normalized delta: " + delta);
	sys.println("magnitude of delta: " + magnitude);

Yeah, I wrote these debug lines so that the script tells you what it's calculating. Please read the console output to check that the values are as expected:

2 hours ago, Dragofer said:

If you look into the direction you'd expect the peek to go, is:

1) peekVector and playerViewVector almost the same?

2) delta and magnitude of delta almost 0?

3) peekVector doesn't get flipped?

Repeat with various other player view directions.

Link to comment
Share on other sites

Here is a fail (the flame gets placed in the exact same pos no matter where I look the door from):

  • peekVector and playerViewVector almost the same? No: (1, -0, -0) vs (-0.01, -1, 0)
  • delta and magnitude of delta almost 0? No: (0.99, -1, 0) & (1.404918)
  • peekVector doesn't get flipped? It gets flipped

Same door in the same pos but from the other side (the flame gets placed in the exact same pos no matter where I look the door from):

  • peekVector and playerViewVector almost the same? No: (1, -0, -0) vs (0.28, 0.76, 0.59)
  • delta and magnitude of delta almost 0? No: (1.28, 0.76, 0.59) & (1.598738)
  • peekVector doesn't get flipped? It gets flipped

 

Edited by snatcher

TDM Modpack 4.0

Link to comment
Share on other sites

1 hour ago, snatcher said:

the flame gets placed in the exact same pos no matter where I look the door from

This is expected, the peek begins from the door center and goes outwards 90° from the door surface. The player view angles are only used to determine whether the peek goes forwards or backwards ("flipped").

1 hour ago, snatcher said:

peekVector and playerViewVector almost the same? No: (1, -0, -0) vs (-0.01, -1, 0)

So this suggests there's a problem with how either peekVector and/or playerViewVector get calculated. playerViewVector is much simpler and uses premade functions, so it's more likely the peekVector is at fault.

You'll need to place debug lines to check the variables that are involved in its calculation, starting with "dimensions". Every time a variable gets changed you need to print its new value.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recent Status Updates

    • Petike the Taffer

      I've finally managed to log in to The Dark Mod Wiki. I'm back in the saddle and before the holidays start in full, I'll be adding a few new FM articles and doing other updates. Written in Stone is already done.
      · 0 replies
    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
    • OrbWeaver

      I like the new frob highlight but it would nice if it was less "flickery" while moving over objects (especially barred metal doors).
      · 4 replies
    • nbohr1more

      Please vote in the 15th Anniversary Contest Theme Poll
       
      · 0 replies
×
×
  • Create New...