|
|
|
|
@ -480,13 +480,52 @@ void Railways::DebugPrintFindWay(struct s_findway_map *fw) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
|
* GetDestBlock: check if the destination is a split block and return
|
|
|
|
|
* the final destination block.
|
|
|
|
|
*/
|
|
|
|
|
string Railways::GetDestBlock(int locoflags, string blockend) {
|
|
|
|
|
int block_f;
|
|
|
|
|
string block;
|
|
|
|
|
string blockp, blockn; // blockend[pos,neg] name
|
|
|
|
|
|
|
|
|
|
blockp = blockend.substr(2, string::npos);
|
|
|
|
|
block_f = server->blocks.GetFlags(blockp);
|
|
|
|
|
if ((block_f & BLOCK_F_SPLIT) && !(locoflags & LOCO_F_SHORTTRAIN)) {
|
|
|
|
|
blockn = server->blocks.GetFlags(blockp);
|
|
|
|
|
|
|
|
|
|
// direction and position
|
|
|
|
|
if (block_f & BLOCK_F_SPLITPOS) {
|
|
|
|
|
blockn = server->blocks.GetSecondBlock(blockp);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
blockn = blockp;
|
|
|
|
|
blockp = server->blocks.GetSecondBlock(blockn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (blockend[0] == '+') blockend = "+:" + blockn;
|
|
|
|
|
else blockend = "-:" + blockp;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
block = blockend;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
debug (0, "Railway::GetDestBlock Final split:%d blockend:%s"
|
|
|
|
|
, (block_f & BLOCK_F_SPLIT) ? 1 : 0
|
|
|
|
|
, block.c_str());
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
|
* FindWay: will be in two phases to decide where to go and how
|
|
|
|
|
* - check if endblock is valid on SPLIT and long trains.
|
|
|
|
|
* - check all possible ways in respect of (out of service blocks)
|
|
|
|
|
* and the ONLYCARGO/PASSENGER flags
|
|
|
|
|
* return 0 if no way found
|
|
|
|
|
*/
|
|
|
|
|
int Railways::FindWay(string blockstart, string blockend, string lockedfor, string *next) {
|
|
|
|
|
int Railways::FindWay(string org_blockstart, string org_blockend, string lockedfor, string *next) {
|
|
|
|
|
// direction 0 ... RIGHT and DOWN
|
|
|
|
|
// direction 1 ... LEFT and UP
|
|
|
|
|
struct s_findway_data fd_pos;
|
|
|
|
|
@ -496,16 +535,27 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
|
|
|
|
|
Railway *rpos, *rnext;
|
|
|
|
|
std::list<struct s_findway_data> fd_list;
|
|
|
|
|
struct s_findway_map *fd_data = NULL;
|
|
|
|
|
string blockstart, blockend;
|
|
|
|
|
string lockedby;
|
|
|
|
|
int x ,y;
|
|
|
|
|
int found = 0;
|
|
|
|
|
int locoflags = server->locomotives.GetFlags(lockedfor);
|
|
|
|
|
|
|
|
|
|
debug (0, "Railway::FindWay blockstart:%s blockend:%s lockedfor:%s", blockstart.c_str(), blockend.c_str(), lockedfor.c_str());
|
|
|
|
|
debug (0, "Railway::FindWay blockstart:%s blockend:%s lockedfor:%s", org_blockstart.c_str(), org_blockend.c_str(), lockedfor.c_str());
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// check blocklen
|
|
|
|
|
if (blockstart.length() <= 3 || blockend.length() <= 3) return 0;
|
|
|
|
|
if (org_blockstart.length() <= 3 || org_blockend.length() <= 3) return 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// setup blockstart and blockend depending on train type
|
|
|
|
|
// long trains need to get special attentions on the destination
|
|
|
|
|
blockstart = org_blockstart; // no check needed
|
|
|
|
|
blockend = GetDestBlock(locoflags, org_blockend);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// allocate and clear memory for checked data
|
|
|
|
|
fd_data = (struct s_findway_map *) malloc (sizeof(struct s_findway_map) * width * height);
|
|
|
|
|
if (fd_data == NULL) {
|
|
|
|
|
@ -514,6 +564,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
|
|
|
|
|
}
|
|
|
|
|
memset (fd_data, 0x0, sizeof(struct s_findway_map) * width*height);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// find start and endpoint mark on fd_data, also startpoint to fd_list
|
|
|
|
|
fd_end.x = fd_start.x = -1;
|
|
|
|
|
@ -558,7 +609,6 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fd_pos = NextPos(fd_start, Get(fd_start.x, fd_start.y).dir);
|
|
|
|
|
// fd_list.push_back(fd_pos);
|
|
|
|
|
|
|
|
|
|
Lock();
|
|
|
|
|
|
|
|
|
|
@ -575,13 +625,9 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
|
|
|
|
|
if (iter != fd_list.end()) {
|
|
|
|
|
fd_pos = *iter;
|
|
|
|
|
fd_list.pop_front();
|
|
|
|
|
// printf ("get from stack (%d,%d)\n", fd_pos.x, fd_pos.y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// printf ("%s:%d fd_start (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_start.x, fd_start.y, fd_start.enterfrom);
|
|
|
|
|
// printf ("%s:%d fd_end (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_end.x, fd_end.y, fd_end.enterfrom);
|
|
|
|
|
// printf ("%s:%d fd_pos (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom);
|
|
|
|
|
if (fd_pos.enterfrom < 0 && fd_pos.enterfrom > 3) {
|
|
|
|
|
fd_pos.enterfrom = -1;
|
|
|
|
|
fd_pos.x = -1;
|
|
|
|
|
@ -667,11 +713,11 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
|
|
|
|
|
fd_pos.way = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
// if block is off ignore it completly
|
|
|
|
|
else if (rpos->type == RAILWAY_BLOCK) {
|
|
|
|
|
int blflags = server->blocks.GetFlags(rpos->name);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// check if block is available for entering
|
|
|
|
|
if ((server->blocks.IsOff(rpos->name) ||
|
|
|
|
|
((blflags & BLOCK_F_ENDSTATION) && !(locoflags & LOCO_F_CANREVERSE)) ||
|
|
|
|
|
((blflags & BLOCK_F_SHORT) && !(locoflags & LOCO_F_SHORTTRAIN) &&
|
|
|
|
|
@ -715,13 +761,12 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
|
|
|
|
|
fd_pos.way = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//printf ("%s:%d fd_pos (%d,%d) enterfrom:%d\n\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found == 0) *next = "";
|
|
|
|
|
else {
|
|
|
|
|
//
|
|
|
|
|
// next = "b:+blockname,t:name:0,t:name:1,b:-blockname"
|
|
|
|
|
// check if way found a block.
|
|
|
|
|
size_t npos;
|
|
|
|
|
if ((npos = next->find(",b:")) != string::npos)
|
|
|
|
|
*next = next->substr(0, next->find(",", npos+1));
|
|
|
|
|
@ -732,6 +777,8 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
|
|
|
|
|
|
|
|
|
|
free (fd_data);
|
|
|
|
|
|
|
|
|
|
debug (0, "Railway::FindWay Result (%s) -> (%s) Found:%d Next:%s", blockstart.c_str(), blockend.c_str(), found, next->c_str());
|
|
|
|
|
|
|
|
|
|
return found;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -768,10 +815,11 @@ int Railways::_NextPosIsValid(string loconame, int locoflags, struct s_findway_d
|
|
|
|
|
int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string block) {
|
|
|
|
|
string pblock;
|
|
|
|
|
string nblock;
|
|
|
|
|
Railway *rpos = NULL;
|
|
|
|
|
int bflags = server->blocks.GetFlags(block);
|
|
|
|
|
int nblockflags = 0;
|
|
|
|
|
int pblockflags = 0;
|
|
|
|
|
int x1, y1, x2, y2, dx = 0, dy = 0;
|
|
|
|
|
int x1, y1, x2, y2, x = 0, y = 0;
|
|
|
|
|
|
|
|
|
|
debug (0, "Railway::_SplitBlockIsFreeAndAllowed loconame:%s flags:%d block:%s", loconame.c_str(), locoflags, block.c_str());
|
|
|
|
|
|
|
|
|
|
@ -779,7 +827,7 @@ int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string
|
|
|
|
|
if ((locoflags & !LOCO_F_SHORTTRAIN) && (bflags & !BLOCK_F_SPLIT)) return 0;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// read negative the positive block flags
|
|
|
|
|
// read negative and positive block flags
|
|
|
|
|
if (bflags & BLOCK_F_SPLITPOS) {
|
|
|
|
|
pblockflags = bflags;
|
|
|
|
|
pblock = block;
|
|
|
|
|
@ -806,14 +854,16 @@ int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string
|
|
|
|
|
if (_FindReference(&x1, &y1, pblock) == 0) return 0;
|
|
|
|
|
if (_FindReference(&x2, &y2, nblock) == 0) return 0;
|
|
|
|
|
debug (0, "Railway::_SplitBlockIsFreeAndAllowed p pos(%d,%d) n pos(%d,%d)", x1, y1, x2, y2);
|
|
|
|
|
// if (x1 == x2 )
|
|
|
|
|
// do {
|
|
|
|
|
//
|
|
|
|
|
// } while
|
|
|
|
|
//
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x = x1; y = y1;
|
|
|
|
|
do {
|
|
|
|
|
if ( railways[GetRIdx(x,y)].lockedby[0] != 0) return 0;
|
|
|
|
|
if (x1 == x2) y++; // block is going from down to up
|
|
|
|
|
else x++; // block is going from left to right
|
|
|
|
|
} while (x != x2 || y != y2);
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
|
|
|
|
|
// direction 0 ... RIGHT and DOWN
|
|
|
|
|
@ -832,7 +882,7 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
|
|
|
|
|
|
|
|
|
|
debug (0, "Railway::FindRandomWay - disabled for now - needs to be rewritten");
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
// check blocklen
|
|
|
|
|
if (blockstart.length() <= 3) return 0;
|
|
|
|
|
|
|
|
|
|
@ -1040,10 +1090,16 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
|
|
|
|
|
free (fd_data);
|
|
|
|
|
|
|
|
|
|
return found;
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* try to lock or unlock the way for the loco(lockedby)
|
|
|
|
|
* Will also do the check for long trains and split blocks.
|
|
|
|
|
*/
|
|
|
|
|
#warning check for split blocks and long trains not yet finished.
|
|
|
|
|
//FIXME: check for split blocks and long trains not yet finished.
|
|
|
|
|
int Railways::LockWay (string way, string lockedby, int lockonoff) {
|
|
|
|
|
int res = 0;
|
|
|
|
|
size_t pos1, pos2;
|
|
|
|
|
@ -1070,9 +1126,12 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
|
|
|
|
|
if ((pos2 = way.find(",", pos1+1)) == string::npos) endblock = way.substr (pos1+3, pos2);
|
|
|
|
|
else endblock = way.substr (pos1+3, pos2-pos1-3);
|
|
|
|
|
|
|
|
|
|
// printf ("%s:%d LockWay Way: '%s' Startblock: '%s' Endblock: '%s'\n", __FILE__, __LINE__, way.c_str(),
|
|
|
|
|
// startblock.c_str(), endblock.c_str());
|
|
|
|
|
printf ("%s:%d LockWay Way: '%s' Startblock: '%s' Endblock: '%s'\n", __FILE__, __LINE__, way.c_str(),
|
|
|
|
|
startblock.c_str(), endblock.c_str());
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// find start position
|
|
|
|
|
//
|
|
|
|
|
if (FindReference(&start.x, &start.y, startblock.substr(2,string::npos))) {
|
|
|
|
|
if (Get(start.x, start.y).dir == 1) {
|
|
|
|
|
if (startblock[0] == '+') start.enterfrom = 0;
|
|
|
|
|
@ -1088,6 +1147,9 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// find end position, this needs to take care of the SPLIT blocks.
|
|
|
|
|
// if split BLOCK and LONG train check for the currect end block
|
|
|
|
|
if (FindReference(&end.x, &end.y, endblock.substr(2,string::npos))) {
|
|
|
|
|
if (Get(end.x, end.y).dir == 1) {
|
|
|
|
|
if (endblock[0] == '+') end.enterfrom = 0;
|
|
|
|
|
|