PDA

View Full Version : Idea: Implementing a "touched" message sent to player when player touches a surface



ZeqMacaw
08-12-2004, 01:10 PM
JK provides two "touched" messages: one sent to a thing's cog when another thing touches it, and one sent to a surface's cog when a thing touches it. If we wanted to detect when a player touches any wall surface, we could use the second "touched" message, but would have to link every surface to a cog. This seems like too much work. What would be nice is to have a "touched" message sent to the player's cog when the player touches any surface. The message would also have which surface the player touched.

Having searched through the edit and cog forums, it looks like this "touched" message has not been implemented by anyone. (If someone has attempted or successfully implemented this message or something similar, would you post the cog(s)?) For now, I present the latest version of my "touched" message kit.

Templates needed:

+toucher_exp none orient=(0.000000/0.000000/0.000000) type=explosion thingflags=0x1 damageclass=0x4 light=0.200000 timer=0.500000 typeflags=0x33 blasttime=0.300000 maxlight=0.400000
toucher_wpn none size=0.173778 movesize=0.17378 orient=(0/0/0) type=weapon collide=3 move=physics thingflags=0x20000400 cog=thing_touch.cog explode=+toucher_exp model3d=wp_touch.3do mass=0 physflags=0x200 typeflags=0x5

The cog used by the toucher_wpn template (the core of the implementation):

# thing_touch.cog
#
# Purpose:
# - Allows a player's cog to receive a "touched" message when the
# player touches a surface.
#
# Notes:
# - Touch detection works as follows:
# - Use a weapon template that uses an explosion template, a cog
# (this one), a 3do (which corresponds to shape of player's 3do), and the
# proper settings.
# - Attach a thing (which uses the weapon template) to the player.
# - Receive the "removed" message in the thing's cog. The message is sent
# when the thing touches a surface.
# - Surface index detection uses dot product to find distance between
# player surface and each architecture surface in a sector. It does not test
# surfaces upon which player is attached or surfaces that are not rendered.
# - The "toucher" in this cog means the thing using the weapon template.
# - Some stats for calculating player's surface position:
# - z offset that visually looks right ingame: 0.13
# - insert offset of ky.3do: -0.000050 0.000000 0.120114
# - movesize of walkplayer: 0.065000
# - distance from walkplayer center to bottom of feet:
# 0.120114 - 0.065000 = 0.055114
# - movesize of toucher_wpn:
# did not work right: 0.065000 + (0.13 - 0.120114) = 0.074886
# currently using radius of ky.3do: 0.173779
# - radius of ky.3do: 0.173779
#
# Problems:
# - Adjustments are used to more accurately detect a touch because
# toucher_wpn's collide=3 or its 3do is not working as expected.
# - There is no known way to find if a surface is an adjoin surface. Want
# to use GetSurfaceAdjoin() to avoid testing adjoin surfaces, but JK
# crashes if used on non-adjoin surfaces. Currently, GetFaceGeoMode() is
# used because adjoin surfaces will usually use geoMode = 0 (do not render).
# - Surface index detection is wrong when the part of the player that is
# touching surface is not in same sector as player's position.
# - Sometimes the toucher becomes stuck even though player keeps moving.
# This seems to occur at sector edges, probably while touching a surface.
# - It would be nice if we only had to include this cog and the two templates
# into a level, without changing them. Right now, we still have to change
# the first param of SendMessageEx() to the correct cog number
# (index in the jkl file + 1). We also need to include a 3do that
# corresponds to the shape of the player.
# - If, because of another mod, the player does not auto-attach, then the
# touch is not detected below player's knees (using ky.3do).
#
# Testing:
# - Use a separate thing attached to player for each major section of body, so
# "removed" message will receive different senderRefs. This idea might also
# help solve problem when toucher is across sector edges when touching.
#
# Written by ZeqMacaw 12-Aug-2004
#
# Special thanks to Descent_pilot for posting his cog for detecting a surface
# index. His method also used the dot product, but it was used differently.
#
#------------------------------------------------------------------------------

flags=0x240

symbols
message startup
message removed
message timer

int player local
thing senderThing local
vector position local
int attachFlags local
vector playerUpVector local
sector sectorIndex local
surface sectorSurfaceCount local
surface sectorSurfaceIndex local
surface surfaceIndex local
int geoMode local
vector surfaceNormal local
flex playerCosineToSurface local
vector surfaceCenter local
flex distance local
thing toucher local
template toucher_tpl=toucher_wpn local
end

#------------------------------------------------------------------------------

code

startup:
Sleep(1);
player = GetLocalPlayerThing();

jkStringClear();
jkStringConcatAsciiString("thing_touch startup");
jkStringConcatInt(player);
jkStringOutput(-1, -1);
return;

removed:
senderThing = GetSenderRef();
position = GetThingPos(player);
attachFlags = GetAttachFlags(player);
playerUpVector = GetThingUVec(player);
sectorIndex = GetThingSector(player);
sectorSurfaceCount = GetNumSectorSurfaces(sectorIndex);

jkStringClear();
jkStringConcatAsciiString("[");
jkStringConcatInt(sectorIndex);
jkStringConcatAsciiString("] ");

for (sectorSurfaceIndex = 0;
sectorSurfaceIndex < sectorSurfaceCount;
sectorSurfaceIndex = sectorSurfaceIndex + 1)
{
surfaceIndex = GetSectorSurfaceRef(sectorIndex, sectorSurfaceIndex);

// Do not test a surface that is unrendered.
geoMode = GetFaceGeoMode(surfaceIndex);
if (geoMode != 0)
{
surfaceNormal = GetSurfaceNormal(surfaceIndex);
playerCosineToSurface = VectorDot(surfaceNormal, playerUpVector);
//jkStringConcatAsciiString("playerCosineToSurface = ");
//jkStringConcatFlex(playerCosineToSurface);
// Do not test a surface upon which player is attached.
// Guessing 80 deg for surface angle upon which player can't
// attach: cos(~80 deg) = ~0.17
if ( ((attachFlags & 0x1) == 0x0)
|| (((attachFlags & 0x1) == 0x1)
&& (playerCosineToSurface > -0.17)
&& (playerCosineToSurface < 0.17)) )
{
// Calculate distance between toucher's position (same as
// player's) and sector's surface.
surfaceCenter = GetSurfaceCenter(surfaceIndex);
distance = VectorDot(surfaceNormal,
VectorSub(position, surfaceCenter));

if (distance < 0.075000)
{
//jkStringConcatFlex(distance);
//jkStringConcatAsciiString(" ");
SendMessageEx(1, touched, sectorSurfaceIndex, player, 3, 6);
}
}
}
}

jkStringOutput(-1, -1);

SetTimer(senderThing, 0.01);
return;

timer:
// Attach a new "toucher" to player.
position = VectorAdd(GetThingPos(player), '0.0 0.0 -0.01');
toucher = CreateThingAtPos(toucher_tpl, GetThingSector(player), position, '0.0 0.0 0.0');
SetThingLook(toucher, GetThingLVec(player));
AttachThingToThingEx(toucher, player, 0x4);
return;

end

The 3do used by toucher_wpn template is a copy of ky.3do with the insert offset changed to:

INSERT OFFSET 0.000000 0.000000 0.000000

The following code shows an example of usage:

Placed in a startup message (such as in kyle.cog):

// Place these in symbols section:
// int player local
// vector position local
// thing toucher local
// template toucher_tpl=toucher_wpn local
Sleep(1);
player = GetLocalPlayerThing();

// Attach "toucher" to player.
position = VectorAdd(GetThingPos(player), '0.0 0.0 -0.01');
toucher = CreateThingAtPos(toucher_tpl, GetThingSector(player), position, '0.0 0.0 0.0');
SetThingLook(toucher, GetThingLVec(player));
AttachThingToThingEx(toucher, player, 0x4);

// Using these for testing.
// ClearPhysicsFlags(player, 0x40); // Disable auto-attaching to floors.
SetPhysicsFlags(player, 0x2000); // Player can fly.

Placed in kyle.cog:

// Place this in symbol section:
// message touched
// surface sectorSurfaceIndex local
touched:
sectorSurfaceIndex = GetParam(1);
jkStringClear();
jkStringConcatAsciiString(" <");
jkStringConcatInt(sectorSurfaceIndex);
jkStringConcatAsciiString("> ");
jkStringOutput(-1, -1);
return;

Comments in the header of the thing_touch.cog explain the problems I have encountered. These problems might be the only ones remaining. If we find solutions to these problems, this new "touched" message should provide an easier way to implement other fun features in our levels.

Anyone think there is a better way? Anyone think this is crazy?

http://forums.massassi.net/html/smile.gif


[This message has been edited by ZeqMacaw (edited August 12, 2004).]

Descent_pilot
08-12-2004, 05:30 PM
Checksum wrote a cog for a matrix mod that went under that I was working on also, it was a run up walls code. This is related to the topic, just wait and hear me out. It works by firing a projectile at .3 jkus out from the player, a projectile that doesn't more like +punch. If the distance is less then .1, then do wall running. You can use this same thing by firing a template like +punch forward, right, left, up, down and back of player, maybe in the middle sections if you wanted, but those 6 basically covers it. Then you can check to see if the distance is less then the player's size (which means it must be touching a surface), but make sure you create it out further then the size. http://forums.massassi.net/html/wink.gif http://forums.massassi.net/html/tongue.gif Then you can check to see what surface using the thing on surface system. If you need me to write it up in code, just ask. Anyways, thats how I'd do it.

------------------
Major projects working on:
SATNRT
JK Pistol Mod
Aliens TC (http://www.massassi.net/levels/files/2967.shtml)

JediKirby
08-12-2004, 10:47 PM
*touches self*

It works!

------------------
jEDIkIRBY - Putting the Romance back into Necromancer.
Proud Leader of the Minnessassian Council

Live on, Adam.

G-Man
08-13-2004, 07:22 AM
<font face="Verdana, Arial" size="2">Originally posted by Descent_pilot:
Checksum wrote a cog for a matrix mod that went under that I was working on also, it was a run up walls code. This is related to the topic, just wait and hear me out. It works by firing a projectile at .3 jkus out from the player, a projectile that doesn't more like +punch. If the distance is less then .1, then do wall running. You can use this same thing by firing a template like +punch forward, right, left, up, down and back of player, maybe in the middle sections if you wanted, but those 6 basically covers it. Then you can check to see if the distance is less then the player's size (which means it must be touching a surface), but make sure you create it out further then the size. http://forums.massassi.net/html/wink.gif http://forums.massassi.net/html/tongue.gif Then you can check to see what surface using the thing on surface system. If you need me to write it up in code, just ask. Anyways, thats how I'd do it.

</font>

what matrix mod?


------------------
Sprite (http://www.pcgamemods.com/1992)Mod (JO 2003) (http://jediknight.filefront.com/file.info?ID=16922)

zagibu
08-13-2004, 12:28 PM
Sounds like complexication...

------------------
"Häb Pfrässe, süsch chlepfts!" - The coolest language in the world (besides Cherokee)

JediKirby
08-13-2004, 01:00 PM
<font face="Verdana, Arial" size="2">Originally posted by G-Man:
what matrix mod?


</font>

Nothing, you were seeing/reading things. There is no Matrix Mod. &gt;.&gt; &lt;.&lt;

JediKirby

------------------
jEDIkIRBY - Putting the Romance back into Necromancer.
Proud Leader of the Minnessassian Council

Live on, Adam.

ZeqMacaw
08-25-2004, 07:34 PM
Yes! I have figured it out and have even tested it in SP and MP. (I learned a lot about MP and "capture" cogs in making it work.)

I will be starting a new thread about "surface index detection" in the next few days that will give the details. I can't do it right now because I must cleanup the code and comments so others can understand it. http://forums.massassi.net/html/smile.gif

For this thread, I am curious:
How many of you understand how useful this "message" would be?

http://forums.massassi.net/html/smile.gif

lucky_jackpot
08-26-2004, 02:58 AM
I'm really interested to see this code http://forums.massassi.net/html/smile.gif - I remember our brief chat in #meu and you mentioning your work on this idea but to see it in its full state... http://forums.massassi.net/html/smile.gif

*...waits patiently...* http://forums.massassi.net/html/biggrin.gif

-Jackpot

------------------
"lucky_jackpot is the smily god..." - gothicX
"jackpot is an evil evil man... so evil, in fact, that he's awesome." - Seb

"Life is mostly froth and bubble, but two things stand in stone,
Kindness in another's trouble, courage in your own"
("Ye Wearie Wayfarer" - by Adam Lindsay Gordon)