RTS type build script - need help - source code supplied
by Andy Hawkins · in Torque Game Engine · 06/13/2008 (9:55 pm) · 4 replies
Description:
Here's the code below.
What it does is an AIPlayer hits a node on a path with an internalName $= "buildObject". The node also has a list of dts objects that are passes into the functions below. The object appears to be built by loading and replacing meshes (replacement animation) every 5 seconds. The data is passed across as well to the new object, but the frame counter is persisted so each new object knows where the animation is up to. It works pretty well...
The problem:
When I delete the previous static object and spawn a new one in place it take about 1 second for the engine to create it so there is a flash where there is nothing there. I also suspect there is more elegant way to do this.
The questions:
1. Is there a better way to handle this type of RTS style building, or if this script is okay - how do I handle the transition?
Right now I'm scheduling the deletion for 1 second later - but this is a hack.
2. Is it possible to load all the meshes into 1 dts and hide parts til later perhaps?
Here's the code below.
What it does is an AIPlayer hits a node on a path with an internalName $= "buildObject". The node also has a list of dts objects that are passes into the functions below. The object appears to be built by loading and replacing meshes (replacement animation) every 5 seconds. The data is passed across as well to the new object, but the frame counter is persisted so each new object knows where the animation is up to. It works pretty well...
The problem:
When I delete the previous static object and spawn a new one in place it take about 1 second for the engine to create it so there is a flash where there is nothing there. I also suspect there is more elegant way to do this.
The questions:
1. Is there a better way to handle this type of RTS style building, or if this script is okay - how do I handle the transition?
Right now I'm scheduling the deletion for 1 second later - but this is a hack.
2. Is it possible to load all the meshes into 1 dts and hide parts til later perhaps?
Associate Andy Hawkins
DrewFX
new Path(Human13Path) { canSaveDynamicFields = "1"; isLooping = "1"; new Marker(myMarker0) { canSaveDynamicFields = "1"; internalName = "Load"; position = "633.81 122.341 20.2"; rotation = "1 0 0 0"; scale = "1 1 1"; seqNum = "1"; type = "Normal"; msToNext = "1000"; smoothingType = "Spline"; }; new Marker(myMarker1) { canSaveDynamicFields = "1"; internalName = "buildTent"; position = "596.601 123.197 20.2"; rotation = "1 0 0 0"; scale = "1 1 1"; seqNum = "2"; type = "Normal"; msToNext = "1000"; smoothingType = "Spline"; frameMax = "3"; buildObjectName0 = "tent1/buildObject_tent1.dts"; buildObjectName1 = "tent1/buildObject_tent2.dts"; buildObjectName2 = "tent1/buildObject_tent3.dts"; buildObjectName3 = "tent1/buildObject_tent4.dts"; }; };AIPlayer calls to set it up
function AIPlayer::onReachDestination(%this,%obj) { %node = %obj.path.getObject(%obj.currentNode); if (%node.internalName $= "buildTent") { // start a build cycle // node has frame information for (%p = 0; %p <= %node.frameMax; %p ++) { %obj.buildObjectName[%p] = %node.buildObjectName[%p]; } %obj.frameMax = %node.frameMax; %obj.schedule(5 * 1000,"initBuildObject",%obj); // true initialise build } } function AIPlayer::initBuildObject(%obj, %init) { // set the player if their build cycle is 0 // wait 10 and then increment a build object by build cycle // repeat until build max is achieved. %obj.frame = 0; %obj.buildObject = DrewFXBuildObject::create(%obj); // schedule the animation %obj.schedule(5 * 1000,"buildObject",%obj,false); } function AIPlayer::buildObject(%obj) { // animate always creates a new object %obj.buildObject = DrewFXBuildObject::animate(%obj.buildObject); if (%obj.buildObject != -1) { // schedule the animation if not complete %obj.schedule(5 * 1000,"buildObject",%obj,false); } }BuildObject functions
// DrewFX Building object type // // Recieves a call to animate to destroy current object // and replace with next object in string array // On completion it broadcasts that its complete // Any object can control the animation and that object // subscribes to the broadcast to know when its done function DrewFXBuildObject::create(%callingObject) { %name = %callingObject.buildObjectName[%callingObject.frame]; %obj = DrewFXBuildObject::spawn(%name,%callingObject.getPosition()); %obj.name = %name; %obj.broadcastMessage = "Build Complete"; for (%p = 0; %p <= %callingObject.frameMax; %p ++) { %obj.buildObjectName[%p] = %callingObject.buildObjectName[%p]; } %obj.frame = 0; %obj.frameMax = %callingObject.frameMax; return %obj; } function DrewFXBuildObject::spawn(%name,%pos) { %shape = "~/data/shapes/buildObjects/" @ %name; %obj = new TSStatic(tent1) { canSaveDynamicFields = "1"; position = %pos; rotation = "0 0 1 179.518"; scale = "1 1 1"; shapeName = %shape; receiveSunLight = "1"; receiveLMLighting = "1"; useCustomAmbientLighting = "0"; customAmbientLighting = "0 0 0 1"; }; MissionCleanup.add(%obj); return %obj; } function DrewFXBuildObject::animate(%obj) { %obj.frame += 1; if (%obj.frame <= %obj.frameMax) { // remember old object persistant stuff // init data is fine for rest %frame = %obj.frame; %name = %obj.buildObjectName[%obj.frame]; // get a new object and pass over data %newObj = DrewFXBuildObject::create(%obj); %newObj.frameMax = %obj.frameMax; %newObj.frame = %frame; // delete old object schedule(1550, 0, destroyBuildObject, %obj); // tell calling function the new object return %newObj; } else { // tell subscribers that this object is built DrewFXBuildObject::broadcastMessage(%obj.broadcastMessage); // return -1 so the calling object knows to quit return -1; } } function destroyBuildObject(%obj) { echo("DrewFXBuildObject - Object Deleted:" @ %obj); %obj.delete(); } function DrewFXBuildObject::broadcastMessage(%obj) { broadcastEventToAllSubscribers(%obj.broadcastMessage); }