Index: src/vehicle_base.h =================================================================== --- src/vehicle_base.h (Revision 22427) +++ src/vehicle_base.h (Arbeitskopie) @@ -460,6 +460,12 @@ * @return the next vehicle or NULL when there isn't a next vehicle. */ inline Vehicle *Next() const { return this->next; } + inline Vehicle *Next(int8 n) { + if (n < 0) return this->Previous(-n); + Vehicle *v = this; + for (int i = 0; i != n && v != NULL; i++) v = v->Next(); + return v; + } /** * Get the previous vehicle of this vehicle. @@ -467,6 +473,12 @@ * @return the previous vehicle or NULL when there isn't a previous vehicle. */ inline Vehicle *Previous() const { return this->previous; } + inline Vehicle *Previous(int8 n) { + if (n < 0) return this->Next(-n); + Vehicle *v = this; + for (int i = 0; i != n && v != NULL; i++) v = v->Previous(); + return v; + } /** * Get the first vehicle of this vehicle chain. Index: src/newgrf_engine.cpp =================================================================== --- src/newgrf_engine.cpp (Revision 22427) +++ src/newgrf_engine.cpp (Arbeitskopie) @@ -659,6 +659,63 @@ return count; } + // get vars for n-th vehicle in chain [signed number relative to vehicle] + case 0x61: // DirDifference + if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return 0; + + { + const Vehicle* u = v->Next((int8)parameter); + if (u == NULL) return 0; + + DirDiff d = (int8)parameter < 0 ? DirDifference(u->direction, v->direction) : DirDifference(v->direction, u->direction); + if (d > DIRDIFF_REVERSE) return d | 0xFFFFFFF8; + return d; + } + + case 0x62: // height difference + if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return 0; + + { + const Vehicle* u = v->Next((int8)parameter); + if (u == NULL) return 0; + return (int8)parameter < 0 ? u->z_pos - v->z_pos : v->z_pos - u->z_pos; + } + + case 0x63: // vehstatus + if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return 0; + + { + const Vehicle* u = v->Next((int8)parameter); + if (u == NULL) return 0; + return u->vehstatus; + } + + case 0x64: // bitstuffed variant xxyyzzhd + if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return 0; + + { + const Vehicle* u = v->Next((int8)parameter); + if (u == NULL) return 0; + + uint32 ret = (int8)parameter < 0 ? DirDifference(u->direction, v->direction) : DirDifference(v->direction, u->direction); + if (ret > DIRDIFF_REVERSE) ret |= 0x08; + if (u->vehstatus & VS_HIDDEN) ret |= 0x80; + ret |= (((int8)parameter < 0 ? u->z_pos - v->z_pos : v->z_pos - u->z_pos) & 0xFF) << 8; + ret |= (((int8)parameter < 0 ? u->y_pos - v->y_pos : v->y_pos - u->y_pos) & 0xFF) << 16; + ret |= (((int8)parameter < 0 ? u->x_pos - v->x_pos : v->x_pos - u->x_pos) & 0xFF) << 24; + return ret; + } + + case 0x65: // engine-id + if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return 0; + + { + const Vehicle* u = v->Next((int8)parameter); + if (u == NULL) return 0xFFFFFFFF; + return Engine::Get(u->engine_type)->grf_prop.local_id; + } + + case 0xFE: case 0xFF: { uint16 modflags = 0;