working on split blocks

master
Steffen Pohle 2 years ago
parent d4efc193c7
commit 54e3342a5e

6
.gitignore vendored

@ -17,4 +17,8 @@ z21emu/z21emu
*.bin
track.json
track.json.backup.*
Modelbahn.anjuta
*.track.json
Backup/
.anjuta_sym_db.db
.anjuta/

@ -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;

@ -101,6 +101,7 @@ class Railways {
int _FindReference(int *x, int *y, string name);
int _SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string block);
int _NextPosIsValid(string loconame, int locoflags, struct s_findway_data *fwd);
string GetDestBlock(int locoflags, string blockend);
public:
Railways();

Loading…
Cancel
Save