mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-16 00:12:51 +00:00
(svn r22984) -Feature: Display profit icons for groups in the group GUI.
This commit is contained in:
parent
d6e6e8a9d4
commit
23a2f23eb3
11
src/group.h
11
src/group.h
@ -26,18 +26,29 @@ struct GroupStatistics {
|
|||||||
uint16 num_vehicle; ///< Number of vehicles.
|
uint16 num_vehicle; ///< Number of vehicles.
|
||||||
uint16 *num_engines; ///< Caches the number of engines of each type the company owns.
|
uint16 *num_engines; ///< Caches the number of engines of each type the company owns.
|
||||||
|
|
||||||
|
uint16 num_profit_vehicle; ///< Number of vehicles considered for profit statistics;
|
||||||
|
Money profit_last_year; ///< Sum of profits for all vehicles.
|
||||||
|
|
||||||
GroupStatistics();
|
GroupStatistics();
|
||||||
~GroupStatistics();
|
~GroupStatistics();
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
|
void ClearProfits()
|
||||||
|
{
|
||||||
|
this->num_profit_vehicle = 0;
|
||||||
|
this->profit_last_year = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static GroupStatistics &Get(CompanyID company, GroupID id_g, VehicleType type);
|
static GroupStatistics &Get(CompanyID company, GroupID id_g, VehicleType type);
|
||||||
static GroupStatistics &Get(const Vehicle *v);
|
static GroupStatistics &Get(const Vehicle *v);
|
||||||
static GroupStatistics &GetAllGroup(const Vehicle *v);
|
static GroupStatistics &GetAllGroup(const Vehicle *v);
|
||||||
|
|
||||||
static void CountVehicle(const Vehicle *v, int delta);
|
static void CountVehicle(const Vehicle *v, int delta);
|
||||||
static void CountEngine(const Vehicle *v, int delta);
|
static void CountEngine(const Vehicle *v, int delta);
|
||||||
|
static void VehicleReachedProfitAge(const Vehicle *v);
|
||||||
|
|
||||||
|
static void UpdateProfits();
|
||||||
static void UpdateAfterLoad();
|
static void UpdateAfterLoad();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@ GroupStatistics::~GroupStatistics()
|
|||||||
void GroupStatistics::Clear()
|
void GroupStatistics::Clear()
|
||||||
{
|
{
|
||||||
this->num_vehicle = 0;
|
this->num_vehicle = 0;
|
||||||
|
this->num_profit_vehicle = 0;
|
||||||
|
this->profit_last_year = 0;
|
||||||
|
|
||||||
/* This is also called when NewGRF change. So the number of engines might have changed. Reallocate. */
|
/* This is also called when NewGRF change. So the number of engines might have changed. Reallocate. */
|
||||||
free(this->num_engines);
|
free(this->num_engines);
|
||||||
@ -139,6 +141,13 @@ void GroupStatistics::Clear()
|
|||||||
|
|
||||||
stats_all.num_vehicle += delta;
|
stats_all.num_vehicle += delta;
|
||||||
stats.num_vehicle += delta;
|
stats.num_vehicle += delta;
|
||||||
|
|
||||||
|
if (v->age > VEHICLE_PROFIT_MIN_AGE) {
|
||||||
|
stats_all.num_profit_vehicle += delta;
|
||||||
|
stats_all.profit_last_year += v->GetDisplayProfitLastYear() * delta;
|
||||||
|
stats.num_profit_vehicle += delta;
|
||||||
|
stats.profit_last_year += v->GetDisplayProfitLastYear() * delta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,6 +162,45 @@ void GroupStatistics::Clear()
|
|||||||
GroupStatistics::Get(v).num_engines[v->engine_type] += delta;
|
GroupStatistics::Get(v).num_engines[v->engine_type] += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a vehicle to the profit sum of its group.
|
||||||
|
*/
|
||||||
|
/* static */ void GroupStatistics::VehicleReachedProfitAge(const Vehicle *v)
|
||||||
|
{
|
||||||
|
GroupStatistics &stats_all = GroupStatistics::GetAllGroup(v);
|
||||||
|
GroupStatistics &stats = GroupStatistics::Get(v);
|
||||||
|
|
||||||
|
stats_all.num_profit_vehicle++;
|
||||||
|
stats_all.profit_last_year += v->GetDisplayProfitLastYear();
|
||||||
|
stats.num_profit_vehicle++;
|
||||||
|
stats.profit_last_year += v->GetDisplayProfitLastYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recompute the profits for all groups.
|
||||||
|
*/
|
||||||
|
/* static */ void GroupStatistics::UpdateProfits()
|
||||||
|
{
|
||||||
|
/* Set up the engine count for all companies */
|
||||||
|
Company *c;
|
||||||
|
FOR_ALL_COMPANIES(c) {
|
||||||
|
for (VehicleType type = VEH_BEGIN; type < VEH_COMPANY_END; type++) {
|
||||||
|
c->group_all[type].ClearProfits();
|
||||||
|
c->group_default[type].ClearProfits();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recalculate */
|
||||||
|
Group *g;
|
||||||
|
FOR_ALL_GROUPS(g) {
|
||||||
|
g->statistics.ClearProfits();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vehicle *v;
|
||||||
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
if (v->IsPrimaryVehicle() && v->age > VEHICLE_PROFIT_MIN_AGE) GroupStatistics::VehicleReachedProfitAge(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the num engines of a groupID. Decrease the old one and increase the new one
|
* Update the num engines of a groupID. Decrease the old one and increase the new one
|
||||||
|
@ -117,6 +117,7 @@ private:
|
|||||||
/* Columns in the group list */
|
/* Columns in the group list */
|
||||||
enum ListColumns {
|
enum ListColumns {
|
||||||
VGC_NAME, ///< Group name.
|
VGC_NAME, ///< Group name.
|
||||||
|
VGC_PROFIT, ///< Profit icon.
|
||||||
VGC_NUMBER, ///< Number of vehicles in the group.
|
VGC_NUMBER, ///< Number of vehicles in the group.
|
||||||
|
|
||||||
VGC_END
|
VGC_END
|
||||||
@ -185,6 +186,15 @@ private:
|
|||||||
this->column_size[VGC_NAME].width = max(170u, this->column_size[VGC_NAME].width);
|
this->column_size[VGC_NAME].width = max(170u, this->column_size[VGC_NAME].width);
|
||||||
this->tiny_step_height = this->column_size[VGC_NAME].height;
|
this->tiny_step_height = this->column_size[VGC_NAME].height;
|
||||||
|
|
||||||
|
this->column_size[VGC_PROFIT].width = 0;
|
||||||
|
this->column_size[VGC_PROFIT].height = 0;
|
||||||
|
static const SpriteID profit_sprites[] = {SPR_PROFIT_NA, SPR_PROFIT_NEGATIVE, SPR_PROFIT_SOME, SPR_PROFIT_LOT};
|
||||||
|
for (uint i = 0; i < lengthof(profit_sprites); i++) {
|
||||||
|
Dimension d = GetSpriteSize(profit_sprites[i]);
|
||||||
|
this->column_size[VGC_PROFIT] = maxdim(this->column_size[VGC_PROFIT], d);
|
||||||
|
}
|
||||||
|
this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_PROFIT].height);
|
||||||
|
|
||||||
SetDParam(0, GroupStatistics::Get(this->vli.company, ALL_GROUP, this->vli.vtype).num_vehicle > 900 ? 9999 : 999);
|
SetDParam(0, GroupStatistics::Get(this->vli.company, ALL_GROUP, this->vli.vtype).num_vehicle > 900 ? 9999 : 999);
|
||||||
this->column_size[VGC_NUMBER] = GetStringBoundingBox(STR_TINY_COMMA);
|
this->column_size[VGC_NUMBER] = GetStringBoundingBox(STR_TINY_COMMA);
|
||||||
this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_NUMBER].height);
|
this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_NUMBER].height);
|
||||||
@ -193,6 +203,7 @@ private:
|
|||||||
|
|
||||||
return WD_FRAMERECT_LEFT + 8 +
|
return WD_FRAMERECT_LEFT + 8 +
|
||||||
this->column_size[VGC_NAME].width + 8 +
|
this->column_size[VGC_NAME].width + 8 +
|
||||||
|
this->column_size[VGC_PROFIT].width + 2 +
|
||||||
this->column_size[VGC_NUMBER].width + 2 +
|
this->column_size[VGC_NUMBER].width + 2 +
|
||||||
WD_FRAMERECT_RIGHT;
|
WD_FRAMERECT_RIGHT;
|
||||||
}
|
}
|
||||||
@ -224,8 +235,22 @@ private:
|
|||||||
int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8;
|
int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8;
|
||||||
DrawString(x, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
|
DrawString(x, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
|
||||||
|
|
||||||
|
/* draw the profit icon */
|
||||||
|
x = rtl ? x - 8 - this->column_size[VGC_PROFIT].width : x + 8 + this->column_size[VGC_NAME].width;
|
||||||
|
SpriteID spr;
|
||||||
|
if (stats.num_profit_vehicle == 0) {
|
||||||
|
spr = SPR_PROFIT_NA;
|
||||||
|
} else if (stats.profit_last_year < 0) {
|
||||||
|
spr = SPR_PROFIT_NEGATIVE;
|
||||||
|
} else if (stats.profit_last_year < 10000 * stats.num_profit_vehicle) { // TODO magic number
|
||||||
|
spr = SPR_PROFIT_SOME;
|
||||||
|
} else {
|
||||||
|
spr = SPR_PROFIT_LOT;
|
||||||
|
}
|
||||||
|
DrawSprite(spr, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROFIT].height) / 2);
|
||||||
|
|
||||||
/* draw the number of vehicles of the group */
|
/* draw the number of vehicles of the group */
|
||||||
x = rtl ? x - 8 - this->column_size[VGC_NUMBER].width : x + 8 + this->column_size[VGC_NAME].width;
|
x = rtl ? x - 2 - this->column_size[VGC_NUMBER].width : x + 2 + this->column_size[VGC_PROFIT].width;
|
||||||
SetDParam(0, stats.num_vehicle);
|
SetDParam(0, stats.num_vehicle);
|
||||||
DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_TINY_COMMA, colour, SA_RIGHT | SA_FORCE);
|
DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_TINY_COMMA, colour, SA_RIGHT | SA_FORCE);
|
||||||
}
|
}
|
||||||
|
@ -1192,6 +1192,12 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
Train *original_src_head = src_head;
|
Train *original_src_head = src_head;
|
||||||
Train *original_dst_head = (dst_head == src_head ? NULL : dst_head);
|
Train *original_dst_head = (dst_head == src_head ? NULL : dst_head);
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
/* Remove old heads from the statistics */
|
||||||
|
if (original_src_head != NULL && original_src_head->IsFrontEngine()) GroupStatistics::CountVehicle(original_src_head, -1);
|
||||||
|
if (original_dst_head != NULL && original_dst_head->IsFrontEngine()) GroupStatistics::CountVehicle(original_dst_head, -1);
|
||||||
|
}
|
||||||
|
|
||||||
/* (Re)arrange the trains in the wanted arrangement. */
|
/* (Re)arrange the trains in the wanted arrangement. */
|
||||||
ArrangeTrains(&dst_head, dst, &src_head, src, move_chain);
|
ArrangeTrains(&dst_head, dst, &src_head, src, move_chain);
|
||||||
|
|
||||||
@ -1242,18 +1248,6 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
DeleteWindowById(WC_VEHICLE_DETAILS, src->index);
|
DeleteWindowById(WC_VEHICLE_DETAILS, src->index);
|
||||||
DeleteWindowById(WC_VEHICLE_TIMETABLE, src->index);
|
DeleteWindowById(WC_VEHICLE_TIMETABLE, src->index);
|
||||||
|
|
||||||
/* We are going to be moved to a different train, and
|
|
||||||
* we were the front engine of the original train. */
|
|
||||||
if (dst_head != NULL && dst_head != src && (src_head == NULL || !src_head->IsFrontEngine())) {
|
|
||||||
GroupStatistics::CountVehicle(src, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The front engine is going to be moved later in the
|
|
||||||
* current train, and it will not be a train anymore. */
|
|
||||||
if (dst_head == NULL && !src_head->IsFrontEngine()) {
|
|
||||||
GroupStatistics::CountVehicle(src, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete orders, group stuff and the unit number as we're not the
|
/* Delete orders, group stuff and the unit number as we're not the
|
||||||
* front of any vehicle anymore. */
|
* front of any vehicle anymore. */
|
||||||
DeleteVehicleOrders(src);
|
DeleteVehicleOrders(src);
|
||||||
@ -1261,18 +1255,16 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
src->unitnumber = 0;
|
src->unitnumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We were a front engine and we are becoming one for a different train.
|
|
||||||
* Increase the group counter accordingly. */
|
|
||||||
if (original_src_head == src && dst_head == src) {
|
|
||||||
GroupStatistics::CountVehicle(src, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We weren't a front engine but are becoming one. So
|
/* We weren't a front engine but are becoming one. So
|
||||||
* we should be put in the default group. */
|
* we should be put in the default group. */
|
||||||
if (original_src_head != src && dst_head == src) {
|
if (original_src_head != src && dst_head == src) {
|
||||||
SetTrainGroupID(src, DEFAULT_GROUP);
|
SetTrainGroupID(src, DEFAULT_GROUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add new heads to statistics */
|
||||||
|
if (src_head != NULL && src_head->IsFrontEngine()) GroupStatistics::CountVehicle(src_head, 1);
|
||||||
|
if (dst_head != NULL && dst_head->IsFrontEngine()) GroupStatistics::CountVehicle(dst_head, 1);
|
||||||
|
|
||||||
/* Handle 'new engine' part of cases #1b, #2b, #3b, #4b and #5 in NormaliseTrainHead. */
|
/* Handle 'new engine' part of cases #1b, #2b, #3b, #4b and #5 in NormaliseTrainHead. */
|
||||||
NormaliseTrainHead(src_head);
|
NormaliseTrainHead(src_head);
|
||||||
NormaliseTrainHead(dst_head);
|
NormaliseTrainHead(dst_head);
|
||||||
@ -1354,7 +1346,7 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3
|
|||||||
|
|
||||||
/* Copy other important data from the front engine */
|
/* Copy other important data from the front engine */
|
||||||
new_head->CopyVehicleConfigAndStatistics(first);
|
new_head->CopyVehicleConfigAndStatistics(first);
|
||||||
GroupStatistics::CountVehicle(new_head, 1);
|
GroupStatistics::CountVehicle(new_head, 1); // after copying over the profit
|
||||||
|
|
||||||
/* If we deleted a window then open a new one for the 'new' train */
|
/* If we deleted a window then open a new one for the 'new' train */
|
||||||
if (IsLocalCompany() && w != NULL) ShowVehicleViewWindow(new_head);
|
if (IsLocalCompany() && w != NULL) ShowVehicleViewWindow(new_head);
|
||||||
|
@ -1137,7 +1137,10 @@ bool Vehicle::HandleBreakdown()
|
|||||||
*/
|
*/
|
||||||
void AgeVehicle(Vehicle *v)
|
void AgeVehicle(Vehicle *v)
|
||||||
{
|
{
|
||||||
if (v->age < MAX_DAY) v->age++;
|
if (v->age < MAX_DAY) {
|
||||||
|
v->age++;
|
||||||
|
if (v->IsPrimaryVehicle() && v->age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedProfitAge(v);
|
||||||
|
}
|
||||||
|
|
||||||
if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return;
|
if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return;
|
||||||
|
|
||||||
@ -2402,6 +2405,11 @@ void VehiclesYearlyLoop()
|
|||||||
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GroupStatistics::UpdateProfits();
|
||||||
|
SetWindowClassesDirty(WC_TRAINS_LIST);
|
||||||
|
SetWindowClassesDirty(WC_SHIPS_LIST);
|
||||||
|
SetWindowClassesDirty(WC_ROADVEH_LIST);
|
||||||
|
SetWindowClassesDirty(WC_AIRCRAFT_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
#define IS_CUSTOM_FIRSTHEAD_SPRITE(x) (x == 0xFD)
|
#define IS_CUSTOM_FIRSTHEAD_SPRITE(x) (x == 0xFD)
|
||||||
#define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE)
|
#define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE)
|
||||||
|
|
||||||
|
static const int VEHICLE_PROFIT_MIN_AGE = DAYS_IN_YEAR * 2; ///< Only vehicles older than this have a meaningful profit.
|
||||||
|
static const Money VEHICLE_PROFIT_THRESHOLD = 10000; ///< Threshold for a vehicle to be considered making good profit.
|
||||||
|
|
||||||
typedef Vehicle *VehicleFromPosProc(Vehicle *v, void *data);
|
typedef Vehicle *VehicleFromPosProc(Vehicle *v, void *data);
|
||||||
|
|
||||||
void VehicleServiceInDepot(Vehicle *v);
|
void VehicleServiceInDepot(Vehicle *v);
|
||||||
|
@ -193,11 +193,11 @@ static void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
|
|||||||
SpriteID spr;
|
SpriteID spr;
|
||||||
|
|
||||||
/* draw profit-based coloured icons */
|
/* draw profit-based coloured icons */
|
||||||
if (v->age <= DAYS_IN_YEAR * 2) {
|
if (v->age <= VEHICLE_PROFIT_MIN_AGE) {
|
||||||
spr = SPR_PROFIT_NA;
|
spr = SPR_PROFIT_NA;
|
||||||
} else if (v->GetDisplayProfitLastYear() < 0) {
|
} else if (v->GetDisplayProfitLastYear() < 0) {
|
||||||
spr = SPR_PROFIT_NEGATIVE;
|
spr = SPR_PROFIT_NEGATIVE;
|
||||||
} else if (v->GetDisplayProfitLastYear() < 10000) {
|
} else if (v->GetDisplayProfitLastYear() < VEHICLE_PROFIT_THRESHOLD) {
|
||||||
spr = SPR_PROFIT_SOME;
|
spr = SPR_PROFIT_SOME;
|
||||||
} else {
|
} else {
|
||||||
spr = SPR_PROFIT_LOT;
|
spr = SPR_PROFIT_LOT;
|
||||||
|
Loading…
Reference in New Issue
Block a user