/** * Save the highscores in a network game when it has ended * @return Position of the local company in the highscore list. */ int8 SaveHighScoreValueNetwork() { const Company *c; const Company *cl[MAX_COMPANIES]; uint count = 0; int8 company = -1; /* Sort all active companies with the highest score first */ FOR_ALL_COMPANIES(c) cl[count++] = c; QSortT(cl, count, &HighScoreSorter); { uint i; memset(_highscore_table[SP_MULTIPLAYER], 0, sizeof(_highscore_table[SP_MULTIPLAYER])); /* Copy over Top5 companies */ for (i = 0; i < lengthof(_highscore_table[SP_MULTIPLAYER]) && i < count; i++) { HighScore *hs = &_highscore_table[SP_MULTIPLAYER][i]; SetDParam(0, cl[i]->index); SetDParam(1, cl[i]->index); GetString(hs->company, STR_HIGHSCORE_NAME, lastof(hs->company)); // get manager/company name string hs->score = cl[i]->old_economy[0].performance_history; hs->title = EndGameGetPerformanceTitleFromValue(hs->score); /* get the ranking of the local company */ if (cl[i]->index == _local_company) company = i; } } /* Add top5 companies to highscore table */ return company; }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { Dimension d; switch (widget) { case WID_S_LEFT: SetDParamMaxValue(0, MAX_YEAR * DAYS_IN_YEAR); d = GetStringBoundingBox(STR_WHITE_DATE_LONG); break; case WID_S_RIGHT: { int64 max_money = UINT32_MAX; const Company *c; FOR_ALL_COMPANIES(c) max_money = max<int64>(c->money, max_money); SetDParam(0, 100LL * max_money); d = GetStringBoundingBox(STR_COMPANY_MONEY); break; } default: return; } d.width += padding.width; d.height += padding.height; *size = maxdim(d, *size); }
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { Dimension d; switch (widget) { /* Left and right should have same sizing. */ case WID_S_LEFT: case WID_S_RIGHT: { SetDParamMaxValue(0, MAX_YEAR * DAYS_IN_YEAR); d = GetStringBoundingBox(STR_WHITE_DATE_LONG); int64 max_money = UINT32_MAX; const Company *c; FOR_ALL_COMPANIES(c) max_money = max<int64>(c->money, max_money); SetDParam(0, 100LL * max_money); d = maxdim(d, GetStringBoundingBox(STR_COMPANY_MONEY)); break; } case WID_S_MIDDLE: d = GetStringBoundingBox(STR_STATUSBAR_AUTOSAVE); d = maxdim(d, GetStringBoundingBox(STR_STATUSBAR_PAUSED)); if (Company::IsValidID(_local_company)) { SetDParam(0, _local_company); d = maxdim(d, GetStringBoundingBox(STR_STATUSBAR_COMPANY_NAME)); } break; default: return; } d.width += padding.width; d.height += padding.height; *size = maxdim(d, *size); }
/** * Check the validity of some of the caches. * Especially in the sense of desyncs between * the cached value and what the value would * be when calculated from the 'base' data. */ static void CheckCaches() { /* Return here so it is easy to add checks that are run * always to aid testing of caches. */ if (_debug_desync_level <= 1) return; /* Check the town caches. */ SmallVector<TownCache, 4> old_town_caches; Town *t; FOR_ALL_TOWNS(t) { MemCpyT(old_town_caches.Append(), &t->cache); } extern void RebuildTownCaches(); RebuildTownCaches(); RebuildSubsidisedSourceAndDestinationCache(); uint i = 0; FOR_ALL_TOWNS(t) { if (MemCmpT(old_town_caches.Get(i), &t->cache) != 0) { DEBUG(desync, 2, "town cache mismatch: town %i", (int)t->index); } i++; } /* Check company infrastructure cache. */ SmallVector<CompanyInfrastructure, 4> old_infrastructure; Company *c; FOR_ALL_COMPANIES(c) MemCpyT(old_infrastructure.Append(), &c->infrastructure); extern void AfterLoadCompanyStats(); AfterLoadCompanyStats(); i = 0; FOR_ALL_COMPANIES(c) { if (MemCmpT(old_infrastructure.Get(i), &c->infrastructure) != 0) { DEBUG(desync, 2, "infrastructure cache mismatch: company %i", (int)c->index); } i++; } /* Strict checking of the road stop cache entries */ const RoadStop *rs; FOR_ALL_ROADSTOPS(rs) { if (IsStandardRoadStopTile(rs->xy)) continue; assert(rs->GetEntry(DIAGDIR_NE) != rs->GetEntry(DIAGDIR_NW)); rs->GetEntry(DIAGDIR_NE)->CheckIntegrity(rs); rs->GetEntry(DIAGDIR_NW)->CheckIntegrity(rs); } Vehicle *v; FOR_ALL_VEHICLES(v) { extern void FillNewGRFVehicleCache(const Vehicle *v); if (v != v->First() || v->vehstatus & VS_CRASHED || !v->IsPrimaryVehicle()) continue; uint length = 0; for (const Vehicle *u = v; u != NULL; u = u->Next()) length++; NewGRFCache *grf_cache = CallocT<NewGRFCache>(length); VehicleCache *veh_cache = CallocT<VehicleCache>(length); GroundVehicleCache *gro_cache = CallocT<GroundVehicleCache>(length); TrainCache *tra_cache = CallocT<TrainCache>(length); length = 0; for (const Vehicle *u = v; u != NULL; u = u->Next()) { FillNewGRFVehicleCache(u); grf_cache[length] = u->grf_cache; veh_cache[length] = u->vcache; switch (u->type) { case VEH_TRAIN: gro_cache[length] = Train::From(u)->gcache; tra_cache[length] = Train::From(u)->tcache; break; case VEH_ROAD: gro_cache[length] = RoadVehicle::From(u)->gcache; break; default: break; } length++; } switch (v->type) { case VEH_TRAIN: Train::From(v)->ConsistChanged(CCF_TRACK); break; case VEH_ROAD: RoadVehUpdateCache(RoadVehicle::From(v)); break; case VEH_AIRCRAFT: UpdateAircraftCache(Aircraft::From(v)); break; case VEH_SHIP: Ship::From(v)->UpdateCache(); break; default: break; } length = 0; for (const Vehicle *u = v; u != NULL; u = u->Next()) { FillNewGRFVehicleCache(u); if (memcmp(&grf_cache[length], &u->grf_cache, sizeof(NewGRFCache)) != 0) { DEBUG(desync, 2, "newgrf cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length); } if (memcmp(&veh_cache[length], &u->vcache, sizeof(VehicleCache)) != 0) { DEBUG(desync, 2, "vehicle cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length); } switch (u->type) { case VEH_TRAIN: if (memcmp(&gro_cache[length], &Train::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) { DEBUG(desync, 2, "train ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); } if (memcmp(&tra_cache[length], &Train::From(u)->tcache, sizeof(TrainCache)) != 0) { DEBUG(desync, 2, "train cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); } break; case VEH_ROAD: if (memcmp(&gro_cache[length], &RoadVehicle::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) { DEBUG(desync, 2, "road vehicle ground vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); } break; default: break; } length++; } free(grf_cache); free(veh_cache); free(gro_cache); free(tra_cache); } /* Check whether the caches are still valid */ FOR_ALL_VEHICLES(v) { byte buff[sizeof(VehicleCargoList)]; memcpy(buff, &v->cargo, sizeof(VehicleCargoList)); v->cargo.InvalidateCache(); assert(memcmp(&v->cargo, buff, sizeof(VehicleCargoList)) == 0); } Station *st; FOR_ALL_STATIONS(st) { for (CargoID c = 0; c < NUM_CARGO; c++) { byte buff[sizeof(StationCargoList)]; memcpy(buff, &st->goods[c].cargo, sizeof(StationCargoList)); st->goods[c].cargo.InvalidateCache(); assert(memcmp(&st->goods[c].cargo, buff, sizeof(StationCargoList)) == 0); } } }