(svn r117) Feature: Performance details window in company league menu (TrueLight)

pull/155/head
dominik 20 years ago
parent cce45b44d8
commit a6f2257600

@ -80,10 +80,14 @@ uint32 CalculateCompanyValue(Player *p) {
return value;
}
static void UpdateCompanyRatingAndValue(Player *p)
// if update is set to true, the economy is updated with this score
// (also the house is updated, should only be true in the on-tick event)
void UpdateCompanyRatingAndValue(Player *p, bool update)
{
byte owner = p->index;
uint score;
int score = 0;
memset(_score_part[owner], 0, sizeof(_score_part[owner]));
/* Count vehicles */
{
@ -100,16 +104,16 @@ static void UpdateCompanyRatingAndValue(Player *p)
v->type == VEH_Ship) {
num++;
if (v->age > 730) {
if (min_profit >= v->profit_last_year)
if (min_profit > v->profit_last_year)
min_profit = v->profit_last_year;
}
}
}
score = (num < 120) ? num * 100 / 120 : 100;
_score_part[owner][SCORE_VEHICLES] = num;
if (min_profit != MAX_INT && min_profit > 0)
score += (min_profit < 10000) ? min_profit/100 : 100;
_score_part[owner][SCORE_MIN_PROFIT] = min_profit;
}
/* Count stations */
@ -123,7 +127,7 @@ static void UpdateCompanyRatingAndValue(Player *p)
do num += facil&1; while (facil>>=1);
}
}
score += (num < 80) ? num * 100 / 80 : 100;
_score_part[owner][SCORE_STATIONS] = num;
}
/* Generate statistics depending on recent income statistics */
@ -144,9 +148,9 @@ static void UpdateCompanyRatingAndValue(Player *p)
} while (++pee,--numec);
if (min_income > 0)
score += min_income >= 50000 ? 50 : min_income / 1000;
_score_part[owner][SCORE_MIN_INCOME] = min_income;
score += max_income >= 100000 ? 100 : max_income / 1000;
_score_part[owner][SCORE_MAX_INCOME] = max_income;
}
}
@ -164,35 +168,63 @@ static void UpdateCompanyRatingAndValue(Player *p)
total_delivered += pee->delivered_cargo;
} while (++pee,--numec);
score += total_delivered >= 40000 ? 400 : total_delivered / 100;
_score_part[owner][SCORE_DELIVERED] = total_delivered;
}
}
/* Generate score for variety of cargo */
{
uint cargo = p->cargo_types;
uint num = 0;
do num += cargo&1; while (cargo>>=1);
score += num < 8 ? num * 50 / 8 : 50;
p->cargo_types = 0;
_score_part[owner][SCORE_CARGO] = num;
if (update)
p->cargo_types = 0;
}
/* Generate score for player money */
{
int32 money = p->player_money;
if (money > 0) {
score += money < 10000000 ? money / (10000000/50) : 50;
_score_part[owner][SCORE_MONEY] = money;
}
}
/* Generate score for loan */
{
score += (250000 - p->current_loan) >= 0 ? (250000 - p->current_loan) / 5000 : 0;
_score_part[owner][SCORE_LOAN] = score_info[SCORE_LOAN].needed - p->current_loan;
}
// Now we calculate the score for each item..
{
int i;
int total_score = 0;
int s;
score = 0;
for (i=0;i<NUM_SCORE;i++) {
// Skip the total
if (i == SCORE_TOTAL) continue;
// Check the score
s = (_score_part[owner][i] >= score_info[i].needed) ? score_info[i].score : ((_score_part[owner][i] * score_info[i].score) / score_info[i].needed);
if (s < 0) s = 0;
score += s;
total_score += score_info[i].score;
}
_score_part[owner][SCORE_TOTAL] = score;
// We always want the score scaled to SCORE_MAX (1000)
if (total_score != SCORE_MAX)
score = score * SCORE_MAX / total_score;
}
p->old_economy[0].performance_history = score;
UpdatePlayerHouse(p, score);
p->old_economy[0].company_value = CalculateCompanyValue(p);
if (update) {
p->old_economy[0].performance_history = score;
UpdatePlayerHouse(p, score);
p->old_economy[0].company_value = CalculateCompanyValue(p);
}
InvalidateWindow(WC_PERFORMANCE_DETAIL, 0);
}
// use 255 as new_player to delete the player.
@ -495,7 +527,7 @@ static void PlayersGenStatistics()
if (p->num_valid_stat_ent != 24)
p->num_valid_stat_ent++;
UpdateCompanyRatingAndValue(p);
UpdateCompanyRatingAndValue(p, true);
PlayersCheckBankrupt(p);
if (p->block_preview != 0)

@ -23,6 +23,48 @@ typedef struct Subsidy {
} Subsidy;
enum {
SCORE_VEHICLES = 0,
SCORE_STATIONS = 1,
SCORE_MIN_PROFIT = 2,
SCORE_MIN_INCOME = 3,
SCORE_MAX_INCOME = 4,
SCORE_DELIVERED = 5,
SCORE_CARGO = 6,
SCORE_MONEY = 7,
SCORE_LOAN = 8,
SCORE_TOTAL = 9, // This must always be the last entry
NUM_SCORE = 10, // How many scores are there..
SCORE_MAX = 1000, // The max score that can be in the performance history
// the scores together of score_info is allowed to be more!
};
typedef struct ScoreInfo {
byte id; // Unique ID of the score
int needed; // How much you need to get the perfect score
int score; // How much score it will give
} ScoreInfo;
static const ScoreInfo score_info[] = {
{SCORE_VEHICLES, 120, 100},
{SCORE_STATIONS, 80, 100},
{SCORE_MIN_PROFIT, 10000, 100},
{SCORE_MIN_INCOME, 50000, 50},
{SCORE_MAX_INCOME, 100000, 100},
{SCORE_DELIVERED, 40000, 400},
{SCORE_CARGO, 8, 50},
{SCORE_MONEY, 10000000, 50},
{SCORE_LOAN, 250000, 50},
{SCORE_TOTAL}
};
int _score_part[MAX_PLAYERS][NUM_SCORE];
void UpdateCompanyRatingAndValue(Player *p, bool update);
VARDEF Subsidy _subsidies[MAX_PLAYERS];
Pair SetupSubsidyDecodeParam(Subsidy *s, bool mode);
void DeleteSubsidyWithIndustry(byte index);

@ -4,6 +4,7 @@
#include "gui.h"
#include "gfx.h"
#include "player.h"
#include "economy.h"
static uint _legend_showbits;
static uint _legend_cargobits;
@ -511,7 +512,227 @@ void ShowDeliveredCargoGraph()
InvalidateWindow(WC_GRAPH_LEGEND, 0);
_legend_showbits = 0;
}
}
}
/*****************************/
/* PERFORMANCE RATING DETAIL */
/*****************************/
static void PerformanceRatingDetailWndProc(Window *w, WindowEvent *e)
{
switch(e->event) {
case WE_PAINT: {
int val, needed, score, i;
byte owner, x;
uint16 y=14;
int total_score = 0;
int color_done, color_notdone;
// Draw standard stuff
DrawWindowWidgets(w);
// The player of which we check the detail performance rating
owner = FindFirstBit(w->click_state) - 13;
// Paint the player icons
for (i=0;i<MAX_PLAYERS;i++) {
if (!DEREF_PLAYER(i)->is_active) {
// Check if we have the player as an active player
if (!(w->disabled_state & (1 << (i+13)))) {
// Bah, player gone :(
w->disabled_state += 1 << (i+13);
// Is this player selected? If so, select first player (always save? :s)
if (w->click_state == 1 << (i+13))
w->click_state = 1 << 13;
// We need a repaint
SetWindowDirty(w);
}
continue;
}
// Check if we have the player marked as inactive
if ((w->disabled_state & (1 << (i+13)))) {
// New player! Yippie :p
w->disabled_state -= 1 << (i+13);
// We need a repaint
SetWindowDirty(w);
}
if (i == owner) x = 1; else x = 0;
DrawPlayerIcon(i, i*33+11+x, 16+x);
}
// The colors used to show how the progress is going
color_done = _color_list[6].window_color_1b;
color_notdone = _color_list[4].window_color_1b;
// Draw all the score parts
for (i=0;i<NUM_SCORE;i++) {
y += 20;
val = _score_part[owner][i];
needed = score_info[i].needed;
score = score_info[i].score;
// SCORE_TOTAL has his own rulez ;)
if (i == SCORE_TOTAL) {
needed = total_score;
score = SCORE_MAX;
} else
total_score += score;
DrawString(7, y, STR_PERFORMANCE_DETAIL_VEHICLES + i, 0);
// Draw the score
SET_DPARAM32(0, score);
DrawStringRightAligned(107, y, SET_PERFORMANCE_DETAIL_INT, 0);
// Calculate the %-bar
if (val > needed) x = 50;
else if (val == 0) x = 0;
else x = ((val * 50) / needed);
// SCORE_LOAN is inversed
if (val < 0 && i == SCORE_LOAN)
x = 0;
// Draw the bar
if (x != 0)
GfxFillRect(112, y-2, x + 112, y+10, color_done);
if (x != 50)
GfxFillRect(x + 112, y-2, 50 + 112, y+10, color_notdone);
// Calculate the %
if (val > needed) x = 100;
else x = ((val * 100) / needed);
// SCORE_LOAN is inversed
if (val < 0 && i == SCORE_LOAN)
x = 0;
// Draw it
SET_DPARAM32(0, x);
DrawStringCentered(137, y, STR_PERFORMANCE_DETAIL_PERCENT, 0);
// SCORE_LOAN is inversed
if (i == SCORE_LOAN)
val = needed - val;
// Draw the amount we have against what is needed
// For some of them it is in currency format
SET_DPARAM32(0, val);
SET_DPARAM32(1, needed);
switch (i) {
case SCORE_MIN_PROFIT:
case SCORE_MIN_INCOME:
case SCORE_MAX_INCOME:
case SCORE_MONEY:
case SCORE_LOAN:
DrawString(167, y, STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY, 0);
break;
default:
DrawString(167, y, STR_PERFORMANCE_DETAIL_AMOUNT_INT, 0);
}
}
break;
}
case WE_CLICK:
// Check which button is clicked
if (IS_INT_INSIDE(e->click.widget, 13, 21)) {
// Is it no on disable?
if ((w->disabled_state & (1 << e->click.widget)) == 0) {
w->click_state = 1 << e->click.widget;
SetWindowDirty(w);
}
}
break;
case WE_CREATE:
{
int i;
Player *p2;
w->hidden_state = 0;
w->disabled_state = 0;
// Hide the player who are not active
for (i=0;i<MAX_PLAYERS;i++) {
if (!DEREF_PLAYER(i)->is_active) {
w->disabled_state += 1 << (i+13);
}
}
// Update all player stats with the current data
// (this is because _score_info is not saved to a savegame)
FOR_ALL_PLAYERS(p2)
if (p2->is_active)
UpdateCompanyRatingAndValue(p2, false);
w->custom[0] = 74;
w->custom[1] = 5;
w->click_state = 1 << 13;
SetWindowDirty(w);
}
break;
case WE_TICK:
{
// Update the player score every 5 days
if (--w->custom[0] == 0) {
w->custom[0] = 74;
if (--w->custom[1] == 0) {
Player *p2;
w->custom[1] = 5;
FOR_ALL_PLAYERS(p2)
// Skip if player is not active
if (p2->is_active)
UpdateCompanyRatingAndValue(p2, false);
SetWindowDirty(w);
}
}
}
break;
}
}
static const Widget _performance_rating_detail_widgets[] = {
{ WWT_TEXTBTN, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
{ WWT_CAPTION, 14, 11, 266, 0, 13, STR_PERFORMANCE_DETAIL, STR_018C_WINDOW_TITLE_DRAG_THIS},
{ WWT_IMGBTN, 14, 0, 266, 14, 27, 0x0},
{ WWT_IMGBTN, 14, 0, 266, 28, 47, 0x0,STR_PERFORMANCE_DETAIL_VEHICLES_TIP},
{ WWT_IMGBTN, 14, 0, 266, 48, 67, 0x0,STR_PERFORMANCE_DETAIL_STATIONS_TIP},
{ WWT_IMGBTN, 14, 0, 266, 68, 87, 0x0,STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP},
{ WWT_IMGBTN, 14, 0, 266, 88, 107, 0x0,STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP},
{ WWT_IMGBTN, 14, 0, 266, 108, 127, 0x0,STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP},
{ WWT_IMGBTN, 14, 0, 266, 128, 147, 0x0,STR_PERFORMANCE_DETAIL_DELIVERED_TIP},
{ WWT_IMGBTN, 14, 0, 266, 148, 167, 0x0,STR_PERFORMANCE_DETAIL_CARGO_TIP},
{ WWT_IMGBTN, 14, 0, 266, 168, 187, 0x0,STR_PERFORMANCE_DETAIL_MONEY_TIP},
{ WWT_IMGBTN, 14, 0, 266, 188, 207, 0x0,STR_PERFORMANCE_DETAIL_LOAN_TIP},
{ WWT_IMGBTN, 14, 0, 266, 208, 227, 0x0,STR_PERFORMANCE_DETAIL_TOTAL_TIP},
{ WWT_IMGBTN, 14, 2, 34, 14, 26, 0x0,STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
{ WWT_IMGBTN, 14, 35, 67, 14, 26, 0x0,STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
{ WWT_IMGBTN, 14, 68, 100, 14, 26, 0x0,STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
{ WWT_IMGBTN, 14, 101, 133, 14, 26, 0x0,STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
{ WWT_IMGBTN, 14, 134, 166, 14, 26, 0x0,STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
{ WWT_IMGBTN, 14, 167, 199, 14, 26, 0x0,STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
{ WWT_IMGBTN, 14, 200, 232, 14, 26, 0x0,STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
{ WWT_IMGBTN, 14, 233, 265, 14, 26, 0x0,STR_704F_CLICK_HERE_TO_TOGGLE_COMPANY},
{ WWT_LAST},
};
static const WindowDesc _performance_rating_detail_desc = {
-1, -1, 267, 228,
WC_PERFORMANCE_DETAIL,0,
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
_performance_rating_detail_widgets,
PerformanceRatingDetailWndProc
};
void ShowPerformanceRatingDetail()
{
AllocateWindowDescFront(&_performance_rating_detail_desc, 0);
}
/***********************/
/* PERFORMANCE HISTORY */
@ -558,14 +779,17 @@ static void PerformanceHistoryWndProc(Window *w, WindowEvent *e)
case WE_CLICK:
if (e->click.widget == 2)
ShowGraphLegend();
if (e->click.widget == 3)
ShowPerformanceRatingDetail();
break;
}
}
static const Widget _performance_history_widgets[] = {
{ WWT_TEXTBTN, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
{ WWT_CAPTION, 14, 11, 525, 0, 13, STR_7051_COMPANY_PERFORMANCE_RATINGS, STR_018C_WINDOW_TITLE_DRAG_THIS},
{ WWT_CAPTION, 14, 11, 475, 0, 13, STR_7051_COMPANY_PERFORMANCE_RATINGS, STR_018C_WINDOW_TITLE_DRAG_THIS},
{ WWT_PUSHTXTBTN, 14, 526, 575, 0, 13, STR_704C_KEY, STR_704D_SHOW_KEY_TO_GRAPHS},
{ WWT_PUSHTXTBTN, 14, 476, 525, 0, 13, STR_PERFORMANCE_DETAIL_KEY, STR_704D_SHOW_KEY_TO_GRAPHS},
{ WWT_IMGBTN, 14, 0, 575, 14, 237, 0x0},
{ WWT_LAST},
};

@ -19,6 +19,7 @@ void ShowPerformanceHistoryGraph();
void ShowCompanyValueGraph();
void ShowCargoPaymentRates();
void ShowCompanyLeagueTable();
void ShowPerformanceRatingDetail();
/* news_gui.c */
void ShowLastNewsMessage();

@ -342,6 +342,7 @@ STR_0157_PERFORMANCE_HISTORY_GRAPH :Performance history graph
STR_0158_COMPANY_VALUE_GRAPH :Company value graph
STR_0159_CARGO_PAYMENT_RATES :Cargo payment rates
STR_015A_COMPANY_LEAGUE_TABLE :Company league table
STR_PERFORMANCE_DETAIL_MENU :Detail performance rating
############ range for menu ends
STR_015B_OPENTTD :{WHITE}About OpenTTD
@ -2518,3 +2519,33 @@ STR_B005_COAL_MINE_SUBSIDENCE_LEAVES :{BLACK}{BIGFONT}Coal mine subsidence leave
STR_BRIBE_FAILED :{WHITE}Your attempted bribery has been
STR_BRIBE_FAILED_2 :{WHITE}discovered by a regional investigator
STR_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG}
STR_PERFORMANCE_DETAIL :{WHITE}Detail performance rating
STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detail
STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}{TINYFONT}({CURRCOMPACT}/{CURRCOMPACT})
STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}{TINYFONT}({INT32}/{INT32})
STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{INT32}%
SET_PERFORMANCE_DETAIL_INT :{BLACK}{INT32}
############ Those following lines need to be in this order!!
STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vehicles:
STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stations:
STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. profit:
STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. income:
STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. income:
STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Delivered:
STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Cargo:
STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Money:
STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Loan:
STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total:
############ End of order list
STR_PERFORMANCE_DETAIL_VEHICLES_TIP :{BLACK}Amount of vehicles. This includes road vehicles, trains, ships and aircraft.
STR_PERFORMANCE_DETAIL_STATIONS_TIP :{BLACK}Amount of station parts. Every part of a station (e.g. train station, bus stop, airport) is counted, even if they are connected to one station.
STR_PERFORMANCE_DETAIL_MIN_PROFIT_TIP :{BLACK}The minimum profit of all the vehicles that are more than 2 years old.
STR_PERFORMANCE_DETAIL_MIN_INCOME_TIP :{BLACK}Amount of cash made in the month with the lowest profit of the past 12 quarters
STR_PERFORMANCE_DETAIL_MAX_INCOME_TIP :{BLACK}Amount of cash made in the month with the highest profit of the past 12 quarters
STR_PERFORMANCE_DETAIL_DELIVERED_TIP :{BLACK}Units of cargo delivered in the past four quarters.
STR_PERFORMANCE_DETAIL_CARGO_TIP :{BLACK}Types of cargo delivered in the last quarter.
STR_PERFORMANCE_DETAIL_MONEY_TIP :{BLACK}Amount of cash on hand
STR_PERFORMANCE_DETAIL_LOAN_TIP :{BLACK}Do you have a high loan?
STR_PERFORMANCE_DETAIL_TOTAL_TIP :{BLACK}Total points out of possible points

@ -202,7 +202,10 @@ void MenuClickGraphs(int index)
void MenuClickLeague(int index)
{
ShowCompanyLeagueTable();
switch(index) {
case 0: ShowCompanyLeagueTable(); return;
case 1: ShowPerformanceRatingDetail(); return;
}
}
void MenuClickIndustry(int index)
@ -648,7 +651,7 @@ static void ToolbarGraphsClick(Window *w)
static void ToolbarLeagueClick(Window *w)
{
PopupMainToolbMenu(w, 258, 11, STR_015A_COMPANY_LEAGUE_TABLE, 1);
PopupMainToolbMenu(w, 258, 11, STR_015A_COMPANY_LEAGUE_TABLE, 2);
}
static void ToolbarIndustryClick(Window *w)

@ -601,11 +601,18 @@ void IncreaseDate()
/* XXX: check if year 2050 was reached */
}
int FindFirstBit(uint32 x)
int FindFirstBit(uint32 value)
{
int i = 0;
assert(x != 0);
for(;!(x&1);i++,x>>=1);
// This is much faster then the one that was before here.
// Created by Darkvater.. blame him if it is wrong ;)
// Btw, the macro FINDFIRSTBIT is better to use when your value is
// not more then 128.
byte i = 0;
if (value & 0xffff0000) { value >>= 16; i += 16; }
if (value & 0x0000ff00) { value >>= 8; i += 8; }
if (value & 0x000000f0) { value >>= 4; i += 4; }
if (value & 0x0000000c) { value >>= 2; i += 2; }
if (value & 0x00000002) { i += 1; }
return i;
}

@ -705,6 +705,9 @@ void MakeNewEditorWorld()
MarkWholeScreenDirty();
}
void StartupPlayers();
void StartupDisasters();
void StartScenario()
{
_game_mode = GM_NORMAL;

@ -393,6 +393,7 @@ enum {
WC_INDUSTRY_DIRECTORY = 0x43,
WC_MESSAGE_HISTORY = 0x44,
WC_CHEATS = 0x45,
WC_PERFORMANCE_DETAIL = 0x46,
};

@ -346,6 +346,8 @@ restart:;
_last_window++;
SetWindowDirty(w);
CallWindowEventNP(w, WE_CREATE);
return w;
}

@ -293,6 +293,7 @@ enum WindowEvents {
WE_DROPDOWN_SELECT = 16,
WE_RCLICK = 17,
WE_KEYPRESS = 18,
WE_CREATE = 19,
};

Loading…
Cancel
Save