Game Development Community

Platforms Players can Ride Version 1.1

by Cinder Games · in Torque Game Engine · 01/27/2007 (4:34 pm) · 268 replies

Platforms Players can Ride Version 1.2!!!!!!
with Dynamic object Attachment
###################################
##This post has been edited and updated 2/13/07 ##
##################################

subvoicestudios.com/~ramensama/TorqueDynamicAttachment.jpg

Here's the new and improved files you'd need.
Version 1.2
subvoicestudios.com/~ramensama/torque1.5.2.zip

1.7.2008
What's new? There are several new features and improvements.

1) Removed or reduced jitter caused by multiple players on a platform
2) Support for new items on platforms. Now Items, Shapes, lights, particle emitters, and possibly others!
3) Object to object Attachment. Players can now attach Items, shapes, etc to them. Even the attached objects can attach more objects to themselves!
4) Reduced the number of code changes.... a little.


This must be extracted in the base torque directory where it's installed...
c:/torque

or whatever. it's designed to simply overwrite a stock install of torque.

Afterwards you must add pathshape.cc and pathshape.h to your project in visual studio or whatever.

img292.imageshack.us/img292/9507/addexistingxy9.gif

To attach an object, you must use this syntax:

ParentObject.attachChild(ChildObject);

So if you want to attach an item to the player, move the player towards the object, press F11 to get the object ID. Press ~ and type in $player.attachchild(ObjectID);

The item is now attached to the player.

$player.detachchild(ObjectID); is how to remove the object.






Ancient Versions of the code can be found here.
These are version 1.1, not the newest version and probably have bugs that the newer code does not.
Here's a link to the new updated code. It's for torque 1.4...
subvoicestudios.com/~ramensama/torque.zip

And for Torque 1.5
subvoicestudios.com/~ramensama/torque1.5.zip
#81
08/05/2007 (8:17 am)
@Joe Thanks for the reply!

Yesterday I was a winmerge virgin - today, Winmerge is my new best friend! Got the example code and mission working (the problems seemed relate to 1.5.2 changing to sgLightManager - it doesn't like the old stuff AT ALL).

Now to figure out how to script the objects correctly!
#82
08/05/2007 (1:52 pm)
Glad to hear it! Good luck with the scripting.
#83
08/05/2007 (5:15 pm)
Trying to help a friend with this...

Was anyone able to get this working in TGEA? It looks as though many of the functions in "renderMountedImage" are OpenGL commands, so are there DirectX equivalents to these commands?

We've got just about everything else ported over to TGEA using WinMerge, but this isn't a direct merge... this needs some translation from OpenGL -> DirectX..... As far as I can tell.

Thanks!
#84
08/05/2007 (5:33 pm)
@Ed

It does need those, your correct. I tried to merge it about 25 times and every time it failed. It compiles fine, but if you try to jump on the platform, it wont collide.
#85
08/06/2007 (4:10 pm)
I've come across things acting a little wacky... By declaring the pathShape as part of a path in the .mis file, it seems impossible to add/remove pathShape objects using script. The object is created as part of the world and if you remove the object, seem to also delete the path - or at least have no way to recreate the object later. I really don't understand some things about the language yet, so I may just be missing something.

The issue seems to be that in the example, the pathShape object gets defined as the first node of the path. So no matter what, the object is created when the game starts. If the pathShape is not declared as part of the path, the script doesn't seem to work quite right (even if you define a marker in it's place). I finally (hopefully) nailed the issue by rewriting the PathShape::followpath and PathShape::PushPath.

I rewrote the script simply push all of the defined markers and then append the first to the end. I set the loopNode to the nodeCount +1 and got rid of the popFront call. I also changed the logic to define the loopNode in the pushPath function - mainly because I couldn't figure out why to do the "is looping" logic in both functions ... and I was there anyhow.

These changes seem to make the routine work both for pathShape objects defined as part of the Path (like in the example) as well as dynamically created pathShape objects following a path defined of only markers (I have NO IDEA how to correctly make a path using the World Editor, so I'm not sure if they will work on paths made this way - but I suspect they will).

Finally, I added a data member called "loopMode" to the loopingShape datablock. This allowed me to add an additional looping method called "retrace". Retrace pushes all of the defined markers, then pushes the nodes in reverse (skipping the highest node). This leaves (nodeCount*2) - 1 nodes in the new loop. Retrace allows more complicated linear paths to be created and followed forward and back. The original "loop" mode simply plots a straight line from the last node to the first at the end.

NOTE: seqNum should probably be defined in the pathShape declaration if the pathShape is going to be used as the first marker node. I'm not sure if anything else uses this value, but it makes debugging easier.
#86
08/06/2007 (4:27 pm)
Here is the code described above. It's really my first torquesript program so I very well may have missed something. But it seems to work pretty well so far.

This is pretty much a stripped down version of the original routine with some logic moved to the next routine.
function PathShape::followPath(%this,%path) {
   echo("PathShape::followPath(" @ %this @ "," SPC %path @")");
   %this.path = %path;
   if (!(%this.speed = %path.speed))
	{
      %this.speed = 10;
	}
   	echo("PathShape::followPath() loopNode == ", %this.loopNode);   
   	%this.pushPath(%path);
        %this.popFront(); // This pop removes initial DUMMY node.
}
8/23/07 Update: replaced the popfront call to fix my "off by one" bug.

This is where I change the path logic slightly and add the "retrace" option.
function PathShape::pushPath(%this,%path) {
   echo("PathShape::pushPath(" @ %this @ "," SPC %path @")");
   for (%i = 0; %i < %path.getCount(); %i++) {
      %this.pushNode(%path.getObject(%i)); // Push all of the defined markers 
    }
 	if(%this.path.isLooping) {
		if(%this.loopMode $= "retrace"){
			// Loop these backwards and add the numbers in reverse (skip the top
			// node
			%this.loopNode = (%path.getCount()*2)-1;	// Twice the path - the double "reverse" node
			%this.loopNode -= 1;  // Added to zero-justify the number (8/23/07)
			for (%i = %path.getCount()-1; %i>0; %i--) {
				%this.pushNode(%path.getObject(%i-1));	// Put these on the que
			}				
		}
		else{
   			// If looping, push the starting node on to end to make this a loop			
			%this.loopNode = %path.getCount()+1;// The number of path targets + end node
			%this.loopNode -= 1;  // Added to zero-justify the number (8/23/07)
			%this.pushNode(%path.getObject(0));	// Send the path back to the start
		}
	}
	else {
		%this.loopNode = -1;	// Don't loop
	}   
}
8/23/07 Update: added two decrement lines to fix my "off by one" bug.

In order to retrace, simply add the following line to the pathshape datablock and then set the value to "retrace" when declaring the object.

loopMode = "";

So there ya go, my first torquescript code. Does it work for anyone else?
#87
08/06/2007 (4:52 pm)
Oh yeah ... and a helper function for creating one of these objects! This would have come in VERY handy when trying to figure this out (the original resource's description is misleading);

function mkPthShp(){	
	%pt = new PathShape(pthShapeName) // You don't have to name it, but it's useful sometimes
	{
		dataBlock = "LoopingShape";
		position = "-126.233 144.903 102.6";	// Std Shape Stuff
		rotation = "1 0 0 0";
		scale = "4 4 4";        
		receiveSunLight = "1";
		receiveLMLighting = "1";
		useAdaptiveSelfIllumination = "0";
		useCustomAmbientLighting = "0";
		customAmbientSelfIllumination = "0";
		customAmbientLighting = "0 0 0 1";
		useLightingOcclusion = "1";			// ^^
		speed = "10";			// Default speed
		loopNode = "4";			// Higest node in the path .. gets overwritten anyhow
		loopMode = "retrace";	// New retrace mode
		Path = "tgtGamePath1";  // This is just a defined path object
	};
	MissionCleanup.add(%pt);
	return(%pt);
}
#88
08/08/2007 (1:46 am)
I implemented the pathshape resource on Torque 1.5.2 and everything seems to be working right but I am having problems with implementing blockers or walls to prevent the player from running off the platform created.

The problem is that intermittently the player will be able to pass through the collision boxes of the 'walls' created to stop the player from falling off the object. This usually happens when the platform is going one way and the player runs the opposite way. The player seems to phase right through the wall. I have tested this with a platform with all 4 walls on each side.

My current 'guess' is that there is a 'time' in between ticks that the players location and the shape location are out of sync leaving a hole..allow the player to fail the collision check. Has anybody else run into something like this?
#89
08/09/2007 (10:07 am)
@Terence, I *think* your problem comes from a current non-feature of pathshapes - they don't detect collision. Player attachment happens when the *player* moves and detects the shape. When the *shape* moves, it doesn't check for collision. Therefore, if the shape moves into the player (as a moving wall might do), they will overlap, and you have your pass-through problem.

Adding collision-detection to an object is complicated. I've messed with it and gotten as far as generating "yo I hit something" messages, not as far as actually creating a useful response. Examine this old resource and search generally for collision if you want to dive in.

@Kent, thanks for posting this. I was also stymied at first by the path implementation. Haven't tried your code but it looks like an improvement.
#90
08/09/2007 (5:02 pm)
I did everything the first post said to to do.
It compiles fine.
But when I try to run it, I get the following message::
In the title bar of the error it says Fatal (c:\torque\sdk\engine\gui\core\guitypes.cc @363


GuiControlProfile: unable to find specified profile (GuiDefaultProfile) and GuiDefualtProfile does not exist!


This the code from lines 360-363 I did not touch it but i'm guessing this casues the error.
if(!profile)
profile = dynamic_cast(Sim::findObject("GuiDefaultProfile"));

AssertFatal(profile != NULL, avar("GuiControlProfile: unable to find specified profile (%s) and GuiDefaultProfile does not exist!", argv[0]));

Any help? Can someone help me?

And I am using torque 1.4.2
#91
08/13/2007 (12:38 pm)
Why can't i move a pathshape in the Torque Editor?
#92
08/13/2007 (1:15 pm)
@Joe: adding basic collision detection to PathShape is pretty easy, you just need to implement a castRay() function... see the original PathShape resource
#93
08/15/2007 (12:14 pm)
@Beffy, thanks for the link and for making this possible w/your original resource! Good to learn the history on this stuff.

Re. collision, I am confused. According to my very sketchy base of programming/tge knowledge:

-- castRay() is for 3rd-person-camera and projectile collision. (Camera collision can also be handled simply by adding an LOScol mesh to an object.)
-- for an object (like a pathShape) to push the player when it runs into him from the side - which is what I want it to do - it needs buildConvex() and/or buildPolyList() functions, and more.
-- in my case, just to get a moving pathShape to report collision when it runs into the player, I had to add all these functions to it: buildPolyList(); buildConvex(); updateWorkingCollisionSet(); and checkCollision(). All in all, a clusterhack of stuff that I don't really understand, pulled from player.cc & item.cc -- but not including castRay().

Am I wildly off here?
#94
08/15/2007 (5:55 pm)
@Beffy, Yeah I'm with Joe on this... Been studying the collision example and the original resource trying to figure out what's what and can't seem to figure out how castRay comes into the picture (or when it is called to determine a collision). I would assume the player calls it possible when a castRay is done to check if the weapon is to be pushed back? *sigh*

My original intentions are to add some form of guard rails on 3 sides of the platform and use a mountable object on the remaining side (for a door). Doing this would hopefully prevent players from falling to their doom when they get on a lift.
#95
08/23/2007 (12:03 pm)
Well, my first TorqueScript was less-than-perfect. It turns out there was a cascading "off-by-one" bug in my script (The nodes go from 0-6 not 1-7 ... duh). Anyhow, I updated the code snippets in the post above.
#96
08/23/2007 (12:14 pm)
I had to recreate my entire *&^%$ custom TGE C++ project (don't ask). While I was at it, I took the time to make "clean" TGE 1.5.2 files for some of my favorite older-version resources.

If anyone needs it, the .zip file for the pathshape.1.5.2 is Here. This should drop right into an UNMODIFIED TGE 1.5.2 installation.

NOTE: this is only an updated C++ portion of the resource. You will still need to get the entire resource from this site for the demo and the .cs files.
#97
08/31/2007 (2:15 pm)
Has anyone that has implimented this into TGEA willing to help me out? I have tryed implimenting this alot and it has always failed. Is there anything more that has to be done then merging the differences that are not TGE related?

Thanks.
#98
09/02/2007 (2:04 pm)
Alright, with TGEA 1.02 I get this error:

gameBase.cpp
..\engine\game\gameBase.cpp(435) : error C2065: 'con' : undeclared identifier
..\engine\game\gameBase.cpp(435) : error C2227: left of '->getGhostIndex' must point to class/struct/union/generic type
type is ''unknown-type''

Here is that section of code in my gameBase.cpp:

if(stream->writeFlag(mask & ParentObjectMask))   {      
        // Check to see if we need to write an object ID      
        if(stream->writeFlag( mGraph.parent ))      {         
        [b] S32 t = con->getGhostIndex( mGraph.parent ); [/b]        
            // Check to see if we can actually ghost this...         
            if(t == -1)         {            
                // Cant, try again later            
                retMask |= ParentObjectMask;            
                stream->writeFlag(false);

What is wrong?
#99
09/02/2007 (2:29 pm)
Sorry for the triple post but it compiled, and again, it didnt work. The player doesnt attach with the platform and it moves on without the player. What would cause it to not attach?
#100
09/05/2007 (6:50 pm)
I have been spending more time with the collision code trying to fix the problem I am having with the Pathshapes. The picture describes things better than I can. Basically what seems to be happening is that when the platform goes right (arrow in green) and the player goes left (arrow in red) the collision fails and the player pops out on the other end. This doesn't happen all the time either, sometimes the colllision does work properly.
If the shape doesn't move, then the collisions work properly all the time.

www.posdreams.com/tmp/platform.jpg
@Joe
The shape itself works if the platform isn't in motion. I do agree, that the issue may lie with collision not handled correctly on pathshape, but I am unsure why adding the collision functions buildConvex, getPolyList etc would help. The Platform itself is derived from ShapeBase which already has alot of the collision functionalty in it (from my limited knowledge it looks like the Shape collision is being done on the collision meshes built when you model the shape itself). Could you give me more details about how you detect the collision? This may be helpful on what I trying to do.

My guesses are now that because the pathshape actually 'transforms' the attached objects on it that when you have 2 bodies in motion, the pathshape in movement actually places the player past the collision hulls on certain ticks. I need to check this, but if the pathshape is called after the player movement then no collision would occur and the player simply pass through the shape.

What should happen if I was going to get collision work would be to try to figure out how to detect a collision between the pathshape and all attach children. It would then readjust the transforms of each child accordingly. Of course saying this and doing it is completely different as I still have to figure out what is going on with the collision code.