|
|
|
@ -1137,8 +1137,244 @@ void Load_VESR()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct vehicle_venc {
|
|
|
|
|
VehicleID id;
|
|
|
|
|
VehicleCache vcache;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct train_venc {
|
|
|
|
|
VehicleID id;
|
|
|
|
|
GroundVehicleCache gvcache;
|
|
|
|
|
bool cached_tilt;
|
|
|
|
|
uint8 cached_num_engines;
|
|
|
|
|
byte user_def_data;
|
|
|
|
|
int cached_max_curve_speed;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct roadvehicle_venc {
|
|
|
|
|
VehicleID id;
|
|
|
|
|
GroundVehicleCache gvcache;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct aircraft_venc {
|
|
|
|
|
VehicleID id;
|
|
|
|
|
uint16 cached_max_range;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static std::vector<vehicle_venc> _vehicle_vencs;
|
|
|
|
|
static std::vector<train_venc> _train_vencs;
|
|
|
|
|
static std::vector<roadvehicle_venc> _roadvehicle_vencs;
|
|
|
|
|
static std::vector<aircraft_venc> _aircraft_vencs;
|
|
|
|
|
|
|
|
|
|
void Save_VENC()
|
|
|
|
|
{
|
|
|
|
|
if (!IsNetworkServerSave()) {
|
|
|
|
|
SlSetLength(0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SlAutolength([](void *) {
|
|
|
|
|
int types[4] = {};
|
|
|
|
|
int total = 0;
|
|
|
|
|
for (Vehicle *v : Vehicle::Iterate()) {
|
|
|
|
|
total++;
|
|
|
|
|
if (v->type < VEH_COMPANY_END) types[v->type]++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* vehicle cache */
|
|
|
|
|
SlWriteUint32(total);
|
|
|
|
|
for (Vehicle *v : Vehicle::Iterate()) {
|
|
|
|
|
SlWriteUint32(v->index);
|
|
|
|
|
SlWriteUint16(v->vcache.cached_max_speed);
|
|
|
|
|
SlWriteUint16(v->vcache.cached_cargo_age_period);
|
|
|
|
|
SlWriteByte(v->vcache.cached_vis_effect);
|
|
|
|
|
SlWriteByte(v->vcache.cached_veh_flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto write_gv_cache = [&](const GroundVehicleCache &cache) {
|
|
|
|
|
SlWriteUint32(cache.cached_weight);
|
|
|
|
|
SlWriteUint32(cache.cached_slope_resistance);
|
|
|
|
|
SlWriteUint32(cache.cached_max_te);
|
|
|
|
|
SlWriteUint32(cache.cached_axle_resistance);
|
|
|
|
|
SlWriteUint32(cache.cached_max_track_speed);
|
|
|
|
|
SlWriteUint32(cache.cached_power);
|
|
|
|
|
SlWriteUint32(cache.cached_air_drag);
|
|
|
|
|
SlWriteUint16(cache.cached_total_length);
|
|
|
|
|
SlWriteUint16(cache.first_engine);
|
|
|
|
|
SlWriteByte(cache.cached_veh_length);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* train */
|
|
|
|
|
SlWriteUint32(types[VEH_TRAIN]);
|
|
|
|
|
for (Train *t : Train::Iterate()) {
|
|
|
|
|
SlWriteUint32(t->index);
|
|
|
|
|
write_gv_cache(t->gcache);
|
|
|
|
|
SlWriteByte(t->tcache.cached_tilt);
|
|
|
|
|
SlWriteByte(t->tcache.cached_num_engines);
|
|
|
|
|
SlWriteByte(t->tcache.user_def_data);
|
|
|
|
|
SlWriteUint32(t->tcache.cached_max_curve_speed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* road vehicle */
|
|
|
|
|
SlWriteUint32(types[VEH_ROAD]);
|
|
|
|
|
for (RoadVehicle *rv : RoadVehicle::Iterate()) {
|
|
|
|
|
SlWriteUint32(rv->index);
|
|
|
|
|
write_gv_cache(rv->gcache);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* aircraft */
|
|
|
|
|
SlWriteUint32(types[VEH_AIRCRAFT]);
|
|
|
|
|
for (Aircraft *a : Aircraft::Iterate()) {
|
|
|
|
|
SlWriteUint32(a->index);
|
|
|
|
|
SlWriteUint16(a->acache.cached_max_range);
|
|
|
|
|
}
|
|
|
|
|
}, nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Load_VENC()
|
|
|
|
|
{
|
|
|
|
|
if (SlGetFieldLength() == 0) return;
|
|
|
|
|
|
|
|
|
|
if (!_networking || _network_server) {
|
|
|
|
|
SlSkipBytes(SlGetFieldLength());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_vehicle_vencs.resize(SlReadUint32());
|
|
|
|
|
for (vehicle_venc &venc : _vehicle_vencs) {
|
|
|
|
|
venc.id = SlReadUint32();
|
|
|
|
|
venc.vcache.cached_max_speed = SlReadUint16();
|
|
|
|
|
venc.vcache.cached_cargo_age_period = SlReadUint16();
|
|
|
|
|
venc.vcache.cached_vis_effect = SlReadByte();
|
|
|
|
|
venc.vcache.cached_veh_flags = SlReadByte();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto read_gv_cache = [&](GroundVehicleCache &cache) {
|
|
|
|
|
cache.cached_weight = SlReadUint32();
|
|
|
|
|
cache.cached_slope_resistance = SlReadUint32();
|
|
|
|
|
cache.cached_max_te = SlReadUint32();
|
|
|
|
|
cache.cached_axle_resistance = SlReadUint32();
|
|
|
|
|
cache.cached_max_track_speed = SlReadUint32();
|
|
|
|
|
cache.cached_power = SlReadUint32();
|
|
|
|
|
cache.cached_air_drag = SlReadUint32();
|
|
|
|
|
cache.cached_total_length = SlReadUint16();
|
|
|
|
|
cache.first_engine = SlReadUint16();
|
|
|
|
|
cache.cached_veh_length = SlReadByte();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_train_vencs.resize(SlReadUint32());
|
|
|
|
|
for (train_venc &venc : _train_vencs) {
|
|
|
|
|
venc.id = SlReadUint32();
|
|
|
|
|
read_gv_cache(venc.gvcache);
|
|
|
|
|
venc.cached_tilt = SlReadByte();
|
|
|
|
|
venc.cached_num_engines = SlReadByte();
|
|
|
|
|
venc.user_def_data = SlReadByte();
|
|
|
|
|
venc.cached_max_curve_speed = SlReadUint32();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_roadvehicle_vencs.resize(SlReadUint32());
|
|
|
|
|
for (roadvehicle_venc &venc : _roadvehicle_vencs) {
|
|
|
|
|
venc.id = SlReadUint32();
|
|
|
|
|
read_gv_cache(venc.gvcache);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_aircraft_vencs.resize(SlReadUint32());
|
|
|
|
|
for (aircraft_venc &venc : _aircraft_vencs) {
|
|
|
|
|
venc.id = SlReadUint32();
|
|
|
|
|
venc.cached_max_range = SlReadUint16();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SlResetVENC()
|
|
|
|
|
{
|
|
|
|
|
_vehicle_vencs.clear();
|
|
|
|
|
_train_vencs.clear();
|
|
|
|
|
_roadvehicle_vencs.clear();
|
|
|
|
|
_aircraft_vencs.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void LogVehicleVENCMessage(const Vehicle *v, const char *var)
|
|
|
|
|
{
|
|
|
|
|
char log_buffer[1024];
|
|
|
|
|
|
|
|
|
|
char *p = log_buffer + seprintf(log_buffer, lastof(log_buffer), "[load]: vehicle cache mismatch: %s", var);
|
|
|
|
|
|
|
|
|
|
extern void WriteVehicleInfo(char *&p, const char *last, const Vehicle *u, const Vehicle *v, uint length);
|
|
|
|
|
uint length = 0;
|
|
|
|
|
for (const Vehicle *u = v->First(); u != v; u = u->Next()) {
|
|
|
|
|
length++;
|
|
|
|
|
}
|
|
|
|
|
WriteVehicleInfo(p, lastof(log_buffer), v, v->First(), length);
|
|
|
|
|
DEBUG(desync, 0, "%s", log_buffer);
|
|
|
|
|
LogDesyncMsg(log_buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
void CheckVehicleVENCProp(T &v_prop, T venc_prop, const Vehicle *v, const char *var)
|
|
|
|
|
{
|
|
|
|
|
if (v_prop != venc_prop) {
|
|
|
|
|
v_prop = venc_prop;
|
|
|
|
|
LogVehicleVENCMessage(v, var);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SlProcessVENC()
|
|
|
|
|
{
|
|
|
|
|
for (const vehicle_venc &venc : _vehicle_vencs) {
|
|
|
|
|
Vehicle *v = Vehicle::GetIfValid(venc.id);
|
|
|
|
|
if (v == nullptr) continue;
|
|
|
|
|
CheckVehicleVENCProp(v->vcache.cached_max_speed, venc.vcache.cached_max_speed, v, "cached_max_speed");
|
|
|
|
|
CheckVehicleVENCProp(v->vcache.cached_cargo_age_period, venc.vcache.cached_cargo_age_period, v, "cached_cargo_age_period");
|
|
|
|
|
CheckVehicleVENCProp(v->vcache.cached_vis_effect, venc.vcache.cached_vis_effect, v, "cached_vis_effect");
|
|
|
|
|
if (HasBit(v->vcache.cached_veh_flags ^ venc.vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT)) {
|
|
|
|
|
SB(v->vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT, 1, HasBit(venc.vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT) ? 1 : 0);
|
|
|
|
|
LogVehicleVENCMessage(v, "VCF_LAST_VISUAL_EFFECT");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto check_gv_cache = [&](GroundVehicleCache &v_gvcache, const GroundVehicleCache &venc_gvcache, const Vehicle *v) {
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_weight, venc_gvcache.cached_weight, v, "cached_weight");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_slope_resistance, venc_gvcache.cached_slope_resistance, v, "cached_slope_resistance");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_max_te, venc_gvcache.cached_max_te, v, "cached_max_te");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_axle_resistance, venc_gvcache.cached_axle_resistance, v, "cached_axle_resistance");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_max_track_speed, venc_gvcache.cached_max_track_speed, v, "cached_max_track_speed");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_power, venc_gvcache.cached_power, v, "cached_power");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_air_drag, venc_gvcache.cached_air_drag, v, "cached_air_drag");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_total_length, venc_gvcache.cached_total_length, v, "cached_total_length");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.first_engine, venc_gvcache.first_engine, v, "first_engine");
|
|
|
|
|
CheckVehicleVENCProp(v_gvcache.cached_veh_length, venc_gvcache.cached_veh_length, v, "cached_veh_length");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const train_venc &venc : _train_vencs) {
|
|
|
|
|
Train *t = Train::GetIfValid(venc.id);
|
|
|
|
|
if (t == nullptr) continue;
|
|
|
|
|
check_gv_cache(t->gcache, venc.gvcache, t);
|
|
|
|
|
CheckVehicleVENCProp(t->tcache.cached_tilt, venc.cached_tilt, t, "cached_tilt");
|
|
|
|
|
CheckVehicleVENCProp(t->tcache.cached_num_engines, venc.cached_num_engines, t, "cached_num_engines");
|
|
|
|
|
CheckVehicleVENCProp(t->tcache.user_def_data, venc.user_def_data, t, "user_def_data");
|
|
|
|
|
CheckVehicleVENCProp(t->tcache.cached_max_curve_speed, venc.cached_max_curve_speed, t, "cached_max_curve_speed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const roadvehicle_venc &venc : _roadvehicle_vencs) {
|
|
|
|
|
RoadVehicle *rv = RoadVehicle::GetIfValid(venc.id);
|
|
|
|
|
if (rv == nullptr) continue;
|
|
|
|
|
check_gv_cache(rv->gcache, venc.gvcache, rv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const aircraft_venc &venc : _aircraft_vencs) {
|
|
|
|
|
Aircraft *a = Aircraft::GetIfValid(venc.id);
|
|
|
|
|
if (a == nullptr) continue;
|
|
|
|
|
if (a->acache.cached_max_range != venc.cached_max_range) {
|
|
|
|
|
a->acache.cached_max_range = venc.cached_max_range;
|
|
|
|
|
a->acache.cached_max_range_sqr = venc.cached_max_range * venc.cached_max_range;
|
|
|
|
|
LogVehicleVENCMessage(a, "cached_max_range");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern const ChunkHandler _veh_chunk_handlers[] = {
|
|
|
|
|
{ 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_ARRAY},
|
|
|
|
|
{ 'VEOX', Save_VEOX, Load_VEOX, nullptr, nullptr, CH_SPARSE_ARRAY},
|
|
|
|
|
{ 'VESR', Save_VESR, Load_VESR, nullptr, nullptr, CH_SPARSE_ARRAY | CH_LAST},
|
|
|
|
|
{ 'VESR', Save_VESR, Load_VESR, nullptr, nullptr, CH_SPARSE_ARRAY},
|
|
|
|
|
{ 'VENC', Save_VENC, Load_VENC, nullptr, nullptr, CH_RIFF | CH_LAST},
|
|
|
|
|
};
|
|
|
|
|