Massassi Forums Logo

This is the static archive of the Massassi Forums. The forums are closed indefinitely. Thanks for all the memories!

You can also download Super Old Archived Message Boards from when Massassi first started.

"View" counts are as of the day the forums were archived, and will no longer increase.

ForumsCog Forum → Tip: Provide a "touched" message to player that includes surface index detection.
Tip: Provide a "touched" message to player that includes surface index detection.
2004-08-26, 5:03 PM #1
Background:

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 we would have to link every surface to a cog. This seems like too much work. Idealy, there would be a "touched" message sent to the player's cog when the player touches any surface. The message would also identify which surface the player touched.

The ideal workaround:

1. One cog that somehow detects when the player touches a surface and also which surface it is.
2. The cog would then send the "touched" message to the player cog with the surface index as a parameter.
3. It would work as a mod so that any level could use it.
4. It would work with other mods.
5. It would work in both SP and MP.
6. It would not be slow.
7. The only requirement in using the workaround would be to add the cog and just use the "touched" message as if it were built-in to JK.

A tested working implementation:

1. There are 2 cogs and 2 templates. (Not bad, might be able to reduce this.)
2. SendMessageEx() is used, and surface index detection is accurate. (There are two small problems here, but will likely not be a problem with most levels.)
3. There are no level dependencies.
4. One thing is used, so that's one less thing for other mods. The thing is attached to the player, so there might be strange interactions if other things were attached to the player. No triggers are used.
5. It works in both SP and MP.
6. I am not sure how to test slowness, but I did not notice any slowdown on two machines I typically play JK on. (The machines are P3-550MHz-128MB.)
7. Need to add the two templates and the two cogs to a jkl. Besides that, using the "touched" message is just like using the other messages.

Here are the templates:
Code:
toucher_wpn         none   orient=(0/0/0) type=weapon collide=1 move=physics thingflags=0x8080c10 timer=10 mass=0
physflags=0x200 maxrotvel=90 damageclass=0x2 typeflags=0xd cog=class_toucher.cog model3d=ky.3do size=0.065 movesize=0.065

toucher_water_wpn   none   orient=(0/0/0) type=weapon collide=1 move=physics thingflags=0x10080c10 timer=10 mass=0
physflags=0x200 maxrotvel=90 damageclass=0x2 typeflags=0xd cog=class_toucher.cog model3d=ky.3do size=0.065 movesize=0.065


Here are the cogs:
Code:
# class_toucher.cog
#
# Purpose:
# - Allows a player's cog to receive a "touch" message when the 
#   player touches a surface.
# Notes:
# - Requires object_toucher.cog.
# - Requires toucher_wpn and toucher_water_wpn templates.
#
# Written by ZeqMacaw 26-Aug-2004
#
# Thanks to Cubix (a local friend) for helping me work out a couple of 
#   problems with the toucher.
# Special thanks to Descent_pilot for posting his cog for detecting a surface 
#   index. His post not only gave me a starting point for the surface index 
#   detection, it convinced me that my "touched" message idea could be 
#   implemented.
#------------------------------------------------------------------------------
flags=0x240
symbols
	message	startup		
	message	created
	message	removed
end
#------------------------------------------------------------------------------
code
startup:
	return;
created:
	return;
removed:
	return;
end

# object_toucher.cog
#
# Capture cog for class_toucher things.
#
# Written by ZeqMacaw 26-Aug-2004
# 
# "Finding point in polygon" algorithm found here:
# http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
#------------------------------------------------------------------------------
flags=0x240
symbols
	message	startup		
	message	removed
	int		player			local
	vector	position			local
	flex		distanceMin			local
	int		geoMode			local
	vector	surfaceNormal		local
	vector	surfaceCenter		local
	flex		distance			local
	surface	touchedSurfaceIndex	local
	surface	touchedSectorIndex	local
	int		i				local
	surface	adjoinIndex			local
	surface	adjoinIndex1		local
	sector	sectorIndex			local
	sector	sectorIndex1		local
	surface	sectorSurfaceCount	local
	surface	sectorSurfaceCount1	local
	surface	sectorSurfaceIndex	local
	surface	sectorSurfaceIndex1	local
	surface	surfaceIndex		local
	surface	surfaceIndex1		local
	template    toucher_tpl=toucher_wpn				local
	template    toucher_water_tpl=toucher_water_wpn		local
	thing		toucher			local
	vector	ZeroVector			local
	int		isOnSurface			local
	vector	point				local
	flex		dot				local
	int		coordinateValue		local
	int		coordinateValueMax	local
	int		coordinateIgnored		local
	int		surfaceVertexIndex	local
	int		surfaceVertexCount	local
	int		pointIsOnTheLine		local
	vector	vec				local
	vector	p				local
	vector	p0				local
	vector	p1				local
	vector	p2				local
end
#------------------------------------------------------------------------------
code
startup:
	Sleep(1);
	player = GetLocalPlayerThing();
	ZeroVector = VectorSet(0, 0, 0);
	call CreateToucher;
	return;
removed:
	position = GetThingPos(player);
	sectorIndex = GetThingSector(player);
	sectorSurfaceCount = GetNumSectorSurfaces(sectorIndex);

	touchedSurfaceIndex = -1;
	distanceMin = 0.1;
	for (sectorSurfaceIndex = 0; 
	     sectorSurfaceIndex < sectorSurfaceCount; 
	     sectorSurfaceIndex = sectorSurfaceIndex + 1)
	{
		surfaceIndex = GetSectorSurfaceRef(sectorIndex, sectorSurfaceIndex);
		surfaceNormal = GetSurfaceNormal(surfaceIndex);

		// Calculate distance between toucher's position (same as 
		// player's) and sector's surface.
		surfaceCenter = GetSurfaceCenter(surfaceIndex);
		distance = VectorDot(surfaceNormal, 
			VectorSub(position, surfaceCenter));
		geoMode = GetFaceGeoMode(surfaceIndex);
		//NOTE: For now, a surface is considered an adjoin if it is unrendered.
		if ((geoMode == 0) && (distance < 0.065))
		{
			// Player is across an adjoin, so check adjoining sector.
			i = 1;
			call CheckSectorSurfaces;
		}
		else if (distance < distanceMin)
		{
			point = VectorAdd(VectorScale(
				VectorSub(ZeroVector, surfaceNormal), distance), position);
			surfaceIndexi = surfaceIndex;
			call IsPointInPolygon;

			if (isOnSurface != 0)
			{
				distanceMin = distance;
				touchedSurfaceIndex = sectorSurfaceIndex;  // surfaceIndex
				touchedSectorIndex = sectorIndex;
			}
		}
	}

	if (touchedSurfaceIndex > -1)
	{
		SendMessageEx(GetThingClassCog(player), touched, 
			touchedSurfaceIndex, player, touchedSectorIndex, GetSelfCog());
	}

	// The delay before creating toucher again prevents player getting stuck 
	// in surface.
	Sleep(0.1);
	call CreateToucher;
	return;
CreateToucher:
	if ((GetThingFlags(player) & 0x2000000) == 0x2000000)
	{
		toucher = FireProjectile(player, toucher_water_tpl, -1, -1, '0.0 0.0 0.0', 
			'0.0 0.0 0.0', 0, 0, 0, 0); 
	}
	else
	{
		toucher = FireProjectile(player, toucher_tpl, -1, -1, '0.0 0.0 0.0', 
			'0.0 0.0 0.0', 0, 0, 0, 0); 
	}
	SetLifeLeft(toucher, 0);
	ClearThingFlags(toucher, 0x80000);
	CaptureThing(toucher);
	SetThingModel(toucher, GetThingModel(player));
	SetThingLook(toucher, GetThingLVec(player));
	AttachThingToThingEx(toucher, player, 0x4);
	return;
CheckSectorSurfaces:
	adjoinIndex = GetSurfaceAdjoin(surfaceIndex[i - 1]);
	sectorIndex = GetSurfaceSector(adjoinIndex);
	sectorSurfaceCount = GetNumSectorSurfaces(sectorIndex);

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

		// Don't check the adjoin surface.
		if (surfaceIndex != adjoinIndex)
		{
			surfaceNormal = GetSurfaceNormal(surfaceIndex);

			// Calculate distance between toucher's position (same as 
			// player's) and sector's surface.
			surfaceCenter = GetSurfaceCenter(surfaceIndex);
			distance = VectorDot(surfaceNormal, 
				VectorSub(position, surfaceCenter));
			geoMode = GetFaceGeoMode(surfaceIndex);
			//NOTE: For now, a surface is considered an adjoin if it is unrendered.
			if ((geoMode == 0) && (distance < 0.065))
			{
				//NOTE: Because of "threading" limit, don't bother going any 
				//  further.
				// Player is across an adjoin, so check adjoining sector.
//				call CheckSectorSurfaces;
			}
			else if (distance < distanceMin)
			{
				point = VectorAdd(VectorScale(
					VectorSub(ZeroVector, surfaceNormal), distance), position);
				surfaceIndexi = surfaceIndex;
				call IsPointInPolygon;

				if (isOnSurface != 0)
				{
					distanceMin = distance;
					touchedSurfaceIndex = sectorSurfaceIndex;  // surfaceIndex
					touchedSectorIndex = sectorIndex;
				}
			}
		}
	}

	i = i - 1;
	return;
IsPointInPolygon:
	// Set which coordinate to ignore (for projecting to 2D) by selecting the 
	// one with largest absolute value in the surfaceNormal.  
	// 0 = x; 1 = y; 2 = z
	coordinateValue = VectorX(surfaceNormal);
	if (coordinateValue < 0)
	{
		coordinateValue = coordinateValue * -1;
	}
	coordinateValueMax = coordinateValue;
	coordinateIgnored = 0;
	coordinateValue = VectorY(surfaceNormal);
	if (coordinateValue < 0)
	{
		coordinateValue = coordinateValue * -1;
	}
	if (coordinateValue > coordinateValueMax)
	{
		coordinateValueMax = coordinateValue;
		coordinateIgnored = 1;
	}
	coordinateValue = VectorZ(surfaceNormal);
	if (coordinateValue < 0)
	{
		coordinateValue = coordinateValue * -1;
	}
	if (coordinateValue > coordinateValueMax)
	{
		coordinateIgnored = 2;
	}

	// Change the vectors to 2-coordinate projection.
	surfaceVertexCount = GetNumSurfaceVertices(surfaceIndexi);
	HeapNew(0, surfaceVertexCount + 1);
	if (coordinateIgnored != 2)
	{
		if (coordinateIgnored == 0)
		{
			for (surfaceVertexIndex = 0; 
			     surfaceVertexIndex < surfaceVertexCount; 
			     surfaceVertexIndex = surfaceVertexIndex + 1)
			{
				vec = GetSurfaceVertexPos(surfaceIndexi, surfaceVertexIndex);
				HeapSet(surfaceVertexIndex, VectorSet(VectorY(vec), VectorZ(vec), 0));
			}
			p = VectorSet(VectorY(point), VectorZ(point), 0);
		}
		else
		{
			for (surfaceVertexIndex = 0; 
			     surfaceVertexIndex < surfaceVertexCount; 
			     surfaceVertexIndex = surfaceVertexIndex + 1)
			{
				vec = GetSurfaceVertexPos(surfaceIndexi, surfaceVertexIndex);
				HeapSet(surfaceVertexIndex, VectorSet(VectorX(vec), VectorZ(vec), 0));
			}
			p = VectorSet(VectorX(point), VectorZ(point), 0);
		}
	}
	else
	{
		for (surfaceVertexIndex = 0; 
			 surfaceVertexIndex < surfaceVertexCount; 
			 surfaceVertexIndex = surfaceVertexIndex + 1)
		{
			HeapSet(surfaceVertexIndex, GetSurfaceVertexPos(surfaceIndexi, surfaceVertexIndex));
		}
		p = point;
	}
	HeapSet(surfaceVertexCount, HeapGet(0));

	isOnSurface = 0;
	for (surfaceVertexIndex = 0; 
	     surfaceVertexIndex < surfaceVertexCount; 
	     surfaceVertexIndex = surfaceVertexIndex + 1)
	{
		if (VectorY(HeapGet(surfaceVertexIndex)) <= VectorY(p))
		{
			if (VectorY(HeapGet(surfaceVertexIndex + 1)) > VectorY(p))
			{
				p0 = HeapGet(surfaceVertexIndex);
				p1 = HeapGet(surfaceVertexIndex + 1);
				p2 = p;
				call IsPointOnTheLine;
				if (pointIsOnTheLine > 0)
				{
					isOnSurface = isOnSurface + 1;
				}
			}
		}
		else
		{
			if (VectorY(HeapGet(surfaceVertexIndex + 1)) <= VectorY(p))
			{
				p0 = HeapGet(surfaceVertexIndex);
				p1 = HeapGet(surfaceVertexIndex + 1);
				p2 = p;
				call IsPointOnTheLine;
				if (pointIsOnTheLine < 0)
				{
					isOnSurface = isOnSurface - 1;
				}
			}
		}
	}
	HeapFree();
	return;
IsPointOnTheLine:
	pointIsOnTheLine 
		= ( (VectorX(p1) - VectorX(p0)) * (VectorY(p2) - VectorY(p0))
		-   (VectorX(p2) - VectorX(p0)) * (VectorY(p1) - VectorY(p0)) );
	return;
end


What's going on:

The object_toucher creates itself using one of the templates. If player is not in a water sector, use the toucher_wpn template, else use the other. It attaches itself to the player. The templates are setup for exploding the toucher on touching other things and touching surfaces. It is set to be the same size as the player, so it will explode whenever a player touches somthing. When a touch (explosion) occurs, the removed message handler in object_toucher calculates the surface index detection, sends the "touched" message if a surface was touched, and finally creates another toucher before being destroyed.

Because a 0x4 attachment breaks on entering and exiting water, the object_toucher uses the toucher_wpn to explode when entering water and toucher_water_wpn when exiting water. This keeps an attachment because only the crossing causes the break.

The templates are set to be destroyed after 10 seconds, but the object_toucher cog disables this. Because the object_toucher cog is local to the player, there is only one toucher per machine. This means that only the local player's machine needs to do the detection, and there won't be any unusual interactions between touchers because each machine only knows about one.

The "touched" message sends these parameters:
Param 0: the surface that was touched
Param 1: the player who touched the surface
Param 2: the sector that contains the surface
Param 3: the cog that sent the message


Closing:

At least two small problems exist. One problem is that the surface detection only "goes through" one adjoin. Thus, if the player's position (a point near his belly button) is in one sector, and he touches a surface two sectors away, then the detection will not send the "touched" message. This is a small (forgive the pun) problem because the sectors would have to be really small slivers for this to occur. The other problem is that I haven't found a better way to detect adjoins than to detect if a surface is unrendered. This (I hope) is a small problem because it seems unlikely that a rendered adjoin would need surface index detection using the "touched" message.

I already see potential for making this implementation better, but I posted anyway so others can use it and improve on it in the meantime. One idea is to change the size and movesize of the toucher to match the player's current size and movesize (just like what the cog does with matching the player's model). Also, the surface index detection could use some more cleanup work. I had tried using recursion for searching through adjoins, but remembered the "thread limt" of 5 mentioned in the DataMaster, leaving the code a bit messy.

Suggestions, comments, and (of course) bug reports welcome. Use of the code is encouraged. (Email me if you do use it. I'd love to hear about it.)

[http://forums.massassi.net/html/smile.gif]
2004-08-26, 5:11 PM #2
For those of you who just want to use the implementation:
- Copy the two templates and the two cogs and paste them in an appropriate jkl file. (In addition to placing the two cogs in the cogscripts section, place the object_toucher.cog in the cogs section so it can handle its "startup" message. In JED, you only need to add the object_toucher.cog in the Placed Cogs window.)
- Use the new "touched" message in your player cog like this:
Code:
touchedSurface    = GetParam(0);
playerThatTouched = GetParam(1);
surfaceSector     = GetParam(2);
cogSender         = GetParam(3);


[http://forums.massassi.net/html/smile.gif]
2004-08-27, 12:55 AM #3
Wow, seems to be accurately reporting surfaces for me. I smushed it into Canyon Oasis and modded kyle.cog to print the received info on screen. Have done no testing to make sure it doesn't generate any network traffic yet though, but it doesn't look like it should. Quick question though: what's the point of class_toucher.cog? It has absolutely no purpose that I can see. It's more or less an empty cog... also, you give the thing's a timer of 10 and then remove the timer in the cog... but since creation should be unsync'd, why even bother giving them a timer in the template?

QM
2004-08-27, 1:45 AM #4
Quote:
<font face="Verdana, Arial" size="2">
I smushed it into Canyon Oasis and modded kyle.cog to print the received info on screen.
</font>

Cool! Thanks for testing it. That's exactly the test that I did right before posting the tip. [http://forums.massassi.net/html/smile.gif]

Quote:
<font face="Verdana, Arial" size="2">
what's the point of class_toucher.cog? It has absolutely no purpose that I can see. It's more or less an empty cog
</font>

Quib Mask, I am glad you asked. It is used by the two templates as their class cog, and is separated from the object_toucher.cog for a very important reason. (The cog probably could be reduced more, but I'll have to test it.) I'll explain the reason in my answer to your next question...

Quote:
<font face="Verdana, Arial" size="2">
you give the thing's a timer of 10 and then remove the timer in the cog... but since creation should be unsync'd, why even bother giving them a timer in the template?
</font>

"Since creation should be unsynced" is the key phrase here. In my tests, I had the 0x10 thing flag cleared so I could see the objects in-game. Plus, I verified the thing count using dispstats. Both ways showed that *all* computers were creating a toucher for each player when I did not separate the class and the object (capture) cogs. Not only that, the other player's toucher would sometimes "stick" causing the attachment to fail and a new toucher would be created without destoying the "stuck" one. Thus, extra touchers and false detection would result. Solving this problem was the main reason I did not post this tip sooner. [http://forums.massassi.net/html/smile.gif]

So, the technique with the thing's timer is used to destroy all of the touchers except the one on the local computer.

I hope that makes sense, because the problem was quite frustrating for at least a week. I was actually about to give up, until I thought of using a capture cog.

Of course, I might have misunderstood the problem's cause, and would not mind being corrected. [http://forums.massassi.net/html/smile.gif]

BTW, have you noticed any strange detection (or none at all) around the pillars in Canyon Oasis? I have, but it seems minor at the moment.

[http://forums.massassi.net/html/smile.gif]
2004-08-27, 5:14 AM #5
For those of lacking in cog knowledge, what does this mean for us, as level designers and modders?

JediKirby

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

Live on, Adam.

[This message has been edited by jEDIkIRBY (edited August 28, 2004).]
ᵗʰᵉᵇˢᵍ๒ᵍᵐᵃᶥᶫ∙ᶜᵒᵐ
ᴸᶥᵛᵉ ᴼᵑ ᴬᵈᵃᵐ
2004-08-27, 5:59 AM #6
Modified quote from jEDIkIRBY:
"What does this mean for level designers and modders?"

I am hoping that this mod will reduce our burden in making certain kinds of mods. For instance, let's say you want to allow a player to climb only certain surfaces. Ugh! You would have to link many of the surfaces in the level to cogs. (And think of the agony if you changed your mind on which surfaces. "Hmm...which surface is the number 42?" "Ack! there are way too many surfaces that need changing, let's just keep it the way it is.") With this mod, just build the level, and let the cogger write a cog to detect the type of surface (that was touched) based on the mat used and so on.

Did my example help?

I am hoping to see some new mods come from this (even if I have to make them myself). [http://forums.massassi.net/html/smile.gif]

Now, I just need an "exited" message so my space station level will be easier to finish...

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


[This message has been edited by ZeqMacaw (edited August 27, 2004).]
2004-08-28, 6:08 AM #7
So, perhaps this could be used with the Nightfire mod, so that the grappling hood only stuck to specific surfaces?

Or perhaps, some sort of spiderman mod where your web-slinging is calculated based on surfaces? Thus your web would only shoot out to the top parts of buildings, or something like that?

JediKirby

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

Live on, Adam.
ᵗʰᵉᵇˢᵍ๒ᵍᵐᵃᶥᶫ∙ᶜᵒᵐ
ᴸᶥᵛᵉ ᴼᵑ ᴬᵈᵃᵐ
2004-08-28, 7:15 AM #8
Yes, to all of the above; although I haven't tested the method on other things yet.

[http://forums.massassi.net/html/smile.gif]
2004-08-29, 9:26 AM #9
Quote from Quib Mask: "creation should be unsync'd"

I just realized that I didn't explain my theory of how the creation is being sync'd. Actually, it is very simple; FireProjectile is probably doing the synching even though the cog uses the 0x200 flag.

Another note: I had to use FireProjectile instead of CreateThing (which probably does not sync) because it gives a parent to the toucher. Thus, the toucher could have the flag that disables exploding on the parent (which it would do continuously without the parent link because it touches the player).

[http://forums.massassi.net/html/smile.gif]
2004-08-30, 7:47 AM #10
I want a spiderman mod on my desk by friday, Parker. [/jameson]

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

Live on, Adam.
ᵗʰᵉᵇˢᵍ๒ᵍᵐᵃᶥᶫ∙ᶜᵒᵐ
ᴸᶥᵛᵉ ᴼᵑ ᴬᵈᵃᵐ
2004-08-31, 5:18 PM #11
Please note that the following two lines need to be changed so that a surface index is used (and not the sector surface index, which is useful for debugging).

Code:
touchedSurfaceIndex = sectorSurfaceIndex;  // surfaceIndex

touchedSurfaceIndex = sectorSurfaceIndex;  // surfaceIndex


Change them to:
Code:
touchedSurfaceIndex = surfaceIndex;  // surfaceIndex

touchedSurfaceIndex = surfaceIndex;  // surfaceIndex


I *am* working on cleaning up the code further.

(To lucky_jackpot: What do you think of this "touched" message code, now that you have seen it?)

[http://forums.massassi.net/html/smile.gif]
2004-08-31, 11:56 PM #12
I've been following this topic every day for a while now, feverishly doing my best to follow it, and I think this is well on its way to being a major productivity boost for editors [http://forums.massassi.net/html/biggrin.gif] - every now and again, something truly innovative rears its head for JK editors and I rate this as one of the most recent by far... [http://forums.massassi.net/html/biggrin.gif]

I must confess that I haven't had the time in the last few weeks to play, let-alone edit JK; work has been just too punishing recently. Mercifully, I finish today (roll on 17:30pm [http://forums.massassi.net/html/biggrin.gif]) so I look forward to having a thorough play-test of this code over the next few days... [http://forums.massassi.net/html/smile.gif]. I'll report back then, but so far, the more I look at your "revamped touched message" the more I stand in awe of some excellent cogging - keep up the fantastic progress [http://forums.massassi.net/html/biggrin.gif]

-Jackpot

PS: And yes - as I'm finishing today, I have one last thorough report to write up and then I can (finally [http://forums.massassi.net/html/wink.gif])get back on schedule with all the projects for other people that I'm due (and you all know who you are - all I can offer are my apologies about the slow progress [http://forums.massassi.net/html/redface.gif]...)

------------------
"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)
"lucky_jackpot is the smily god..." -gothicX
"Life is mostly froth and bubble, but two things stand in stone,
Kindness in another's trouble, courage in your own"
- "Ye Wearie Wayfarer"
|| AI Builder: compatible with both JK & MotS || My website ||
2004-09-01, 7:29 AM #13
*calls off his mob of midgets* fine, you're safe for now LJ... for now.

By the way, zeq, you're needed in my other cog thread, thanks.

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

Live on, Adam.

[This message has been edited by jEDIkIRBY (edited September 01, 2004).]
ᵗʰᵉᵇˢᵍ๒ᵍᵐᵃᶥᶫ∙ᶜᵒᵐ
ᴸᶥᵛᵉ ᴼᵑ ᴬᵈᵃᵐ
2004-09-15, 12:37 PM #14
I forgot to comment on this when I was first reading it. That is quite the piece of cogging right there! I can not tell you how many times I'd wished I could snag a surface without attaching a cog to it!

I tried making sense of it, but quickly got lost. It'd take me awhile to fully understand its workings.

You mentioned that it could have problems in two ways. One being that it checks if a surface is rendered or not to see if its an adjoin. I don't see how thats going to cause to big of a problem.

And the other is that it can only look through 1 adjoin deciding on the surface touched. Now, I don't fully understand the code like I said...I'm curious if the MotS verb FindSectorAtPos() would help with that at all? There's also the IsSphereInSector() verb using in chainlightning which there's no documentation on but sounds useful. You might not even have MotS so its just a thought.
-El Scorcho

"Its dodgeball time!" -Stormy Waters

↑ Up to the top!