Q: Is there some inherent conflict with replacing the normal navigation system func_trains use (the interconnected path_corner entities) with an array of vectors (where we use the index to decide which vector the func_train follows)?
thanks,
OneManClan
====================
LONG VERSION:
Dear Gurus of QuakeC,
I’m on to v2 of the TF2 style 'payload cart’, this time using an array of vectors to provide the waypoints, rather than the normal set of path_corner entities, BUT.. I've have gotten stuck. I'm not sure if the fault lies in my code, or in some quirk of QuakeC. Sorry bout the longish post, but I couldn't condense further without leaving out a potentially crucial detail.
OBJECTIVE
To control the movement of the func_cart (a func_train) by using an array of vectors, which are loaded from a .txt file when the map begins. [EDIT: This is actually an 'implementation' idea, NOT the 'objective'. The actual 'objective' is to make a TF2 style payload 'cart': When blue touches it it moves forward along a fixed path, if they don't it stops, and (after a few seconds) it goes backwards. I'm happy to scrap this implementation if someone can suggest a better method.]
HISTORY
I did get a previous version of this 'reversible cart' working using multiple path_corner entities, but was advised that using an array make more sense, and which is supported by FTE (which I'm using).
PROBLEM
Lots of little weird things including: The func_cart insists on starting at [7], and seems to constantly skip array vector [0]. Strategic dprints also show that the vectors seem to be changing value, ie ones are displayed are not part of the set, and new ones are being generated (?). The cart does stick to the basic path though, except for not going to position[0]. Hopefully the following description of my method will reveal something basic I've overlooked:
CURRENT ATTEMPT
1. We make a .txt file w the vectors the func_cart will follow(agrpl.txt):
Code: Select all
-383 383 200
-383 383 40
-383 -384 40
447 -384 40
448 383 40
0 384 40
1 -1 40
[EDIT: I just realised that I've been assuming that the cart has been starting at [7], but [7] is very close to '0 0 0', so its possible that [0] is not being read, and that the cart is positioning itself at '0 0 0', will test asap]
2. We remove all the waypoint entities from the original map via an ent edit, leaving only the cart and the first target. The map simply does NOT load if the first target isn’t there. [Theory 1: this is the problem]. An excerpt from agrpl.ent:
Code: Select all
{
"model" "*1"
"sounds" "1"
"dmg" "0"
"target" "point1"
"targetname" "train"
"classname" "func_cart"
}
{
"origin" "-383 383 200"
"target" "point2"
"targetname" "point1"
"classname" "path_corner"
}
3. In the QuakeC, we make some new variables:
Code: Select all
.vector current_target; // where the cart is going
.float array_index; // keeps track of which array element the cart is at
.float final_array_element; // keeps track of the number of elements in the array, and also detects the final element
Code: Select all
/*************************************************
fills the global vector array 'cart_target'
returns the number of elements.
************************************************/
#define MAX_WAYPOINTS 20
vector cart_target[MAX_WAYPOINTS];
float () WaypointLoad =
{
local float file, i;
local string str;
// mapname is a global
str = strcat(mapname,".txt");
file = fopen(str, FILE_READ);
if(file < 0)
{
dprint("Problem opening ");
dprint(str);
dprint("\n");
return;
}
for( i = 0; str; i++)
{
str = fgets(file);
if (str == "") break;
cart_target[i] = stov(str);
// Note: this DOES print the correct vectors!
dprint("WaypointLoad loading vector ");
dprint(ftos(i));
dprint(": ");
dprint(vtos(cart_target[i]));
dprint("\n");
}
fclose(file);
// return the number of elements in the array
return i;
};
5. We setup the func_cart via:
Code: Select all
/*************************************************
********** 1. defining the cart entity
************************************************/
void() func_cart =
{
//self is the cart
self.speed = CARTSPEED; // the carts speed
if (!self.target)
{
objerror ("func_cart without a target");
}
self.solid = SOLID_BSP;
self.movetype = #MOVETYPE_PUSH;
self.blocked = fc_blocked; // defined elsewhere
self.touch = fc_touch; // defined elsewhere
self.classname = "cart";
// self.impulse gets set to (time+10) every time Blue touches the cart
// if (self.impulse is > time) ... the cart moves
self.impulse = time + DELAY_BEFORE_GAME_BEGINS;
// What the cart looks like
setmodel( self, self.model );
setsize( self, self.mins, self.maxs );
// we load the waypoints, and .final_array_element is the number of waypoints
self.final_array_element = WaypointLoad();
// array_index stores the current vector index
self.array_index = 0;
// .current_target stores the current vector
self.current_target = cart_target[self.array_index];
// appear at target 1
// The following doesn't work, the cart does NOT appear at
// cart_target[0] (which is '-383 383 200')
// It appears at a point 1/2 way between [0], and [1]
// Possibly there's a conflict w what's in the .ent
setorigin( self, self.current_target );
self.nextthink = self.ltime + DELAY_BEFORE_GAME_BEGINS;
self.think = fc_next;
};
Code: Select all
/*************************************************
**********3. finds next path_corner and moves cart
*************************************************/
void() fc_next =
{
// this dprint reveals that the vector values are constantly increasing(?)
dprint("\n fc_next we are targeting: self.origin -self.mins: ");
dprint(vtos(self.origin - self.mins));
// this dprint reveals that the indexes [i]are[/i] all traversed (ie 'the nodes are walked') but when it gets to (and displays that we're at)[0], the cart (almost)instantly skips to [1]
dprint(", current array_index: ");
dprint(ftos(self.array_index));
dprint("\n");
// self is the cart
self.speed = CARTSPEED; // restore speed in case Red blocked it
if(self.array_index > self.final_array_element)
{
self.array_index = 0;
self.current_target = cart_target[self.array_index];
}
else
{
self.array_index = self.array_index + 1;
self.current_target = cart_target[self.array_index];
}
if(!self.target )
{
objerror( "cart_next: no next target" );
}
SUB_CalcMove( self.current_target - self.mins, self.speed, fc_next );
};
I've got the cart to loop through the whole path, BUT a bunch of weird things are happening that are hard to describe:
1. I put some dprints at the start of fc_next, and Also, every time the actual .origin vector of the cart seems to keep changing, I can't see a pattern, and the path seems the same.
2. The cart does not go through [0].
I could post more details, including results of tests Ive done, but to keep this is simple as possible, could someone please confirm:
Q1: Is there some error I've made?
Q2: Is this method is somehow fundamentally flawed?
Q3: Is there some conflict in the method I'm using, and the basic definition/concept of a func_train?
thanks,
OneManClan